Index: net/http/bidirectional_stream.cc |
diff --git a/net/http/bidirectional_stream.cc b/net/http/bidirectional_stream.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..811ab8ae037c9cffba016fae22cbc0b7f6d56521 |
--- /dev/null |
+++ b/net/http/bidirectional_stream.cc |
@@ -0,0 +1,95 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "net/http/bidirectional_stream.h" |
+ |
+#include "base/memory/scoped_ptr.h" |
+#include "net/base/request_priority.h" |
+#include "net/spdy/spdy_buffer.h" |
+#include "net/spdy/spdy_header_block.h" |
+#include "net/spdy/spdy_http_utils.h" |
+#include "net/spdy/spdy_stream.h" |
+ |
+namespace net { |
+ |
+BidirectionalStream::BidirectionalStream( |
+ const base::WeakPtr<SpdySession>& spdy_session) |
+ : spdy_session_(spdy_session), weak_factory_(this) {} |
+ |
+BidirectionalStream::~BidirectionalStream() {} |
+ |
+void BidirectionalStream::Start(const HttpRequestInfo* request_info, |
+ Delegate* delegate) { |
+ delegate_ = delegate; |
+ DCHECK(!stream_); |
+ if (!spdy_session_) |
+ delegate_->OnFailed(ERR_CONNECTION_CLOSED); |
+ |
+ request_info_ = request_info; |
+ |
+ // TODO(xunjieli): Incorporate request priority and NetLog. |
+ int rv = stream_request_.StartRequest( |
+ SPDY_REQUEST_RESPONSE_STREAM, spdy_session_, request_info_->url, |
+ net::DEFAULT_PRIORITY, BoundNetLog(), |
+ base::Bind(&BidirectionalStream::OnStreamInitialized, |
+ weak_factory_.GetWeakPtr())); |
+ if (rv != ERR_IO_PENDING) |
+ OnStreamInitialized(rv); |
+} |
+ |
+void BidirectionalStream::SendData(IOBuffer* data, |
+ int length, |
+ bool end_stream) { |
+ stream_->SendData(data, length, |
+ end_stream ? NO_MORE_DATA_TO_SEND : MORE_DATA_TO_SEND); |
+} |
+ |
+void BidirectionalStream::OnRequestHeadersSent() { |
+ delegate_->OnRequestHeadersSent(); |
+} |
+ |
+SpdyResponseHeadersStatus BidirectionalStream::OnResponseHeadersUpdated( |
+ const SpdyHeaderBlock& response_headers) { |
+ delegate_->OnHeaders(response_headers); |
+ return RESPONSE_HEADERS_ARE_COMPLETE; |
+} |
+ |
+void BidirectionalStream::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) { |
+ delegate_->OnDataReceived(buffer.Pass()); |
+} |
+ |
+void BidirectionalStream::OnDataSent() { |
+ delegate_->OnDataSent(); |
+} |
+ |
+void BidirectionalStream::OnTrailers(const SpdyHeaderBlock& trailers) { |
+ delegate_->OnTrailers(trailers); |
+} |
+ |
+void BidirectionalStream::OnClose(int status) { |
+ delegate_->OnClose(status); |
+} |
+ |
+void BidirectionalStream::SendRequestHeaders() { |
+ stream_->SetDelegate(this); |
+ scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock); |
+ CreateSpdyHeadersFromHttpRequest(*request_info_, request_info_->extra_headers, |
+ stream_->GetProtocolVersion(), true, |
+ headers.get()); |
+ bool end_stream = (request_info_->method == "GET"); |
mef
2015/09/30 16:18:16
I wonder what should happen with different request
xunjieli
2015/10/01 18:41:16
I am not sure. Should we limit the use to POST and
mef
2015/10/07 23:44:56
Yeah, I think it is fine to keep this for now.
|
+ stream_->SendRequestHeaders( |
+ headers.Pass(), end_stream ? NO_MORE_DATA_TO_SEND : MORE_DATA_TO_SEND); |
+} |
+ |
+void BidirectionalStream::OnStreamInitialized(int rv) { |
+ DCHECK_NE(ERR_IO_PENDING, rv); |
+ if (rv == OK) { |
+ stream_ = stream_request_.ReleaseStream(); |
+ SendRequestHeaders(); |
+ return; |
+ } |
+ delegate_->OnFailed(rv); |
+} |
+ |
+} // namespace net |