// Copyright 2018 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. // // The QuicHttpProxyBackendStream instance manages an instance of // net::URLRequest to initiate a single HTTP call to the backend. It also // implements the callbacks of net::URLRequest to receive the response. It is // instantiated by a delegate (for instance, the QuicSimpleServerStream class) // when a complete HTTP request is received within a single QUIC stream. // However, the instance is owned by QuicHttpProxyBackend, that destroys it // safely on the quic proxy thread. Upon receiving a response (success or // failed), the response headers and body are posted back to the main thread. In // the main thread, the QuicHttpProxyBackendStream instance calls the interface, // that is implemented by the delegate to return the response headers and body. // In addition to managing the HTTP request/response to the backend, it // translates the quic_spdy headers to/from HTTP headers for the backend. // #ifndef NET_TOOLS_QUIC_QUIC_HTTP_PROXY_BACKEND_STREAM_H_ #define NET_TOOLS_QUIC_QUIC_HTTP_PROXY_BACKEND_STREAM_H_ #include #include "base/bind.h" #include "base/callback.h" #include "base/location.h" #include "base/logging.h" #include "base/macros.h" #include "net/base/request_priority.h" #include "net/base/upload_data_stream.h" #include "net/url_request/url_request.h" #include "net/third_party/quic/tools/quic_backend_response.h" #include "net/third_party/quic/tools/quic_simple_server_backend.h" #include "net/third_party/spdy/core/spdy_header_block.h" #include "net/tools/quic/quic_http_proxy_backend.h" namespace base { class SequencedTaskRunner; class SingleThreadTaskRunner; } // namespace base namespace quic { class QuicBackendResponse; class QuicSimpleServerBackend; } // namespace quic namespace net { class HttpRequestHeaders; class SSLCertRequestInfo; class SSLInfo; class UploadDataStream; class QuicHttpProxyBackend; // An adapter for making HTTP requests to net::URLRequest. class QuicHttpProxyBackendStream : public net::URLRequest::Delegate { public: QuicHttpProxyBackendStream(QuicHttpProxyBackend* context); ~QuicHttpProxyBackendStream() override; static const std::set kHopHeaders; static const int kBufferSize; static const int kProxyHttpBackendError; static const std::string kDefaultQuicPeerIP; // Set callbacks to be called from this to the main (quic) thread. // A |delegate| may be NULL. // If set_delegate() is called multiple times, only the last delegate will be // used. void set_delegate(quic::QuicSimpleServerBackend::RequestHandler* delegate); void reset_delegate() { delegate_ = nullptr; } void Initialize(quic::QuicConnectionId quic_connection_id, quic::QuicStreamId quic_stream_id, std::string quic_peer_ip); virtual bool SendRequestToBackend( const spdy::SpdyHeaderBlock* incoming_request_headers, const std::string& incoming_body); quic::QuicConnectionId quic_connection_id() const { return quic_connection_id_; } quic::QuicStreamId quic_stream_id() const { return quic_stream_id_; } const net::HttpRequestHeaders& request_headers() const { return request_headers_; } // Releases all resources for the request and deletes the object itself. virtual void CancelRequest(); // net::URLRequest::Delegate implementations: void OnReceivedRedirect(net::URLRequest* request, const net::RedirectInfo& redirect_info, bool* defer_redirect) override; void OnCertificateRequested( net::URLRequest* request, net::SSLCertRequestInfo* cert_request_info) override; void OnSSLCertificateError(net::URLRequest* request, const net::SSLInfo& ssl_info, bool fatal) override; void OnResponseStarted(net::URLRequest* request, int net_error) override; void OnReadCompleted(net::URLRequest* request, int bytes_read) override; bool ResponseIsCompleted() const { return response_completed_; } quic::QuicBackendResponse* GetBackendResponse() const; private: void StartOnBackendThread(); void SendRequestOnBackendThread(); void ReadOnceTask(); void OnResponseCompleted(); void CopyHeaders(const spdy::SpdyHeaderBlock* incoming_request_headers); bool ValidateHttpMethod(std::string method); bool AddRequestHeader(std::string name, std::string value); // Adds a request body to the request before it starts. void SetUpload(std::unique_ptr upload); void SendResponseOnDelegateThread(); void ReleaseRequest(); spdy::SpdyHeaderBlock getAsQuicHeaders(net::HttpResponseHeaders* resp_headers, int response_code, uint64_t response_decoded_body_size); // The quic proxy backend context QuicHttpProxyBackend* proxy_context_; // Send back the response from the backend to |delegate_| quic::QuicSimpleServerBackend::RequestHandler* delegate_; // Task runner for interacting with the delegate scoped_refptr delegate_task_runner_; // Task runner for the proxy network operations. scoped_refptr quic_proxy_task_runner_; // The corresponding QUIC conn/client/stream quic::QuicConnectionId quic_connection_id_; quic::QuicStreamId quic_stream_id_; std::string quic_peer_ip_; // Url, method and spec for making a http request to the Backend GURL url_; std::string method_type_; net::HttpRequestHeaders request_headers_; std::unique_ptr upload_; std::unique_ptr url_request_; // Buffers that holds the response body scoped_refptr buf_; std::string data_received_; bool response_completed_; // Response and push resources received from the backend bool headers_set_; std::unique_ptr quic_response_; base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(QuicHttpProxyBackendStream); }; } // namespace net #endif // NET_TOOLS_QUIC_QUIC_HTTP_PROXY_BACKEND_STREAM_H_