| // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #ifndef QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_BACKEND_H_ | 
 | #define QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_BACKEND_H_ | 
 |  | 
 | #include <cstdint> | 
 | #include <memory> | 
 |  | 
 | #include "absl/strings/string_view.h" | 
 | #include "quiche/quic/core/http/quic_spdy_stream.h" | 
 | #include "quiche/quic/core/quic_error_codes.h" | 
 | #include "quiche/quic/core/quic_types.h" | 
 | #include "quiche/quic/core/socket_factory.h" | 
 | #include "quiche/quic/core/web_transport_interface.h" | 
 | #include "quiche/quic/tools/quic_backend_response.h" | 
 | #include "quiche/spdy/core/http2_header_block.h" | 
 |  | 
 | namespace quic { | 
 |  | 
 | // This interface implements the functionality to fetch a response | 
 | // from the backend (such as cache, http-proxy etc) to serve | 
 | // requests received by a Quic Server | 
 | class QuicSimpleServerBackend { | 
 |  public: | 
 |   // This interface implements the methods | 
 |   // called by the QuicSimpleServerBackend implementation | 
 |   // to process the request in the backend | 
 |   class RequestHandler { | 
 |    public: | 
 |     virtual ~RequestHandler() {} | 
 |  | 
 |     virtual QuicConnectionId connection_id() const = 0; | 
 |     virtual QuicStreamId stream_id() const = 0; | 
 |     virtual std::string peer_host() const = 0; | 
 |     virtual QuicSpdyStream* GetStream() = 0; | 
 |     // Called when the response is ready at the backend and can be send back to | 
 |     // the QUIC client. | 
 |     virtual void OnResponseBackendComplete( | 
 |         const QuicBackendResponse* response) = 0; | 
 |     // Sends additional non-full-response data (without headers) to the request | 
 |     // stream, e.g. for CONNECT data. May only be called after sending an | 
 |     // incomplete response (using `QuicBackendResponse::INCOMPLETE_RESPONSE`). | 
 |     // Sends the data with the FIN bit to close the stream if `close_stream` is | 
 |     // true. | 
 |     virtual void SendStreamData(absl::string_view data, bool close_stream) = 0; | 
 |     // Abruptly terminates (resets) the request stream with `error`. | 
 |     virtual void TerminateStreamWithError(QuicResetStreamError error) = 0; | 
 |   }; | 
 |  | 
 |   struct WebTransportResponse { | 
 |     spdy::Http2HeaderBlock response_headers; | 
 |     std::unique_ptr<WebTransportVisitor> visitor; | 
 |   }; | 
 |  | 
 |   virtual ~QuicSimpleServerBackend() = default; | 
 |   // This method initializes the backend instance to fetch responses | 
 |   // from a backend server, in-memory cache etc. | 
 |   virtual bool InitializeBackend(const std::string& backend_url) = 0; | 
 |   // Returns true if the backend has been successfully initialized | 
 |   // and could be used to fetch HTTP requests | 
 |   virtual bool IsBackendInitialized() const = 0; | 
 |   // Passes the socket factory in use by the QuicServer. Must live as long as | 
 |   // incoming requests/data are still sent to the backend, or until cleared by | 
 |   // calling with null. Must not be called while backend is handling requests. | 
 |   virtual void SetSocketFactory(SocketFactory* /*socket_factory*/) {} | 
 |   // Triggers a HTTP request to be sent to the backend server or cache | 
 |   // If response is immediately available, the function synchronously calls | 
 |   // the `request_handler` with the HTTP response. | 
 |   // If the response has to be fetched over the network, the function | 
 |   // asynchronously calls `request_handler` with the HTTP response. | 
 |   // | 
 |   // Not called for requests using the CONNECT method. | 
 |   virtual void FetchResponseFromBackend( | 
 |       const spdy::Http2HeaderBlock& request_headers, | 
 |       const std::string& request_body, RequestHandler* request_handler) = 0; | 
 |  | 
 |   // Handles headers for requests using the CONNECT method. Called immediately | 
 |   // on receiving the headers, potentially before the request is complete or | 
 |   // data is received. Any response (complete or incomplete) should be sent, | 
 |   // potentially asynchronously, using `request_handler`. | 
 |   // | 
 |   // If not overridden by backend, sends an error appropriate for a server that | 
 |   // does not handle CONNECT requests. | 
 |   virtual void HandleConnectHeaders( | 
 |       const spdy::Http2HeaderBlock& /*request_headers*/, | 
 |       RequestHandler* request_handler) { | 
 |     spdy::Http2HeaderBlock headers; | 
 |     headers[":status"] = "405"; | 
 |     QuicBackendResponse response; | 
 |     response.set_headers(std::move(headers)); | 
 |     request_handler->OnResponseBackendComplete(&response); | 
 |   } | 
 |   // Handles data for requests using the CONNECT method.  Called repeatedly | 
 |   // whenever new data is available. If `data_complete` is true, data was | 
 |   // received with the FIN bit, and this is the last call to this method. | 
 |   // | 
 |   // If not overridden by backend, abruptly terminates the stream. | 
 |   virtual void HandleConnectData(absl::string_view /*data*/, | 
 |                                  bool /*data_complete*/, | 
 |                                  RequestHandler* request_handler) { | 
 |     request_handler->TerminateStreamWithError( | 
 |         QuicResetStreamError::FromInternal(QUIC_STREAM_CONNECT_ERROR)); | 
 |   } | 
 |  | 
 |   // Clears the state of the backend  instance | 
 |   virtual void CloseBackendResponseStream(RequestHandler* request_handler) = 0; | 
 |  | 
 |   virtual WebTransportResponse ProcessWebTransportRequest( | 
 |       const spdy::Http2HeaderBlock& /*request_headers*/, | 
 |       WebTransportSession* /*session*/) { | 
 |     WebTransportResponse response; | 
 |     response.response_headers[":status"] = "400"; | 
 |     return response; | 
 |   } | 
 |   virtual bool SupportsWebTransport() { return false; } | 
 |   virtual bool SupportsExtendedConnect() { return true; } | 
 | }; | 
 |  | 
 | }  // namespace quic | 
 |  | 
 | #endif  // QUICHE_QUIC_TOOLS_QUIC_SIMPLE_SERVER_BACKEND_H_ |