1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_BACKEND_H_ 6 #define QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_BACKEND_H_ 7 8 #include <cstdint> 9 #include <memory> 10 11 #include "absl/strings/string_view.h" 12 #include "quiche/quic/core/http/quic_spdy_stream.h" 13 #include "quiche/quic/core/quic_error_codes.h" 14 #include "quiche/quic/core/quic_types.h" 15 #include "quiche/quic/core/socket_factory.h" 16 #include "quiche/quic/core/web_transport_interface.h" 17 #include "quiche/quic/tools/quic_backend_response.h" 18 #include "quiche/spdy/core/http2_header_block.h" 19 20 namespace quic { 21 22 // This interface implements the functionality to fetch a response 23 // from the backend (such as cache, http-proxy etc) to serve 24 // requests received by a Quic Server 25 class QuicSimpleServerBackend { 26 public: 27 // This interface implements the methods 28 // called by the QuicSimpleServerBackend implementation 29 // to process the request in the backend 30 class RequestHandler { 31 public: ~RequestHandler()32 virtual ~RequestHandler() {} 33 34 virtual QuicConnectionId connection_id() const = 0; 35 virtual QuicStreamId stream_id() const = 0; 36 virtual std::string peer_host() const = 0; 37 virtual QuicSpdyStream* GetStream() = 0; 38 // Called when the response is ready at the backend and can be send back to 39 // the QUIC client. 40 virtual void OnResponseBackendComplete( 41 const QuicBackendResponse* response) = 0; 42 // Sends additional non-full-response data (without headers) to the request 43 // stream, e.g. for CONNECT data. May only be called after sending an 44 // incomplete response (using `QuicBackendResponse::INCOMPLETE_RESPONSE`). 45 // Sends the data with the FIN bit to close the stream if `close_stream` is 46 // true. 47 virtual void SendStreamData(absl::string_view data, bool close_stream) = 0; 48 // Abruptly terminates (resets) the request stream with `error`. 49 virtual void TerminateStreamWithError(QuicResetStreamError error) = 0; 50 }; 51 52 struct WebTransportResponse { 53 spdy::Http2HeaderBlock response_headers; 54 std::unique_ptr<WebTransportVisitor> visitor; 55 }; 56 57 virtual ~QuicSimpleServerBackend() = default; 58 // This method initializes the backend instance to fetch responses 59 // from a backend server, in-memory cache etc. 60 virtual bool InitializeBackend(const std::string& backend_url) = 0; 61 // Returns true if the backend has been successfully initialized 62 // and could be used to fetch HTTP requests 63 virtual bool IsBackendInitialized() const = 0; 64 // Passes the socket factory in use by the QuicServer. Must live as long as 65 // incoming requests/data are still sent to the backend, or until cleared by 66 // calling with null. Must not be called while backend is handling requests. SetSocketFactory(SocketFactory *)67 virtual void SetSocketFactory(SocketFactory* /*socket_factory*/) {} 68 // Triggers a HTTP request to be sent to the backend server or cache 69 // If response is immediately available, the function synchronously calls 70 // the `request_handler` with the HTTP response. 71 // If the response has to be fetched over the network, the function 72 // asynchronously calls `request_handler` with the HTTP response. 73 // 74 // Not called for requests using the CONNECT method. 75 virtual void FetchResponseFromBackend( 76 const spdy::Http2HeaderBlock& request_headers, 77 const std::string& request_body, RequestHandler* request_handler) = 0; 78 79 // Handles headers for requests using the CONNECT method. Called immediately 80 // on receiving the headers, potentially before the request is complete or 81 // data is received. Any response (complete or incomplete) should be sent, 82 // potentially asynchronously, using `request_handler`. 83 // 84 // If not overridden by backend, sends an error appropriate for a server that 85 // does not handle CONNECT requests. HandleConnectHeaders(const spdy::Http2HeaderBlock &,RequestHandler * request_handler)86 virtual void HandleConnectHeaders( 87 const spdy::Http2HeaderBlock& /*request_headers*/, 88 RequestHandler* request_handler) { 89 spdy::Http2HeaderBlock headers; 90 headers[":status"] = "405"; 91 QuicBackendResponse response; 92 response.set_headers(std::move(headers)); 93 request_handler->OnResponseBackendComplete(&response); 94 } 95 // Handles data for requests using the CONNECT method. Called repeatedly 96 // whenever new data is available. If `data_complete` is true, data was 97 // received with the FIN bit, and this is the last call to this method. 98 // 99 // If not overridden by backend, abruptly terminates the stream. HandleConnectData(absl::string_view,bool,RequestHandler * request_handler)100 virtual void HandleConnectData(absl::string_view /*data*/, 101 bool /*data_complete*/, 102 RequestHandler* request_handler) { 103 request_handler->TerminateStreamWithError( 104 QuicResetStreamError::FromInternal(QUIC_STREAM_CONNECT_ERROR)); 105 } 106 107 // Clears the state of the backend instance 108 virtual void CloseBackendResponseStream(RequestHandler* request_handler) = 0; 109 ProcessWebTransportRequest(const spdy::Http2HeaderBlock &,WebTransportSession *)110 virtual WebTransportResponse ProcessWebTransportRequest( 111 const spdy::Http2HeaderBlock& /*request_headers*/, 112 WebTransportSession* /*session*/) { 113 WebTransportResponse response; 114 response.response_headers[":status"] = "400"; 115 return response; 116 } SupportsWebTransport()117 virtual bool SupportsWebTransport() { return false; } SupportsExtendedConnect()118 virtual bool SupportsExtendedConnect() { return true; } 119 }; 120 121 } // namespace quic 122 123 #endif // QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_BACKEND_H_ 124