mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-11-28 00:06:09 +03:00
369 lines
12 KiB
C
369 lines
12 KiB
C
|
// Copyright 2014 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 NET_HTTP_HTTP_TRANSACTION_TEST_UTIL_H_
|
||
|
#define NET_HTTP_HTTP_TRANSACTION_TEST_UTIL_H_
|
||
|
|
||
|
#include "net/http/http_transaction.h"
|
||
|
|
||
|
#include <stdint.h>
|
||
|
|
||
|
#include <string>
|
||
|
|
||
|
#include "base/callback.h"
|
||
|
#include "base/compiler_specific.h"
|
||
|
#include "base/memory/weak_ptr.h"
|
||
|
#include "base/strings/string16.h"
|
||
|
#include "net/base/io_buffer.h"
|
||
|
#include "net/base/load_flags.h"
|
||
|
#include "net/base/net_error_details.h"
|
||
|
#include "net/base/net_errors.h"
|
||
|
#include "net/base/request_priority.h"
|
||
|
#include "net/base/test_completion_callback.h"
|
||
|
#include "net/disk_cache/disk_cache.h"
|
||
|
#include "net/http/http_cache.h"
|
||
|
#include "net/http/http_request_info.h"
|
||
|
#include "net/http/http_response_headers.h"
|
||
|
#include "net/http/http_response_info.h"
|
||
|
#include "net/socket/connection_attempts.h"
|
||
|
|
||
|
namespace net {
|
||
|
|
||
|
class HttpRequestHeaders;
|
||
|
class IOBuffer;
|
||
|
class SSLPrivateKey;
|
||
|
class X509Certificate;
|
||
|
class NetLogWithSource;
|
||
|
struct HttpRequestInfo;
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// mock transaction data
|
||
|
|
||
|
// these flags may be combined to form the test_mode field
|
||
|
enum {
|
||
|
TEST_MODE_NORMAL = 0,
|
||
|
TEST_MODE_SYNC_NET_START = 1 << 0,
|
||
|
TEST_MODE_SYNC_NET_READ = 1 << 1,
|
||
|
TEST_MODE_SYNC_CACHE_START = 1 << 2,
|
||
|
TEST_MODE_SYNC_CACHE_READ = 1 << 3,
|
||
|
TEST_MODE_SYNC_CACHE_WRITE = 1 << 4,
|
||
|
TEST_MODE_SYNC_ALL = (TEST_MODE_SYNC_NET_START | TEST_MODE_SYNC_NET_READ |
|
||
|
TEST_MODE_SYNC_CACHE_START | TEST_MODE_SYNC_CACHE_READ |
|
||
|
TEST_MODE_SYNC_CACHE_WRITE),
|
||
|
TEST_MODE_SLOW_READ = 1 << 5
|
||
|
};
|
||
|
|
||
|
using MockTransactionReadHandler = int (*)(int64_t content_length,
|
||
|
int64_t offset,
|
||
|
IOBuffer* buf,
|
||
|
int buf_len);
|
||
|
using MockTransactionHandler = void (*)(const HttpRequestInfo* request,
|
||
|
std::string* response_status,
|
||
|
std::string* response_headers,
|
||
|
std::string* response_data);
|
||
|
|
||
|
struct MockTransaction {
|
||
|
const char* url;
|
||
|
const char* method;
|
||
|
// If |request_time| is unspecified, the current time will be used.
|
||
|
base::Time request_time;
|
||
|
const char* request_headers;
|
||
|
int load_flags;
|
||
|
const char* status;
|
||
|
const char* response_headers;
|
||
|
// If |response_time| is unspecified, the current time will be used.
|
||
|
base::Time response_time;
|
||
|
const char* data;
|
||
|
int test_mode;
|
||
|
MockTransactionHandler handler;
|
||
|
MockTransactionReadHandler read_handler;
|
||
|
scoped_refptr<X509Certificate> cert;
|
||
|
CertStatus cert_status;
|
||
|
int ssl_connection_status;
|
||
|
// Value returned by MockNetworkTransaction::Start (potentially
|
||
|
// asynchronously if |!(test_mode & TEST_MODE_SYNC_NET_START)|.)
|
||
|
Error start_return_code;
|
||
|
// Value returned by MockNetworkTransaction::Read (potentially
|
||
|
// asynchronously if |!(test_mode & TEST_MODE_SYNC_NET_START)|.)
|
||
|
Error read_return_code;
|
||
|
};
|
||
|
|
||
|
extern const MockTransaction kSimpleGET_Transaction;
|
||
|
extern const MockTransaction kSimplePOST_Transaction;
|
||
|
extern const MockTransaction kTypicalGET_Transaction;
|
||
|
extern const MockTransaction kETagGET_Transaction;
|
||
|
extern const MockTransaction kRangeGET_Transaction;
|
||
|
|
||
|
// returns the mock transaction for the given URL
|
||
|
const MockTransaction* FindMockTransaction(const GURL& url);
|
||
|
|
||
|
// Add/Remove a mock transaction that can be accessed via FindMockTransaction.
|
||
|
// There can be only one MockTransaction associated with a given URL.
|
||
|
void AddMockTransaction(const MockTransaction* trans);
|
||
|
void RemoveMockTransaction(const MockTransaction* trans);
|
||
|
|
||
|
struct ScopedMockTransaction : MockTransaction {
|
||
|
ScopedMockTransaction() {
|
||
|
AddMockTransaction(this);
|
||
|
}
|
||
|
explicit ScopedMockTransaction(const MockTransaction& t)
|
||
|
: MockTransaction(t) {
|
||
|
AddMockTransaction(this);
|
||
|
}
|
||
|
~ScopedMockTransaction() {
|
||
|
RemoveMockTransaction(this);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// mock http request
|
||
|
|
||
|
class MockHttpRequest : public HttpRequestInfo {
|
||
|
public:
|
||
|
explicit MockHttpRequest(const MockTransaction& t);
|
||
|
};
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// use this class to test completely consuming a transaction
|
||
|
|
||
|
class TestTransactionConsumer {
|
||
|
public:
|
||
|
TestTransactionConsumer(RequestPriority priority,
|
||
|
HttpTransactionFactory* factory);
|
||
|
virtual ~TestTransactionConsumer();
|
||
|
|
||
|
void Start(const HttpRequestInfo* request, const NetLogWithSource& net_log);
|
||
|
|
||
|
bool is_done() const { return state_ == DONE; }
|
||
|
int error() const { return error_; }
|
||
|
|
||
|
const HttpResponseInfo* response_info() const {
|
||
|
return trans_->GetResponseInfo();
|
||
|
}
|
||
|
const HttpTransaction* transaction() const { return trans_.get(); }
|
||
|
const std::string& content() const { return content_; }
|
||
|
|
||
|
private:
|
||
|
enum State {
|
||
|
IDLE,
|
||
|
STARTING,
|
||
|
READING,
|
||
|
DONE
|
||
|
};
|
||
|
|
||
|
void DidStart(int result);
|
||
|
void DidRead(int result);
|
||
|
void DidFinish(int result);
|
||
|
void Read();
|
||
|
|
||
|
void OnIOComplete(int result);
|
||
|
|
||
|
State state_;
|
||
|
std::unique_ptr<HttpTransaction> trans_;
|
||
|
std::string content_;
|
||
|
scoped_refptr<IOBuffer> read_buf_;
|
||
|
int error_;
|
||
|
|
||
|
static int quit_counter_;
|
||
|
};
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// mock network layer
|
||
|
|
||
|
class MockNetworkLayer;
|
||
|
|
||
|
// This transaction class inspects the available set of mock transactions to
|
||
|
// find data for the request URL. It supports IO operations that complete
|
||
|
// synchronously or asynchronously to help exercise different code paths in the
|
||
|
// HttpCache implementation.
|
||
|
class MockNetworkTransaction
|
||
|
: public HttpTransaction,
|
||
|
public base::SupportsWeakPtr<MockNetworkTransaction> {
|
||
|
typedef WebSocketHandshakeStreamBase::CreateHelper CreateHelper;
|
||
|
|
||
|
public:
|
||
|
MockNetworkTransaction(RequestPriority priority, MockNetworkLayer* factory);
|
||
|
~MockNetworkTransaction() override;
|
||
|
|
||
|
int Start(const HttpRequestInfo* request,
|
||
|
const CompletionCallback& callback,
|
||
|
const NetLogWithSource& net_log) override;
|
||
|
|
||
|
int RestartIgnoringLastError(const CompletionCallback& callback) override;
|
||
|
|
||
|
int RestartWithCertificate(scoped_refptr<X509Certificate> client_cert,
|
||
|
scoped_refptr<SSLPrivateKey> client_private_key,
|
||
|
const CompletionCallback& callback) override;
|
||
|
|
||
|
int RestartWithAuth(const AuthCredentials& credentials,
|
||
|
const CompletionCallback& callback) override;
|
||
|
|
||
|
bool IsReadyToRestartForAuth() override;
|
||
|
|
||
|
int Read(IOBuffer* buf,
|
||
|
int buf_len,
|
||
|
const CompletionCallback& callback) override;
|
||
|
void PopulateNetErrorDetails(NetErrorDetails* details) const override;
|
||
|
|
||
|
void StopCaching() override;
|
||
|
|
||
|
bool GetFullRequestHeaders(HttpRequestHeaders* headers) const override;
|
||
|
|
||
|
int64_t GetTotalReceivedBytes() const override;
|
||
|
|
||
|
int64_t GetTotalSentBytes() const override;
|
||
|
|
||
|
void DoneReading() override;
|
||
|
|
||
|
const HttpResponseInfo* GetResponseInfo() const override;
|
||
|
|
||
|
LoadState GetLoadState() const override;
|
||
|
|
||
|
void SetQuicServerInfo(QuicServerInfo* quic_server_info) override;
|
||
|
|
||
|
bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
|
||
|
|
||
|
bool GetRemoteEndpoint(IPEndPoint* endpoint) const override;
|
||
|
|
||
|
void SetPriority(RequestPriority priority) override;
|
||
|
|
||
|
void SetWebSocketHandshakeStreamCreateHelper(
|
||
|
CreateHelper* create_helper) override;
|
||
|
|
||
|
void SetBeforeNetworkStartCallback(
|
||
|
const BeforeNetworkStartCallback& callback) override;
|
||
|
|
||
|
void SetBeforeHeadersSentCallback(
|
||
|
const BeforeHeadersSentCallback& callback) override;
|
||
|
|
||
|
void SetRequestHeadersCallback(RequestHeadersCallback callback) override {}
|
||
|
void SetResponseHeadersCallback(ResponseHeadersCallback) override {}
|
||
|
|
||
|
int ResumeNetworkStart() override;
|
||
|
|
||
|
void GetConnectionAttempts(ConnectionAttempts* out) const override;
|
||
|
|
||
|
CreateHelper* websocket_handshake_stream_create_helper() {
|
||
|
return websocket_handshake_stream_create_helper_;
|
||
|
}
|
||
|
|
||
|
RequestPriority priority() const { return priority_; }
|
||
|
const HttpRequestInfo* request() const { return request_; }
|
||
|
|
||
|
// Bogus value that will be returned by GetTotalReceivedBytes() if the
|
||
|
// MockNetworkTransaction was started.
|
||
|
static const int64_t kTotalReceivedBytes;
|
||
|
// Bogus value that will be returned by GetTotalSentBytes() if the
|
||
|
// MockNetworkTransaction was started.
|
||
|
static const int64_t kTotalSentBytes;
|
||
|
|
||
|
private:
|
||
|
int StartInternal(const HttpRequestInfo* request,
|
||
|
const CompletionCallback& callback,
|
||
|
const NetLogWithSource& net_log);
|
||
|
void CallbackLater(const CompletionCallback& callback, int result);
|
||
|
void RunCallback(const CompletionCallback& callback, int result);
|
||
|
|
||
|
const HttpRequestInfo* request_;
|
||
|
HttpResponseInfo response_;
|
||
|
std::string data_;
|
||
|
int64_t data_cursor_;
|
||
|
int64_t content_length_;
|
||
|
int test_mode_;
|
||
|
RequestPriority priority_;
|
||
|
MockTransactionReadHandler read_handler_;
|
||
|
CreateHelper* websocket_handshake_stream_create_helper_;
|
||
|
BeforeNetworkStartCallback before_network_start_callback_;
|
||
|
base::WeakPtr<MockNetworkLayer> transaction_factory_;
|
||
|
int64_t received_bytes_;
|
||
|
int64_t sent_bytes_;
|
||
|
|
||
|
// NetLog ID of the fake / non-existent underlying socket used by the
|
||
|
// connection. Requires Start() be passed a NetLogWithSource with a real
|
||
|
// NetLog to
|
||
|
// be initialized.
|
||
|
unsigned int socket_log_id_;
|
||
|
|
||
|
bool done_reading_called_;
|
||
|
bool reading_;
|
||
|
|
||
|
CompletionCallback resume_start_callback_; // used for pause and restart.
|
||
|
|
||
|
base::WeakPtrFactory<MockNetworkTransaction> weak_factory_;
|
||
|
|
||
|
};
|
||
|
|
||
|
class MockNetworkLayer : public HttpTransactionFactory,
|
||
|
public base::SupportsWeakPtr<MockNetworkLayer> {
|
||
|
public:
|
||
|
MockNetworkLayer();
|
||
|
~MockNetworkLayer() override;
|
||
|
|
||
|
int transaction_count() const { return transaction_count_; }
|
||
|
bool done_reading_called() const { return done_reading_called_; }
|
||
|
bool stop_caching_called() const { return stop_caching_called_; }
|
||
|
void TransactionDoneReading();
|
||
|
void TransactionStopCaching();
|
||
|
|
||
|
// Resets the transaction count. Can be called after test setup in order to
|
||
|
// make test expectations independent of how test setup is performed.
|
||
|
void ResetTransactionCount();
|
||
|
|
||
|
// Returns the last priority passed to CreateTransaction, or
|
||
|
// DEFAULT_PRIORITY if it hasn't been called yet.
|
||
|
RequestPriority last_create_transaction_priority() const {
|
||
|
return last_create_transaction_priority_;
|
||
|
}
|
||
|
|
||
|
// Returns the last transaction created by
|
||
|
// CreateTransaction. Returns a NULL WeakPtr if one has not been
|
||
|
// created yet, or the last transaction has been destroyed, or
|
||
|
// ClearLastTransaction() has been called and a new transaction
|
||
|
// hasn't been created yet.
|
||
|
base::WeakPtr<MockNetworkTransaction> last_transaction() {
|
||
|
return last_transaction_;
|
||
|
}
|
||
|
|
||
|
// Makes last_transaction() return NULL until the next transaction
|
||
|
// is created.
|
||
|
void ClearLastTransaction() {
|
||
|
last_transaction_.reset();
|
||
|
}
|
||
|
|
||
|
// HttpTransactionFactory:
|
||
|
int CreateTransaction(RequestPriority priority,
|
||
|
std::unique_ptr<HttpTransaction>* trans) override;
|
||
|
HttpCache* GetCache() override;
|
||
|
HttpNetworkSession* GetSession() override;
|
||
|
|
||
|
// The caller must guarantee that |clock| will outlive this object.
|
||
|
void SetClock(base::Clock* clock);
|
||
|
base::Clock* clock() const { return clock_; }
|
||
|
|
||
|
// The current time (will use clock_ if it is non NULL).
|
||
|
base::Time Now();
|
||
|
|
||
|
private:
|
||
|
int transaction_count_;
|
||
|
bool done_reading_called_;
|
||
|
bool stop_caching_called_;
|
||
|
RequestPriority last_create_transaction_priority_;
|
||
|
|
||
|
// By default clock_ is NULL but it can be set to a custom clock by test
|
||
|
// frameworks using SetClock.
|
||
|
base::Clock* clock_;
|
||
|
|
||
|
base::WeakPtr<MockNetworkTransaction> last_transaction_;
|
||
|
};
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// helpers
|
||
|
|
||
|
// read the transaction completely
|
||
|
int ReadTransaction(HttpTransaction* trans, std::string* result);
|
||
|
|
||
|
} // namespace net
|
||
|
|
||
|
#endif // NET_HTTP_HTTP_TRANSACTION_TEST_UTIL_H_
|