blob: c5811e6d86d2f1b2a42bc8d84a81f819bdd85962 [file] [log] [blame]
// 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 proxy functionality is implemented as a separate thread namely
// “quic proxy thread”, managed by an instance of the QuicHttpProxyBackend
// class. The QuicHttpProxyBackend instance also manages an instance of the
// class net::URLRequestContext, that manages a single context for all the
// HTTP calls made to the backend server. Finally, the QuicHttpProxyBackend
// instance owns (creates/ destroys) the instances of QuicHttpProxyBackendStream
// to avoid orphan pointers of QuicHttpProxyBackendStream when the corresponding
// QUIC connection is destroyed on the main thread due to several reasons. The
// QUIC connection management and protocol parsing is performed by the main/quic
// thread, in the same way as the toy QUIC server.
//
// quic_http_proxy_backend_stream.h has a description of threads, the flow
// of packets in QUIC proxy in the forward and reverse directions.
#ifndef NET_TOOLS_QUIC_QUIC_HTTP_PROXY_BACKEND_H_
#define NET_TOOLS_QUIC_QUIC_HTTP_PROXY_BACKEND_H_
#include <stdint.h>
#include <memory>
#include <queue>
#include "base/base64.h"
#include "base/callback.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/values.h"
#include "net/third_party/quic/tools/quic_simple_server_backend.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_builder.h"
#include "url/gurl.h"
namespace base {
class SingleThreadTaskRunner;
} // namespace base
namespace quic {
class QuicSimpleServerBackend;
} // namespace quic
namespace net {
class QuicHttpProxyBackendStream;
// Manages the context to proxy HTTP requests to the backend server
// Owns instance of net::URLRequestContext.
class QuicHttpProxyBackend : public quic::QuicSimpleServerBackend {
public:
explicit QuicHttpProxyBackend();
~QuicHttpProxyBackend() override;
// Must be called from the backend thread of the quic proxy
net::URLRequestContext* GetURLRequestContext();
scoped_refptr<base::SingleThreadTaskRunner> GetProxyTaskRunner() const;
using ProxyBackendStreamMap =
std::unordered_map<quic::QuicSimpleServerBackend::RequestHandler*,
std::unique_ptr<QuicHttpProxyBackendStream>>;
const ProxyBackendStreamMap* proxy_backend_streams_map() const {
return &backend_stream_map_;
}
GURL backend_url() const { return backend_url_; }
// Implements the functions for interface quic::QuicSimpleServerBackend
bool InitializeBackend(const std::string& backend_url) override;
bool IsBackendInitialized() const override;
void FetchResponseFromBackend(
const spdy::SpdyHeaderBlock& request_headers,
const std::string& incoming_body,
quic::QuicSimpleServerBackend::RequestHandler* quic_stream) override;
void CloseBackendResponseStream(
quic::QuicSimpleServerBackend::RequestHandler* quic_stream) override;
private:
// Maps quic streams in the frontend to the corresponding http streams
// managed by |this|
ProxyBackendStreamMap backend_stream_map_;
bool ValidateBackendUrl(const std::string& backend_url);
void InitializeURLRequestContext();
QuicHttpProxyBackendStream* InitializeQuicProxyBackendStream(
quic::QuicSimpleServerBackend::RequestHandler* quic_server_stream);
// URLRequestContext to make URL requests to the backend
std::unique_ptr<net::URLRequestContext> context_; // owned by this
bool thread_initialized_;
// <scheme://hostname:port/ for the backend HTTP server
GURL backend_url_;
// Backend thread is owned by |this|
std::unique_ptr<base::Thread> proxy_thread_;
scoped_refptr<base::SingleThreadTaskRunner> proxy_task_runner_;
// Protects against concurrent access from quic (main) and proxy
// threads for adding and clearing a backend request handler
base::Lock backend_stream_mutex_;
DISALLOW_COPY_AND_ASSIGN(QuicHttpProxyBackend);
};
} // namespace net
#endif // NET_TOOLS_QUIC_QUIC_HTTP_PROXY_BACKEND_H_