summaryrefslogtreecommitdiffstats
path: root/net/http
diff options
context:
space:
mode:
Diffstat (limited to 'net/http')
-rw-r--r--net/http/http_cache_transaction.cc92
-rw-r--r--net/http/http_cache_transaction.h4
-rw-r--r--net/http/http_network_transaction.cc62
-rw-r--r--net/http/http_network_transaction.h7
-rw-r--r--net/http/http_request_info.cc3
-rw-r--r--net/http/http_request_info.h4
6 files changed, 128 insertions, 44 deletions
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc
index bf29f85..201f647 100644
--- a/net/http/http_cache_transaction.cc
+++ b/net/http/http_cache_transaction.cc
@@ -23,10 +23,12 @@
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/base/net_log.h"
+#include "net/base/network_delegate.h"
#include "net/base/ssl_cert_request_info.h"
#include "net/base/ssl_config_service.h"
#include "net/disk_cache/disk_cache.h"
#include "net/http/disk_cache_based_ssl_host_info.h"
+#include "net/http/http_network_session.h"
#include "net/http/http_request_info.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_transaction.h"
@@ -486,6 +488,13 @@ int HttpCache::Transaction::DoLoop(int result) {
case STATE_ADD_TO_ENTRY_COMPLETE:
rv = DoAddToEntryComplete(rv);
break;
+ case STATE_NOTIFY_BEFORE_SEND_HEADERS:
+ DCHECK_EQ(OK, rv);
+ rv = DoNotifyBeforeSendHeaders();
+ break;
+ case STATE_NOTIFY_BEFORE_SEND_HEADERS_COMPLETE:
+ rv = DoNotifyBeforeSendHeadersComplete(rv);
+ break;
case STATE_START_PARTIAL_CACHE_VALIDATION:
DCHECK_EQ(OK, rv);
rv = DoStartPartialCacheValidation();
@@ -909,6 +918,57 @@ int HttpCache::Transaction::DoAddToEntryComplete(int result) {
return OK;
}
+int HttpCache::Transaction::DoNotifyBeforeSendHeaders() {
+ // Balanced in DoNotifyBeforeSendHeadersComplete.
+ cache_callback_->AddRef();
+ next_state_ = STATE_NOTIFY_BEFORE_SEND_HEADERS_COMPLETE;
+
+ if (cache_->GetSession() && cache_->GetSession()->network_delegate()) {
+ // TODO(mpcomplete): need to be able to modify these headers.
+ HttpRequestHeaders headers = request_->extra_headers;
+ return cache_->GetSession()->network_delegate()->NotifyBeforeSendHeaders(
+ request_->request_id, &headers, cache_callback_);
+ }
+
+ return OK;
+}
+
+int HttpCache::Transaction::DoNotifyBeforeSendHeadersComplete(int result) {
+ cache_callback_->Release(); // Balanced in DoNotifyBeforeSendHeaders.
+
+ // We now have access to the cache entry.
+ //
+ // o if we are a reader for the transaction, then we can start reading the
+ // cache entry.
+ //
+ // o if we can read or write, then we should check if the cache entry needs
+ // to be validated and then issue a network request if needed or just read
+ // from the cache if the cache entry is already valid.
+ //
+ // o if we are set to UPDATE, then we are handling an externally
+ // conditionalized request (if-modified-since / if-none-match). We check
+ // if the request headers define a validation request.
+ //
+ if (result == net::OK) {
+ switch (mode_) {
+ case READ:
+ result = BeginCacheRead();
+ break;
+ case READ_WRITE:
+ result = BeginPartialCacheValidation();
+ break;
+ case UPDATE:
+ result = BeginExternallyConditionalizedRequest();
+ break;
+ case WRITE:
+ default:
+ NOTREACHED();
+ result = ERR_FAILED;
+ }
+ }
+ return result;
+}
+
// We may end up here multiple times for a given request.
int HttpCache::Transaction::DoStartPartialCacheValidation() {
if (mode_ == NONE)
@@ -1109,6 +1169,8 @@ int HttpCache::Transaction::DoCacheReadResponse() {
int HttpCache::Transaction::DoCacheReadResponseComplete(int result) {
cache_callback_->Release(); // Balance the AddRef from DoCacheReadResponse.
+ next_state_ = STATE_NOTIFY_BEFORE_SEND_HEADERS;
+
net_log_.EndEventWithNetErrorCode(NetLog::TYPE_HTTP_CACHE_READ_INFO, result);
if (result != io_buf_len_ ||
!HttpCache::ParseResponseInfo(read_buf_->data(), io_buf_len_,
@@ -1117,35 +1179,7 @@ int HttpCache::Transaction::DoCacheReadResponseComplete(int result) {
return ERR_CACHE_READ_FAILURE;
}
- // We now have access to the cache entry.
- //
- // o if we are a reader for the transaction, then we can start reading the
- // cache entry.
- //
- // o if we can read or write, then we should check if the cache entry needs
- // to be validated and then issue a network request if needed or just read
- // from the cache if the cache entry is already valid.
- //
- // o if we are set to UPDATE, then we are handling an externally
- // conditionalized request (if-modified-since / if-none-match). We check
- // if the request headers define a validation request.
- //
- switch (mode_) {
- case READ:
- result = BeginCacheRead();
- break;
- case READ_WRITE:
- result = BeginPartialCacheValidation();
- break;
- case UPDATE:
- result = BeginExternallyConditionalizedRequest();
- break;
- case WRITE:
- default:
- NOTREACHED();
- result = ERR_FAILED;
- }
- return result;
+ return OK;
}
int HttpCache::Transaction::DoCacheWriteResponse() {
diff --git a/net/http/http_cache_transaction.h b/net/http/http_cache_transaction.h
index 81160d5..17d7ead 100644
--- a/net/http/http_cache_transaction.h
+++ b/net/http/http_cache_transaction.h
@@ -141,6 +141,8 @@ class HttpCache::Transaction : public HttpTransaction {
STATE_DOOM_ENTRY_COMPLETE,
STATE_ADD_TO_ENTRY,
STATE_ADD_TO_ENTRY_COMPLETE,
+ STATE_NOTIFY_BEFORE_SEND_HEADERS,
+ STATE_NOTIFY_BEFORE_SEND_HEADERS_COMPLETE,
STATE_START_PARTIAL_CACHE_VALIDATION,
STATE_COMPLETE_PARTIAL_CACHE_VALIDATION,
STATE_UPDATE_CACHED_RESPONSE,
@@ -195,6 +197,8 @@ class HttpCache::Transaction : public HttpTransaction {
int DoDoomEntryComplete(int result);
int DoAddToEntry();
int DoAddToEntryComplete(int result);
+ int DoNotifyBeforeSendHeaders();
+ int DoNotifyBeforeSendHeadersComplete(int result);
int DoStartPartialCacheValidation();
int DoCompletePartialCacheValidation(int result);
int DoUpdateCachedResponse();
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index fb197f8..6d1e3d5 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -99,6 +99,9 @@ HttpNetworkTransaction::HttpNetworkTransaction(HttpNetworkSession* session)
: pending_auth_target_(HttpAuth::AUTH_NONE),
ALLOW_THIS_IN_INITIALIZER_LIST(
io_callback_(this, &HttpNetworkTransaction::OnIOComplete)),
+ ALLOW_THIS_IN_INITIALIZER_LIST(delegate_callback_(
+ new CancelableCompletionCallback<HttpNetworkTransaction>(
+ this, &HttpNetworkTransaction::OnIOComplete))),
user_callback_(NULL),
session_(session),
request_(NULL),
@@ -146,6 +149,8 @@ HttpNetworkTransaction::~HttpNetworkTransaction() {
}
}
}
+
+ delegate_callback_->Cancel();
}
int HttpNetworkTransaction::Start(const HttpRequestInfo* request_info,
@@ -514,9 +519,16 @@ int HttpNetworkTransaction::DoLoop(int result) {
case STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE:
rv = DoGenerateServerAuthTokenComplete(rv);
break;
- case STATE_SEND_REQUEST:
+ case STATE_BUILD_REQUEST:
DCHECK_EQ(OK, rv);
net_log_.BeginEvent(NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST, NULL);
+ rv = DoBuildRequest();
+ break;
+ case STATE_BUILD_REQUEST_COMPLETE:
+ rv = DoBuildRequestComplete(rv);
+ break;
+ case STATE_SEND_REQUEST:
+ DCHECK_EQ(OK, rv);
rv = DoSendRequest();
break;
case STATE_SEND_REQUEST_COMPLETE:
@@ -661,38 +673,58 @@ int HttpNetworkTransaction::DoGenerateServerAuthToken() {
int HttpNetworkTransaction::DoGenerateServerAuthTokenComplete(int rv) {
DCHECK_NE(ERR_IO_PENDING, rv);
if (rv == OK)
- next_state_ = STATE_SEND_REQUEST;
+ next_state_ = STATE_BUILD_REQUEST;
return rv;
}
-int HttpNetworkTransaction::DoSendRequest() {
- next_state_ = STATE_SEND_REQUEST_COMPLETE;
+int HttpNetworkTransaction::DoBuildRequest() {
+ next_state_ = STATE_BUILD_REQUEST_COMPLETE;
- UploadDataStream* request_body = NULL;
+ request_body_.reset(NULL);
if (request_->upload_data) {
int error_code;
- request_body = UploadDataStream::Create(request_->upload_data, &error_code);
- if (!request_body)
+ request_body_.reset(
+ UploadDataStream::Create(request_->upload_data, &error_code));
+ if (!request_body_.get())
return error_code;
}
+ headers_valid_ = false;
+
// This is constructed lazily (instead of within our Start method), so that
// we have proxy info available.
if (request_headers_.IsEmpty()) {
- bool using_proxy = (proxy_info_.is_http()|| proxy_info_.is_https()) &&
+ bool using_proxy = (proxy_info_.is_http() || proxy_info_.is_https()) &&
!is_https_request();
- HttpUtil::BuildRequestHeaders(request_, request_body, auth_controllers_,
+ HttpUtil::BuildRequestHeaders(request_, request_body_.get(),
+ auth_controllers_,
ShouldApplyServerAuth(),
ShouldApplyProxyAuth(), using_proxy,
&request_headers_);
+ }
- if (session_->network_delegate())
- session_->network_delegate()->NotifySendHttpRequest(&request_headers_);
+ delegate_callback_->AddRef(); // balanced in DoSendRequestComplete
+ if (session_->network_delegate()) {
+ return session_->network_delegate()->NotifyBeforeSendHeaders(
+ request_->request_id, &request_headers_, delegate_callback_);
}
- headers_valid_ = false;
- return stream_->SendRequest(request_headers_, request_body, &response_,
- &io_callback_);
+ return OK;
+}
+
+int HttpNetworkTransaction::DoBuildRequestComplete(int result) {
+ delegate_callback_->Release(); // balanced in DoBuildRequest
+
+ if (result == OK)
+ next_state_ = STATE_SEND_REQUEST;
+ return result;
+}
+
+int HttpNetworkTransaction::DoSendRequest() {
+ next_state_ = STATE_SEND_REQUEST_COMPLETE;
+
+ return stream_->SendRequest(
+ request_headers_, request_body_.release(), &response_, &io_callback_);
}
int HttpNetworkTransaction::DoSendRequestComplete(int result) {
@@ -1238,6 +1270,8 @@ std::string HttpNetworkTransaction::DescribeState(State state) {
switch (state) {
STATE_CASE(STATE_CREATE_STREAM);
STATE_CASE(STATE_CREATE_STREAM_COMPLETE);
+ STATE_CASE(STATE_BUILD_REQUEST);
+ STATE_CASE(STATE_BUILD_REQUEST_COMPLETE);
STATE_CASE(STATE_SEND_REQUEST);
STATE_CASE(STATE_SEND_REQUEST_COMPLETE);
STATE_CASE(STATE_READ_HEADERS);
diff --git a/net/http/http_network_transaction.h b/net/http/http_network_transaction.h
index 2f55f4f..414b1f9 100644
--- a/net/http/http_network_transaction.h
+++ b/net/http/http_network_transaction.h
@@ -94,6 +94,8 @@ class HttpNetworkTransaction : public HttpTransaction,
STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE,
STATE_GENERATE_SERVER_AUTH_TOKEN,
STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE,
+ STATE_BUILD_REQUEST,
+ STATE_BUILD_REQUEST_COMPLETE,
STATE_SEND_REQUEST,
STATE_SEND_REQUEST_COMPLETE,
STATE_READ_HEADERS,
@@ -125,6 +127,8 @@ class HttpNetworkTransaction : public HttpTransaction,
int DoGenerateProxyAuthTokenComplete(int result);
int DoGenerateServerAuthToken();
int DoGenerateServerAuthTokenComplete(int result);
+ int DoBuildRequest();
+ int DoBuildRequestComplete(int result);
int DoSendRequest();
int DoSendRequestComplete(int result);
int DoReadHeaders();
@@ -217,7 +221,10 @@ class HttpNetworkTransaction : public HttpTransaction,
HttpAuth::Target pending_auth_target_;
CompletionCallbackImpl<HttpNetworkTransaction> io_callback_;
+ scoped_refptr<CancelableCompletionCallback<HttpNetworkTransaction> >
+ delegate_callback_;
CompletionCallback* user_callback_;
+ scoped_ptr<UploadDataStream> request_body_;
scoped_refptr<HttpNetworkSession> session_;
diff --git a/net/http/http_request_info.cc b/net/http/http_request_info.cc
index 8ab3096..18c1b84 100644
--- a/net/http/http_request_info.cc
+++ b/net/http/http_request_info.cc
@@ -9,7 +9,8 @@ namespace net {
HttpRequestInfo::HttpRequestInfo()
: load_flags(0),
priority(LOWEST),
- motivation(NORMAL_MOTIVATION) {
+ motivation(NORMAL_MOTIVATION),
+ request_id(0) {
}
HttpRequestInfo::~HttpRequestInfo() {}
diff --git a/net/http/http_request_info.h b/net/http/http_request_info.h
index 70c1300..b906cf5 100644
--- a/net/http/http_request_info.h
+++ b/net/http/http_request_info.h
@@ -52,6 +52,10 @@ struct HttpRequestInfo {
// The motivation behind this request.
RequestMotivation motivation;
+
+ // An optional globally unique identifier for this request for use by the
+ // consumer. 0 is invalid.
+ uint64 request_id;
};
} // namespace net