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; |