blob: a142dd85526fcce6df76f18b8bce5c4edc7b3cd5 [file] [log] [blame]
// 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_