| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "base/stringprintf.h" | 9 #include "base/stringprintf.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 request_headers_(NULL), | 70 request_headers_(NULL), |
| 71 request_body_(NULL), | 71 request_body_(NULL), |
| 72 read_buf_(read_buffer), | 72 read_buf_(read_buffer), |
| 73 read_buf_unused_offset_(0), | 73 read_buf_unused_offset_(0), |
| 74 response_header_start_offset_(-1), | 74 response_header_start_offset_(-1), |
| 75 response_body_length_(-1), | 75 response_body_length_(-1), |
| 76 response_body_read_(0), | 76 response_body_read_(0), |
| 77 chunked_decoder_(NULL), | 77 chunked_decoder_(NULL), |
| 78 user_read_buf_(NULL), | 78 user_read_buf_(NULL), |
| 79 user_read_buf_len_(0), | 79 user_read_buf_len_(0), |
| 80 user_callback_(NULL), | |
| 81 connection_(connection), | 80 connection_(connection), |
| 82 net_log_(net_log), | 81 net_log_(net_log), |
| 83 ALLOW_THIS_IN_INITIALIZER_LIST( | 82 ALLOW_THIS_IN_INITIALIZER_LIST( |
| 84 io_callback_( | 83 io_callback_( |
| 85 base::Bind(&HttpStreamParser::OnIOComplete, | 84 base::Bind(&HttpStreamParser::OnIOComplete, |
| 86 base::Unretained(this)))), | 85 base::Unretained(this)))), |
| 87 chunk_length_(0), | 86 chunk_length_(0), |
| 88 chunk_length_without_encoding_(0), | 87 chunk_length_without_encoding_(0), |
| 89 sent_last_chunk_(false) { | 88 sent_last_chunk_(false) { |
| 90 } | 89 } |
| 91 | 90 |
| 92 HttpStreamParser::~HttpStreamParser() { | 91 HttpStreamParser::~HttpStreamParser() { |
| 93 if (request_body_ != NULL && request_body_->is_chunked()) | 92 if (request_body_ != NULL && request_body_->is_chunked()) |
| 94 request_body_->set_chunk_callback(NULL); | 93 request_body_->set_chunk_callback(NULL); |
| 95 } | 94 } |
| 96 | 95 |
| 97 int HttpStreamParser::SendRequest(const std::string& request_line, | 96 int HttpStreamParser::SendRequest(const std::string& request_line, |
| 98 const HttpRequestHeaders& headers, | 97 const HttpRequestHeaders& headers, |
| 99 UploadDataStream* request_body, | 98 UploadDataStream* request_body, |
| 100 HttpResponseInfo* response, | 99 HttpResponseInfo* response, |
| 101 OldCompletionCallback* callback) { | 100 const CompletionCallback& callback) { |
| 102 DCHECK_EQ(STATE_NONE, io_state_); | 101 DCHECK_EQ(STATE_NONE, io_state_); |
| 103 DCHECK(!user_callback_); | 102 DCHECK(callback_.is_null()); |
| 104 DCHECK(callback); | 103 DCHECK(!callback.is_null()); |
| 105 DCHECK(response); | 104 DCHECK(response); |
| 106 | 105 |
| 107 if (net_log_.IsLoggingAllEvents()) { | 106 if (net_log_.IsLoggingAllEvents()) { |
| 108 net_log_.AddEvent( | 107 net_log_.AddEvent( |
| 109 NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS, | 108 NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS, |
| 110 make_scoped_refptr(new NetLogHttpRequestParameter( | 109 make_scoped_refptr(new NetLogHttpRequestParameter( |
| 111 request_line, headers))); | 110 request_line, headers))); |
| 112 } | 111 } |
| 113 DVLOG(1) << __FUNCTION__ << "()" | 112 DVLOG(1) << __FUNCTION__ << "()" |
| 114 << " request_line = \"" << request_line << "\"" | 113 << " request_line = \"" << request_line << "\"" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 130 if (request_body_ != NULL && request_body_->is_chunked()) { | 129 if (request_body_ != NULL && request_body_->is_chunked()) { |
| 131 request_body_->set_chunk_callback(this); | 130 request_body_->set_chunk_callback(this); |
| 132 const int kChunkHeaderFooterSize = 12; // 2 CRLFs + max of 8 hex chars. | 131 const int kChunkHeaderFooterSize = 12; // 2 CRLFs + max of 8 hex chars. |
| 133 chunk_buf_ = new IOBuffer(request_body_->GetMaxBufferSize() + | 132 chunk_buf_ = new IOBuffer(request_body_->GetMaxBufferSize() + |
| 134 kChunkHeaderFooterSize); | 133 kChunkHeaderFooterSize); |
| 135 } | 134 } |
| 136 | 135 |
| 137 io_state_ = STATE_SENDING_HEADERS; | 136 io_state_ = STATE_SENDING_HEADERS; |
| 138 result = DoLoop(OK); | 137 result = DoLoop(OK); |
| 139 if (result == ERR_IO_PENDING) | 138 if (result == ERR_IO_PENDING) |
| 140 user_callback_ = callback; | 139 callback_ = callback; |
| 141 | 140 |
| 142 return result > 0 ? OK : result; | 141 return result > 0 ? OK : result; |
| 143 } | 142 } |
| 144 | 143 |
| 145 int HttpStreamParser::ReadResponseHeaders(OldCompletionCallback* callback) { | 144 int HttpStreamParser::ReadResponseHeaders(const CompletionCallback& callback) { |
| 146 DCHECK(io_state_ == STATE_REQUEST_SENT || io_state_ == STATE_DONE); | 145 DCHECK(io_state_ == STATE_REQUEST_SENT || io_state_ == STATE_DONE); |
| 147 DCHECK(!user_callback_); | 146 DCHECK(callback_.is_null()); |
| 148 DCHECK(callback); | 147 DCHECK(!callback.is_null()); |
| 149 | 148 |
| 150 // This function can be called with io_state_ == STATE_DONE if the | 149 // This function can be called with io_state_ == STATE_DONE if the |
| 151 // connection is closed after seeing just a 1xx response code. | 150 // connection is closed after seeing just a 1xx response code. |
| 152 if (io_state_ == STATE_DONE) | 151 if (io_state_ == STATE_DONE) |
| 153 return ERR_CONNECTION_CLOSED; | 152 return ERR_CONNECTION_CLOSED; |
| 154 | 153 |
| 155 int result = OK; | 154 int result = OK; |
| 156 io_state_ = STATE_READ_HEADERS; | 155 io_state_ = STATE_READ_HEADERS; |
| 157 | 156 |
| 158 if (read_buf_->offset() > 0) { | 157 if (read_buf_->offset() > 0) { |
| 159 // Simulate the state where the data was just read from the socket. | 158 // Simulate the state where the data was just read from the socket. |
| 160 result = read_buf_->offset() - read_buf_unused_offset_; | 159 result = read_buf_->offset() - read_buf_unused_offset_; |
| 161 read_buf_->set_offset(read_buf_unused_offset_); | 160 read_buf_->set_offset(read_buf_unused_offset_); |
| 162 } | 161 } |
| 163 if (result > 0) | 162 if (result > 0) |
| 164 io_state_ = STATE_READ_HEADERS_COMPLETE; | 163 io_state_ = STATE_READ_HEADERS_COMPLETE; |
| 165 | 164 |
| 166 result = DoLoop(result); | 165 result = DoLoop(result); |
| 167 if (result == ERR_IO_PENDING) | 166 if (result == ERR_IO_PENDING) |
| 168 user_callback_ = callback; | 167 callback_ = callback; |
| 169 | 168 |
| 170 return result > 0 ? OK : result; | 169 return result > 0 ? OK : result; |
| 171 } | 170 } |
| 172 | 171 |
| 173 void HttpStreamParser::Close(bool not_reusable) { | 172 void HttpStreamParser::Close(bool not_reusable) { |
| 174 if (not_reusable && connection_->socket()) | 173 if (not_reusable && connection_->socket()) |
| 175 connection_->socket()->Disconnect(); | 174 connection_->socket()->Disconnect(); |
| 176 connection_->Reset(); | 175 connection_->Reset(); |
| 177 } | 176 } |
| 178 | 177 |
| 179 int HttpStreamParser::ReadResponseBody(IOBuffer* buf, int buf_len, | 178 int HttpStreamParser::ReadResponseBody(IOBuffer* buf, int buf_len, |
| 180 OldCompletionCallback* callback) { | 179 const CompletionCallback& callback) { |
| 181 DCHECK(io_state_ == STATE_BODY_PENDING || io_state_ == STATE_DONE); | 180 DCHECK(io_state_ == STATE_BODY_PENDING || io_state_ == STATE_DONE); |
| 182 DCHECK(!user_callback_); | 181 DCHECK(callback_.is_null()); |
| 183 DCHECK(callback); | 182 DCHECK(!callback.is_null()); |
| 184 DCHECK_LE(buf_len, kMaxBufSize); | 183 DCHECK_LE(buf_len, kMaxBufSize); |
| 185 | 184 |
| 186 if (io_state_ == STATE_DONE) | 185 if (io_state_ == STATE_DONE) |
| 187 return OK; | 186 return OK; |
| 188 | 187 |
| 189 user_read_buf_ = buf; | 188 user_read_buf_ = buf; |
| 190 user_read_buf_len_ = buf_len; | 189 user_read_buf_len_ = buf_len; |
| 191 io_state_ = STATE_READ_BODY; | 190 io_state_ = STATE_READ_BODY; |
| 192 | 191 |
| 193 int result = DoLoop(OK); | 192 int result = DoLoop(OK); |
| 194 if (result == ERR_IO_PENDING) | 193 if (result == ERR_IO_PENDING) |
| 195 user_callback_ = callback; | 194 callback_ = callback; |
| 196 | 195 |
| 197 return result; | 196 return result; |
| 198 } | 197 } |
| 199 | 198 |
| 200 void HttpStreamParser::OnIOComplete(int result) { | 199 void HttpStreamParser::OnIOComplete(int result) { |
| 201 result = DoLoop(result); | 200 result = DoLoop(result); |
| 202 | 201 |
| 203 // The client callback can do anything, including destroying this class, | 202 // The client callback can do anything, including destroying this class, |
| 204 // so any pending callback must be issued after everything else is done. | 203 // so any pending callback must be issued after everything else is done. |
| 205 if (result != ERR_IO_PENDING && user_callback_) { | 204 if (result != ERR_IO_PENDING && !callback_.is_null()) { |
| 206 OldCompletionCallback* c = user_callback_; | 205 CompletionCallback c = callback_; |
| 207 user_callback_ = NULL; | 206 callback_.Reset(); |
| 208 c->Run(result); | 207 c.Run(result); |
| 209 } | 208 } |
| 210 } | 209 } |
| 211 | 210 |
| 212 void HttpStreamParser::OnChunkAvailable() { | 211 void HttpStreamParser::OnChunkAvailable() { |
| 213 // This method may get called while sending the headers or body, so check | 212 // This method may get called while sending the headers or body, so check |
| 214 // before processing the new data. If we were still initializing or sending | 213 // before processing the new data. If we were still initializing or sending |
| 215 // headers, we will automatically start reading the chunks once we get into | 214 // headers, we will automatically start reading the chunks once we get into |
| 216 // STATE_SENDING_BODY so nothing to do here. | 215 // STATE_SENDING_BODY so nothing to do here. |
| 217 DCHECK(io_state_ == STATE_SENDING_HEADERS || io_state_ == STATE_SENDING_BODY); | 216 DCHECK(io_state_ == STATE_SENDING_HEADERS || io_state_ == STATE_SENDING_BODY); |
| 218 if (io_state_ == STATE_SENDING_BODY) | 217 if (io_state_ == STATE_SENDING_BODY) |
| (...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 761 void HttpStreamParser::GetSSLCertRequestInfo( | 760 void HttpStreamParser::GetSSLCertRequestInfo( |
| 762 SSLCertRequestInfo* cert_request_info) { | 761 SSLCertRequestInfo* cert_request_info) { |
| 763 if (request_->url.SchemeIs("https") && connection_->socket()) { | 762 if (request_->url.SchemeIs("https") && connection_->socket()) { |
| 764 SSLClientSocket* ssl_socket = | 763 SSLClientSocket* ssl_socket = |
| 765 static_cast<SSLClientSocket*>(connection_->socket()); | 764 static_cast<SSLClientSocket*>(connection_->socket()); |
| 766 ssl_socket->GetSSLCertRequestInfo(cert_request_info); | 765 ssl_socket->GetSSLCertRequestInfo(cert_request_info); |
| 767 } | 766 } |
| 768 } | 767 } |
| 769 | 768 |
| 770 } // namespace net | 769 } // namespace net |
| OLD | NEW |