Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(158)

Side by Side Diff: net/http/http_stream_parser.cc

Issue 6134003: Prototype of chunked transfer encoded POST. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/metrics/histogram.h" 8 #include "base/metrics/histogram.h"
9 #include "net/base/auth.h" 9 #include "net/base/auth.h"
10 #include "net/base/io_buffer.h" 10 #include "net/base/io_buffer.h"
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS, 60 NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
61 make_scoped_refptr(new NetLogHttpRequestParameter( 61 make_scoped_refptr(new NetLogHttpRequestParameter(
62 request_line, headers))); 62 request_line, headers)));
63 } 63 }
64 response_ = response; 64 response_ = response;
65 std::string request = request_line + headers.ToString(); 65 std::string request = request_line + headers.ToString();
66 scoped_refptr<StringIOBuffer> headers_io_buf(new StringIOBuffer(request)); 66 scoped_refptr<StringIOBuffer> headers_io_buf(new StringIOBuffer(request));
67 request_headers_ = new DrainableIOBuffer(headers_io_buf, 67 request_headers_ = new DrainableIOBuffer(headers_io_buf,
68 headers_io_buf->size()); 68 headers_io_buf->size());
69 request_body_.reset(request_body); 69 request_body_.reset(request_body);
70 if (request_body_ != NULL && request_body_->is_chunked())
71 request_body_->set_chunk_callback(this);
70 72
71 io_state_ = STATE_SENDING_HEADERS; 73 io_state_ = STATE_SENDING_HEADERS;
72 int result = DoLoop(OK); 74 int result = DoLoop(OK);
73 if (result == ERR_IO_PENDING) 75 if (result == ERR_IO_PENDING)
74 user_callback_ = callback; 76 user_callback_ = callback;
75 77
76 return result > 0 ? OK : result; 78 return result > 0 ? OK : result;
77 } 79 }
78 80
79 int HttpStreamParser::ReadResponseHeaders(CompletionCallback* callback) { 81 int HttpStreamParser::ReadResponseHeaders(CompletionCallback* callback) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 138
137 // The client callback can do anything, including destroying this class, 139 // The client callback can do anything, including destroying this class,
138 // so any pending callback must be issued after everything else is done. 140 // so any pending callback must be issued after everything else is done.
139 if (result != ERR_IO_PENDING && user_callback_) { 141 if (result != ERR_IO_PENDING && user_callback_) {
140 CompletionCallback* c = user_callback_; 142 CompletionCallback* c = user_callback_;
141 user_callback_ = NULL; 143 user_callback_ = NULL;
142 c->Run(result); 144 c->Run(result);
143 } 145 }
144 } 146 }
145 147
148 void HttpStreamParser::OnChunkAvailable() {
149 // This method may get called while sending the headers or body, so check
150 // before processing the new data. If we were still initializing or sending
151 // headers, we will automatically start reading the chunks once we get into
152 // STATE_SENDING_BODY so nothing to do here.
153 DCHECK(io_state_ == STATE_SENDING_HEADERS || io_state_ == STATE_SENDING_BODY);
154 if (io_state_ == STATE_SENDING_BODY)
155 OnIOComplete(0);
156 }
157
146 int HttpStreamParser::DoLoop(int result) { 158 int HttpStreamParser::DoLoop(int result) {
147 bool can_do_more = true; 159 bool can_do_more = true;
148 do { 160 do {
149 switch (io_state_) { 161 switch (io_state_) {
150 case STATE_SENDING_HEADERS: 162 case STATE_SENDING_HEADERS:
151 if (result < 0) 163 if (result < 0)
152 can_do_more = false; 164 can_do_more = false;
153 else 165 else
154 result = DoSendHeaders(result); 166 result = DoSendHeaders(result);
155 break; 167 break;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 int bytes_remaining = request_headers_->BytesRemaining(); 213 int bytes_remaining = request_headers_->BytesRemaining();
202 if (bytes_remaining > 0) { 214 if (bytes_remaining > 0) {
203 // Record our best estimate of the 'request time' as the time when we send 215 // Record our best estimate of the 'request time' as the time when we send
204 // out the first bytes of the request headers. 216 // out the first bytes of the request headers.
205 if (bytes_remaining == request_headers_->size()) { 217 if (bytes_remaining == request_headers_->size()) {
206 response_->request_time = base::Time::Now(); 218 response_->request_time = base::Time::Now();
207 219
208 // We'll record the count of uncoalesced packets IFF coalescing will help, 220 // We'll record the count of uncoalesced packets IFF coalescing will help,
209 // and otherwise we'll use an enum to tell why it won't help. 221 // and otherwise we'll use an enum to tell why it won't help.
210 enum COALESCE_POTENTIAL { 222 enum COALESCE_POTENTIAL {
211 NO_ADVANTAGE = 0, // Coalescing won't reduce packet count. 223 // Coalescing won't reduce packet count.
212 HEADER_ONLY = 1, // There is only a header packet (can't coalesce). 224 NO_ADVANTAGE = 0,
213 COALESCE_POTENTIAL_MAX = 30 // Various cases of coalasced savings. 225 // There is only a header packet or we have a request body but the
226 // request body isn't available yet (can't coalesce).
227 HEADER_ONLY = 1,
228 // Various cases of coalasced savings.
229 COALESCE_POTENTIAL_MAX = 30
214 }; 230 };
215 size_t coalesce = HEADER_ONLY; 231 size_t coalesce = HEADER_ONLY;
216 if (request_body_ != NULL) { 232 if (request_body_ != NULL && !request_body_->is_chunked()) {
217 const size_t kBytesPerPacket = 1430; 233 const size_t kBytesPerPacket = 1430;
218 uint64 body_packets = (request_body_->size() + kBytesPerPacket - 1) / 234 uint64 body_packets = (request_body_->size() + kBytesPerPacket - 1) /
219 kBytesPerPacket; 235 kBytesPerPacket;
220 uint64 header_packets = (bytes_remaining + kBytesPerPacket - 1) / 236 uint64 header_packets = (bytes_remaining + kBytesPerPacket - 1) /
221 kBytesPerPacket; 237 kBytesPerPacket;
222 uint64 coalesced_packets = (request_body_->size() + bytes_remaining + 238 uint64 coalesced_packets = (request_body_->size() + bytes_remaining +
223 kBytesPerPacket - 1) / kBytesPerPacket; 239 kBytesPerPacket - 1) / kBytesPerPacket;
224 if (coalesced_packets < header_packets + body_packets) { 240 if (coalesced_packets < header_packets + body_packets) {
225 if (coalesced_packets > COALESCE_POTENTIAL_MAX) 241 if (coalesced_packets > COALESCE_POTENTIAL_MAX)
226 coalesce = COALESCE_POTENTIAL_MAX; 242 coalesce = COALESCE_POTENTIAL_MAX;
227 else 243 else
228 coalesce = static_cast<size_t>(header_packets + body_packets); 244 coalesce = static_cast<size_t>(header_packets + body_packets);
229 } else { 245 } else {
230 coalesce = NO_ADVANTAGE; 246 coalesce = NO_ADVANTAGE;
231 } 247 }
232 } 248 }
233 UMA_HISTOGRAM_ENUMERATION("Net.CoalescePotential", coalesce, 249 UMA_HISTOGRAM_ENUMERATION("Net.CoalescePotential", coalesce,
234 COALESCE_POTENTIAL_MAX); 250 COALESCE_POTENTIAL_MAX);
235 } 251 }
236 result = connection_->socket()->Write(request_headers_, 252 result = connection_->socket()->Write(request_headers_,
237 bytes_remaining, 253 bytes_remaining,
238 &io_callback_); 254 &io_callback_);
239 } else if (request_body_ != NULL && request_body_->size()) { 255 } else if (request_body_ != NULL &&
256 (request_body_->is_chunked() || request_body_->size())) {
240 io_state_ = STATE_SENDING_BODY; 257 io_state_ = STATE_SENDING_BODY;
241 result = OK; 258 result = OK;
242 } else { 259 } else {
243 io_state_ = STATE_REQUEST_SENT; 260 io_state_ = STATE_REQUEST_SENT;
244 } 261 }
245 return result; 262 return result;
246 } 263 }
247 264
248 int HttpStreamParser::DoSendBody(int result) { 265 int HttpStreamParser::DoSendBody(int result) {
249 if (result > 0) 266 request_body_->ConsumeAndFillBuffer(result);
250 request_body_->DidConsume(result);
251 267
252 if (!request_body_->eof()) { 268 if (!request_body_->eof()) {
253 int buf_len = static_cast<int>(request_body_->buf_len()); 269 int buf_len = static_cast<int>(request_body_->buf_len());
254 result = connection_->socket()->Write(request_body_->buf(), buf_len, 270 if (buf_len) {
255 &io_callback_); 271 result = connection_->socket()->Write(request_body_->buf(), buf_len,
272 &io_callback_);
273 } else {
274 // More POST data is to come hence wait for the callback.
275 result = ERR_IO_PENDING;
276 }
256 } else { 277 } else {
257 io_state_ = STATE_REQUEST_SENT; 278 io_state_ = STATE_REQUEST_SENT;
258 } 279 }
259 return result; 280 return result;
260 } 281 }
261 282
262 int HttpStreamParser::DoReadHeaders() { 283 int HttpStreamParser::DoReadHeaders() {
263 io_state_ = STATE_READ_HEADERS_COMPLETE; 284 io_state_ = STATE_READ_HEADERS_COMPLETE;
264 285
265 // Grow the read buffer if necessary. 286 // Grow the read buffer if necessary.
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 void HttpStreamParser::GetSSLCertRequestInfo( 651 void HttpStreamParser::GetSSLCertRequestInfo(
631 SSLCertRequestInfo* cert_request_info) { 652 SSLCertRequestInfo* cert_request_info) {
632 if (request_->url.SchemeIs("https") && connection_->socket()) { 653 if (request_->url.SchemeIs("https") && connection_->socket()) {
633 SSLClientSocket* ssl_socket = 654 SSLClientSocket* ssl_socket =
634 static_cast<SSLClientSocket*>(connection_->socket()); 655 static_cast<SSLClientSocket*>(connection_->socket());
635 ssl_socket->GetSSLCertRequestInfo(cert_request_info); 656 ssl_socket->GetSSLCertRequestInfo(cert_request_info);
636 } 657 }
637 } 658 }
638 659
639 } // namespace net 660 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698