| Index: net/http/http_stream_parser.cc
|
| ===================================================================
|
| --- net/http/http_stream_parser.cc (revision 42146)
|
| +++ net/http/http_stream_parser.cc (working copy)
|
| @@ -5,6 +5,7 @@
|
| #include "net/http/http_stream_parser.h"
|
|
|
| #include "base/compiler_specific.h"
|
| +#include "base/field_trial.h"
|
| #include "base/trace_event.h"
|
| #include "net/base/io_buffer.h"
|
| #include "net/http/http_request_info.h"
|
| @@ -186,17 +187,39 @@
|
| int HttpStreamParser::DoSendHeaders(int result) {
|
| request_headers_->DidConsume(result);
|
|
|
| - if (request_headers_->BytesRemaining() > 0) {
|
| + // Set up a field trial to see if splitting the first packet helps with
|
| + // latency (loss of the first packet may otherwise cause an RTO of 3 seconds
|
| + // at least on Windows... but with two packets, the probability of loss
|
| + // without any ack to alert us should be lower, and receipt of a first ack
|
| + // will lower the RTO dramatically, so recovery will be fast.).
|
| + static const FieldTrial* kTrial = FieldTrialList::Find("PacketSplit");
|
| + static const bool kForceSecondPacket(kTrial && (kTrial->group() == 0));
|
| + if (kForceSecondPacket)
|
| + DCHECK_EQ(kTrial->group_name(), "_first_packet_split");
|
| +
|
| + int bytes_remaining = request_headers_->BytesRemaining();
|
| + if (bytes_remaining > 0) {
|
| // Record our best estimate of the 'request time' as the time when we send
|
| // out the first bytes of the request headers.
|
| - if (request_headers_->BytesRemaining() == request_headers_->size()) {
|
| + if (bytes_remaining == request_headers_->size()) {
|
| response_->request_time = base::Time::Now();
|
| +
|
| + // Note that we ONLY ensure second packet when this is a fresh connection,
|
| + // as a reused connection (re: reuse_type()) already had traffic, and
|
| + // hence has an RTO which will provide for a fast packet-loss recovery.
|
| + // We also avoid splitting out a second packet if we have a request_body_
|
| + // to send, as it will provide the desired second packet (see bug 38703).
|
| + if (kForceSecondPacket &&
|
| + connection_->reuse_type() != ClientSocketHandle::REUSED_IDLE &&
|
| + (request_body_ == NULL || !request_body_->size()) &&
|
| + bytes_remaining > 1)
|
| + --bytes_remaining; // Leave one byte for next packet.
|
| }
|
| // TODO(vandebo) remove when bug 31096 is resolved
|
| CHECK(connection_);
|
| CHECK(connection_->socket());
|
| result = connection_->socket()->Write(request_headers_,
|
| - request_headers_->BytesRemaining(),
|
| + bytes_remaining,
|
| &io_callback_);
|
| } else if (request_body_ != NULL && request_body_->size()) {
|
| io_state_ = STATE_SENDING_BODY;
|
|
|