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

Side by Side Diff: net/spdy/spdy_http_stream.cc

Issue 15701009: [SPDY] Add a SpdyStreamType enum and use it for SpdyStream (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: CHECK -> DCHECK Created 7 years, 7 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/spdy/spdy_http_stream.h" 5 #include "net/spdy/spdy_http_stream.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <list> 8 #include <list>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 12 matching lines...) Expand all
23 #include "net/spdy/spdy_protocol.h" 23 #include "net/spdy/spdy_protocol.h"
24 #include "net/spdy/spdy_session.h" 24 #include "net/spdy/spdy_session.h"
25 25
26 namespace net { 26 namespace net {
27 27
28 SpdyHttpStream::SpdyHttpStream(SpdySession* spdy_session, 28 SpdyHttpStream::SpdyHttpStream(SpdySession* spdy_session,
29 bool direct) 29 bool direct)
30 : weak_factory_(this), 30 : weak_factory_(this),
31 spdy_session_(spdy_session), 31 spdy_session_(spdy_session),
32 stream_closed_(false), 32 stream_closed_(false),
33 closed_stream_pushed_(false),
34 closed_stream_status_(ERR_FAILED), 33 closed_stream_status_(ERR_FAILED),
35 closed_stream_id_(0), 34 closed_stream_id_(0),
36 request_info_(NULL), 35 request_info_(NULL),
37 has_upload_data_(false), 36 has_upload_data_(false),
38 response_info_(NULL), 37 response_info_(NULL),
39 response_headers_received_(false), 38 response_headers_received_(false),
40 user_buffer_len_(0), 39 user_buffer_len_(0),
41 raw_request_body_buf_size_(0), 40 raw_request_body_buf_size_(0),
42 buffered_read_callback_pending_(false), 41 buffered_read_callback_pending_(false),
43 more_read_data_pending_(false), 42 more_read_data_pending_(false),
(...skipping 16 matching lines...) Expand all
60 int SpdyHttpStream::InitializeStream(const HttpRequestInfo* request_info, 59 int SpdyHttpStream::InitializeStream(const HttpRequestInfo* request_info,
61 RequestPriority priority, 60 RequestPriority priority,
62 const BoundNetLog& stream_net_log, 61 const BoundNetLog& stream_net_log,
63 const CompletionCallback& callback) { 62 const CompletionCallback& callback) {
64 DCHECK(!stream_.get()); 63 DCHECK(!stream_.get());
65 if (spdy_session_->IsClosed()) 64 if (spdy_session_->IsClosed())
66 return ERR_CONNECTION_CLOSED; 65 return ERR_CONNECTION_CLOSED;
67 66
68 request_info_ = request_info; 67 request_info_ = request_info;
69 if (request_info_->method == "GET") { 68 if (request_info_->method == "GET") {
70 int error = spdy_session_->GetPushStream(request_info_->url, &stream_, 69 int error = spdy_session_->GetPushStream(request_info_->url, &stream_,
Ryan Hamilton 2013/05/26 15:33:49 Oh, I see. it does know that it's using a push st
71 stream_net_log); 70 stream_net_log);
72 if (error != OK) 71 if (error != OK)
73 return error; 72 return error;
74 73
75 // |stream_| may be NULL even if OK was returned. 74 // |stream_| may be NULL even if OK was returned.
76 if (stream_) { 75 if (stream_) {
76 DCHECK_EQ(stream_->type(), SPDY_PUSH_STREAM);
77 stream_->SetDelegate(this); 77 stream_->SetDelegate(this);
78 return OK; 78 return OK;
79 } 79 }
80 } 80 }
81 81
82 int rv = stream_request_.StartRequest( 82 int rv = stream_request_.StartRequest(
83 spdy_session_, request_info_->url, priority, 83 SPDY_REQUEST_RESPONSE_STREAM, spdy_session_, request_info_->url,
84 stream_net_log, 84 priority, stream_net_log,
85 base::Bind(&SpdyHttpStream::OnStreamCreated, 85 base::Bind(&SpdyHttpStream::OnStreamCreated,
86 weak_factory_.GetWeakPtr(), callback)); 86 weak_factory_.GetWeakPtr(), callback));
87 87
88 if (rv == OK) { 88 if (rv == OK) {
89 stream_ = stream_request_.ReleaseStream(); 89 stream_ = stream_request_.ReleaseStream();
90 stream_->SetDelegate(this); 90 stream_->SetDelegate(this);
91 } 91 }
92 92
93 return rv; 93 return rv;
94 } 94 }
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 if (stream_id == 0) 196 if (stream_id == 0)
197 return false; 197 return false;
198 198
199 return spdy_session_->GetLoadTimingInfo(stream_id, load_timing_info); 199 return spdy_session_->GetLoadTimingInfo(stream_id, load_timing_info);
200 } 200 }
201 201
202 int SpdyHttpStream::SendRequest(const HttpRequestHeaders& request_headers, 202 int SpdyHttpStream::SendRequest(const HttpRequestHeaders& request_headers,
203 HttpResponseInfo* response, 203 HttpResponseInfo* response,
204 const CompletionCallback& callback) { 204 const CompletionCallback& callback) {
205 if (stream_closed_) { 205 if (stream_closed_) {
206 if (stream_->pushed()) 206 if (stream_->type() == SPDY_PUSH_STREAM)
207 return closed_stream_status_; 207 return closed_stream_status_;
208 208
209 return (closed_stream_status_ == OK) ? ERR_FAILED : closed_stream_status_; 209 return (closed_stream_status_ == OK) ? ERR_FAILED : closed_stream_status_;
210 } 210 }
211 211
212 base::Time request_time = base::Time::Now(); 212 base::Time request_time = base::Time::Now();
213 CHECK(stream_.get()); 213 CHECK(stream_.get());
214 214
215 stream_->SetRequestTime(request_time); 215 stream_->SetRequestTime(request_time);
216 // This should only get called in the case of a request occurring 216 // This should only get called in the case of a request occurring
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 249
250 response_info_ = response; 250 response_info_ = response;
251 251
252 // Put the peer's IP address and port into the response. 252 // Put the peer's IP address and port into the response.
253 IPEndPoint address; 253 IPEndPoint address;
254 int result = stream_->GetPeerAddress(&address); 254 int result = stream_->GetPeerAddress(&address);
255 if (result != OK) 255 if (result != OK)
256 return result; 256 return result;
257 response_info_->socket_address = HostPortPair::FromIPEndPoint(address); 257 response_info_->socket_address = HostPortPair::FromIPEndPoint(address);
258 258
259 scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock); 259 if (stream_->type() == SPDY_PUSH_STREAM) {
260 CreateSpdyHeadersFromHttpRequest(*request_info_, request_headers, 260 // Pushed streams do not send any data, and should always be
261 headers.get(), stream_->GetProtocolVersion(), 261 // idle. However, we still want to return ERR_IO_PENDING to mimic
262 direct_); 262 // non-push behavior. The callback will be called when the
263 stream_->net_log().AddEvent( 263 // response is received.
264 NetLog::TYPE_HTTP_TRANSACTION_SPDY_SEND_REQUEST_HEADERS, 264 result = ERR_IO_PENDING;
265 base::Bind(&SpdyHeaderBlockNetLogCallback, headers.get())); 265 } else {
266 result = 266 scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
267 stream_->SendRequestHeaders( 267 CreateSpdyHeadersFromHttpRequest(
268 headers.Pass(), 268 *request_info_, request_headers,
269 has_upload_data_ ? MORE_DATA_TO_SEND : NO_MORE_DATA_TO_SEND); 269 headers.get(), stream_->GetProtocolVersion(),
270 direct_);
271 stream_->net_log().AddEvent(
272 NetLog::TYPE_HTTP_TRANSACTION_SPDY_SEND_REQUEST_HEADERS,
273 base::Bind(&SpdyHeaderBlockNetLogCallback, headers.get()));
274 result =
275 stream_->SendRequestHeaders(
276 headers.Pass(),
277 has_upload_data_ ? MORE_DATA_TO_SEND : NO_MORE_DATA_TO_SEND);
278 }
279
270 if (result == ERR_IO_PENDING) { 280 if (result == ERR_IO_PENDING) {
271 CHECK(callback_.is_null()); 281 CHECK(callback_.is_null());
272 callback_ = callback; 282 callback_ = callback;
273 } 283 }
274 return result; 284 return result;
275 } 285 }
276 286
277 void SpdyHttpStream::Cancel() { 287 void SpdyHttpStream::Cancel() {
278 callback_.Reset(); 288 callback_.Reset();
279 if (stream_) { 289 if (stream_) {
280 stream_->Cancel(); 290 stream_->Cancel();
281 DCHECK(!stream_); 291 DCHECK(!stream_);
282 } 292 }
283 } 293 }
284 294
285 SpdySendStatus SpdyHttpStream::OnSendRequestHeadersComplete() { 295 void SpdyHttpStream::OnSendRequestHeadersComplete() {
286 if (!callback_.is_null()) 296 if (!callback_.is_null())
287 DoCallback(OK); 297 DoCallback(OK);
288 return has_upload_data_ ? MORE_DATA_TO_SEND : NO_MORE_DATA_TO_SEND;
289 } 298 }
290 299
291 void SpdyHttpStream::OnSendBody() { 300 void SpdyHttpStream::OnSendBody() {
292 CHECK(request_info_ && request_info_->upload_data_stream); 301 CHECK(request_info_ && request_info_->upload_data_stream);
293 if (raw_request_body_buf_size_ > 0) { 302 if (raw_request_body_buf_size_ > 0) {
294 SendRequestBodyData(); 303 SendRequestBodyData();
295 } else { 304 } else {
296 // We shouldn't be called if there's no more data to read. 305 // We shouldn't be called if there's no more data to read.
297 CHECK(!request_info_->upload_data_stream->IsEOF()); 306 CHECK(!request_info_->upload_data_stream->IsEOF());
298 ReadAndSendRequestBodyData(); 307 ReadAndSendRequestBodyData();
299 } 308 }
300 } 309 }
301 310
302 void SpdyHttpStream::OnSendBodyComplete() { 311 void SpdyHttpStream::OnSendBodyComplete() {
303 // |status| is the number of bytes written to the SPDY stream. 312 // |status| is the number of bytes written to the SPDY stream.
304 CHECK(request_info_ && request_info_->upload_data_stream); 313 CHECK(request_info_ && request_info_->upload_data_stream);
305 raw_request_body_buf_size_ = 0; 314 raw_request_body_buf_size_ = 0;
306 } 315 }
307 316
308 int SpdyHttpStream::OnResponseReceived(const SpdyHeaderBlock& response, 317 int SpdyHttpStream::OnResponseReceived(const SpdyHeaderBlock& response,
309 base::Time response_time, 318 base::Time response_time,
310 int status) { 319 int status) {
311 if (!response_info_) { 320 if (!response_info_) {
312 DCHECK(stream_->pushed()); 321 DCHECK_EQ(stream_->type(), SPDY_PUSH_STREAM);
313 push_response_info_.reset(new HttpResponseInfo); 322 push_response_info_.reset(new HttpResponseInfo);
314 response_info_ = push_response_info_.get(); 323 response_info_ = push_response_info_.get();
315 } 324 }
316 325
317 // If the response is already received, these headers are too late. 326 // If the response is already received, these headers are too late.
318 if (response_headers_received_) { 327 if (response_headers_received_) {
319 LOG(WARNING) << "SpdyHttpStream headers received after response started."; 328 LOG(WARNING) << "SpdyHttpStream headers received after response started.";
320 return OK; 329 return OK;
321 } 330 }
322 331
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 // SpdyStream won't call us with data if the header block didn't contain a 378 // SpdyStream won't call us with data if the header block didn't contain a
370 // valid set of headers. So we don't expect to not have headers received 379 // valid set of headers. So we don't expect to not have headers received
371 // here. 380 // here.
372 if (!response_headers_received_) 381 if (!response_headers_received_)
373 return ERR_INCOMPLETE_SPDY_HEADERS; 382 return ERR_INCOMPLETE_SPDY_HEADERS;
374 383
375 // Note that data may be received for a SpdyStream prior to the user calling 384 // Note that data may be received for a SpdyStream prior to the user calling
376 // ReadResponseBody(), therefore user_buffer_ may be NULL. This may often 385 // ReadResponseBody(), therefore user_buffer_ may be NULL. This may often
377 // happen for server initiated streams. 386 // happen for server initiated streams.
378 DCHECK(stream_.get()); 387 DCHECK(stream_.get());
379 DCHECK(!stream_->closed() || stream_->pushed()); 388 DCHECK(!stream_->closed() || stream_->type() == SPDY_PUSH_STREAM);
380 if (buffer) { 389 if (buffer) {
381 response_body_queue_.Enqueue(buffer.Pass()); 390 response_body_queue_.Enqueue(buffer.Pass());
382 391
383 if (user_buffer_) { 392 if (user_buffer_) {
384 // Handing small chunks of data to the caller creates measurable overhead. 393 // Handing small chunks of data to the caller creates measurable overhead.
385 // We buffer data in short time-spans and send a single read notification. 394 // We buffer data in short time-spans and send a single read notification.
386 ScheduleBufferedReadCallback(); 395 ScheduleBufferedReadCallback();
387 } 396 }
388 } 397 }
389 return OK; 398 return OK;
390 } 399 }
391 400
392 void SpdyHttpStream::OnDataSent() { 401 void SpdyHttpStream::OnDataSent() {
393 // For HTTP streams, no data is sent from the client while in the OPEN state, 402 // For HTTP streams, no data is sent from the client while in the OPEN state,
394 // so it is never called. 403 // so it is never called.
395 CHECK(false); 404 CHECK(false);
396 } 405 }
397 406
398 void SpdyHttpStream::OnClose(int status) { 407 void SpdyHttpStream::OnClose(int status) {
399 if (stream_) { 408 if (stream_) {
400 stream_closed_ = true; 409 stream_closed_ = true;
401 closed_stream_pushed_ = stream_->pushed();
402 closed_stream_status_ = status; 410 closed_stream_status_ = status;
403 closed_stream_id_ = stream_->stream_id(); 411 closed_stream_id_ = stream_->stream_id();
404 } 412 }
405 stream_.reset(); 413 stream_.reset();
406 bool invoked_callback = false; 414 bool invoked_callback = false;
407 if (status == net::OK) { 415 if (status == net::OK) {
408 // We need to complete any pending buffered read now. 416 // We need to complete any pending buffered read now.
409 invoked_callback = DoBufferedReadCallback(); 417 invoked_callback = DoBufferedReadCallback();
410 } 418 }
411 if (!invoked_callback && !callback_.is_null()) 419 if (!invoked_callback && !callback_.is_null())
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 bool SpdyHttpStream::IsSpdyHttpStream() const { 555 bool SpdyHttpStream::IsSpdyHttpStream() const {
548 return true; 556 return true;
549 } 557 }
550 558
551 void SpdyHttpStream::Drain(HttpNetworkSession* session) { 559 void SpdyHttpStream::Drain(HttpNetworkSession* session) {
552 Close(false); 560 Close(false);
553 delete this; 561 delete this;
554 } 562 }
555 563
556 } // namespace net 564 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698