OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/http/http_stream_parser.h" | 5 #include "net/http/http_stream_parser.h" |
6 | 6 |
7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
| 8 #include "base/field_trial.h" |
8 #include "base/trace_event.h" | 9 #include "base/trace_event.h" |
9 #include "net/base/io_buffer.h" | 10 #include "net/base/io_buffer.h" |
10 #include "net/http/http_request_info.h" | 11 #include "net/http/http_request_info.h" |
11 #include "net/http/http_response_headers.h" | 12 #include "net/http/http_response_headers.h" |
12 #include "net/http/http_util.h" | 13 #include "net/http/http_util.h" |
13 | 14 |
14 namespace net { | 15 namespace net { |
15 | 16 |
16 HttpStreamParser::HttpStreamParser(ClientSocketHandle* connection, | 17 HttpStreamParser::HttpStreamParser(ClientSocketHandle* connection, |
17 GrowableIOBuffer* read_buffer, | 18 GrowableIOBuffer* read_buffer, |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 break; | 180 break; |
180 } | 181 } |
181 } while (result != ERR_IO_PENDING && can_do_more); | 182 } while (result != ERR_IO_PENDING && can_do_more); |
182 | 183 |
183 return result; | 184 return result; |
184 } | 185 } |
185 | 186 |
186 int HttpStreamParser::DoSendHeaders(int result) { | 187 int HttpStreamParser::DoSendHeaders(int result) { |
187 request_headers_->DidConsume(result); | 188 request_headers_->DidConsume(result); |
188 | 189 |
189 if (request_headers_->BytesRemaining() > 0) { | 190 // Set up a field trial to see if splitting the first packet helps with |
| 191 // latency (loss of the first packet may otherwise cause an RTO of 3 seconds |
| 192 // at least on Windows... but with two packets, the probability of loss |
| 193 // without any ack to alert us should be lower, and receipt of a first ack |
| 194 // will lower the RTO dramatically, so recovery will be fast.). |
| 195 static const FieldTrial* kTrial = FieldTrialList::Find("PacketSplit"); |
| 196 static const bool kForceSecondPacket(kTrial && (kTrial->group() == 0)); |
| 197 if (kForceSecondPacket) |
| 198 DCHECK_EQ(kTrial->group_name(), "_first_packet_split"); |
| 199 |
| 200 int bytes_remaining = request_headers_->BytesRemaining(); |
| 201 if (bytes_remaining > 0) { |
190 // Record our best estimate of the 'request time' as the time when we send | 202 // Record our best estimate of the 'request time' as the time when we send |
191 // out the first bytes of the request headers. | 203 // out the first bytes of the request headers. |
192 if (request_headers_->BytesRemaining() == request_headers_->size()) { | 204 if (bytes_remaining == request_headers_->size()) { |
193 response_->request_time = base::Time::Now(); | 205 response_->request_time = base::Time::Now(); |
| 206 |
| 207 // Note that we ONLY ensure second packet when this is a fresh connection, |
| 208 // as a reused connection (re: reuse_type()) already had traffic, and |
| 209 // hence has an RTO which will provide for a fast packet-loss recovery. |
| 210 // We also avoid splitting out a second packet if we have a request_body_ |
| 211 // to send, as it will provide the desired second packet (see bug 38703). |
| 212 if (kForceSecondPacket && |
| 213 connection_->reuse_type() != ClientSocketHandle::REUSED_IDLE && |
| 214 (request_body_ == NULL || !request_body_->size()) && |
| 215 bytes_remaining > 1) |
| 216 --bytes_remaining; // Leave one byte for next packet. |
194 } | 217 } |
195 // TODO(vandebo) remove when bug 31096 is resolved | 218 // TODO(vandebo) remove when bug 31096 is resolved |
196 CHECK(connection_); | 219 CHECK(connection_); |
197 CHECK(connection_->socket()); | 220 CHECK(connection_->socket()); |
198 result = connection_->socket()->Write(request_headers_, | 221 result = connection_->socket()->Write(request_headers_, |
199 request_headers_->BytesRemaining(), | 222 bytes_remaining, |
200 &io_callback_); | 223 &io_callback_); |
201 } else if (request_body_ != NULL && request_body_->size()) { | 224 } else if (request_body_ != NULL && request_body_->size()) { |
202 io_state_ = STATE_SENDING_BODY; | 225 io_state_ = STATE_SENDING_BODY; |
203 result = OK; | 226 result = OK; |
204 } else { | 227 } else { |
205 io_state_ = STATE_REQUEST_SENT; | 228 io_state_ = STATE_REQUEST_SENT; |
206 } | 229 } |
207 return result; | 230 return result; |
208 } | 231 } |
209 | 232 |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
531 | 554 |
532 bool HttpStreamParser::CanFindEndOfResponse() const { | 555 bool HttpStreamParser::CanFindEndOfResponse() const { |
533 return chunked_decoder_.get() || response_body_length_ >= 0; | 556 return chunked_decoder_.get() || response_body_length_ >= 0; |
534 } | 557 } |
535 | 558 |
536 bool HttpStreamParser::IsMoreDataBuffered() const { | 559 bool HttpStreamParser::IsMoreDataBuffered() const { |
537 return read_buf_->offset() > read_buf_unused_offset_; | 560 return read_buf_->offset() > read_buf_unused_offset_; |
538 } | 561 } |
539 | 562 |
540 } // namespace net | 563 } // namespace net |
OLD | NEW |