OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "net/spdy/spdy_websocket_stream.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/bind_helpers.h" | |
9 #include "base/compiler_specific.h" | |
10 #include "net/base/io_buffer.h" | |
11 #include "net/base/net_errors.h" | |
12 #include "net/spdy/spdy_framer.h" | |
13 #include "net/spdy/spdy_protocol.h" | |
14 #include "net/spdy/spdy_session.h" | |
15 #include "net/spdy/spdy_stream.h" | |
16 #include "url/gurl.h" | |
17 | |
18 namespace net { | |
19 | |
20 SpdyWebSocketStream::SpdyWebSocketStream( | |
21 const base::WeakPtr<SpdySession>& spdy_session, Delegate* delegate) | |
22 : spdy_session_(spdy_session), | |
23 pending_send_data_length_(0), | |
24 delegate_(delegate), | |
25 weak_ptr_factory_(this) { | |
26 DCHECK(spdy_session_.get()); | |
27 DCHECK(delegate_); | |
28 } | |
29 | |
30 SpdyWebSocketStream::~SpdyWebSocketStream() { | |
31 delegate_ = NULL; | |
32 Close(); | |
33 } | |
34 | |
35 int SpdyWebSocketStream::InitializeStream(const GURL& url, | |
36 RequestPriority request_priority, | |
37 const BoundNetLog& net_log) { | |
38 if (!spdy_session_) | |
39 return ERR_SOCKET_NOT_CONNECTED; | |
40 | |
41 int rv = stream_request_.StartRequest( | |
42 SPDY_BIDIRECTIONAL_STREAM, spdy_session_, url, request_priority, net_log, | |
43 base::Bind(&SpdyWebSocketStream::OnSpdyStreamCreated, | |
44 weak_ptr_factory_.GetWeakPtr())); | |
45 | |
46 if (rv == OK) { | |
47 stream_ = stream_request_.ReleaseStream(); | |
48 DCHECK(stream_.get()); | |
49 stream_->SetDelegate(this); | |
50 } | |
51 return rv; | |
52 } | |
53 | |
54 int SpdyWebSocketStream::SendRequest(scoped_ptr<SpdyHeaderBlock> headers) { | |
55 if (!stream_.get()) { | |
56 NOTREACHED(); | |
57 return ERR_UNEXPECTED; | |
58 } | |
59 int result = stream_->SendRequestHeaders(headers.Pass(), MORE_DATA_TO_SEND); | |
60 if (result < OK && result != ERR_IO_PENDING) | |
61 Close(); | |
62 return result; | |
63 } | |
64 | |
65 int SpdyWebSocketStream::SendData(const char* data, int length) { | |
66 if (!stream_.get()) { | |
67 NOTREACHED(); | |
68 return ERR_UNEXPECTED; | |
69 } | |
70 DCHECK_GE(length, 0); | |
71 pending_send_data_length_ = static_cast<size_t>(length); | |
72 scoped_refptr<IOBuffer> buf(new IOBuffer(length)); | |
73 memcpy(buf->data(), data, length); | |
74 stream_->SendData(buf.get(), length, MORE_DATA_TO_SEND); | |
75 return ERR_IO_PENDING; | |
76 } | |
77 | |
78 void SpdyWebSocketStream::Close() { | |
79 if (stream_.get()) { | |
80 stream_->Close(); | |
81 DCHECK(!stream_.get()); | |
82 } | |
83 } | |
84 | |
85 void SpdyWebSocketStream::OnRequestHeadersSent() { | |
86 DCHECK(delegate_); | |
87 delegate_->OnSentSpdyHeaders(); | |
88 } | |
89 | |
90 SpdyResponseHeadersStatus SpdyWebSocketStream::OnResponseHeadersUpdated( | |
91 const SpdyHeaderBlock& response_headers) { | |
92 DCHECK(delegate_); | |
93 delegate_->OnSpdyResponseHeadersUpdated(response_headers); | |
94 return RESPONSE_HEADERS_ARE_COMPLETE; | |
95 } | |
96 | |
97 void SpdyWebSocketStream::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) { | |
98 DCHECK(delegate_); | |
99 delegate_->OnReceivedSpdyData(buffer.Pass()); | |
100 } | |
101 | |
102 void SpdyWebSocketStream::OnDataSent() { | |
103 DCHECK(delegate_); | |
104 delegate_->OnSentSpdyData(pending_send_data_length_); | |
105 pending_send_data_length_ = 0; | |
106 } | |
107 | |
108 void SpdyWebSocketStream::OnClose(int status) { | |
109 stream_.reset(); | |
110 | |
111 // Destruction without Close() call OnClose() with delegate_ being NULL. | |
112 if (!delegate_) | |
113 return; | |
114 Delegate* delegate = delegate_; | |
115 delegate_ = NULL; | |
116 delegate->OnCloseSpdyStream(); | |
117 } | |
118 | |
119 void SpdyWebSocketStream::OnSpdyStreamCreated(int result) { | |
120 DCHECK_NE(ERR_IO_PENDING, result); | |
121 if (result == OK) { | |
122 stream_ = stream_request_.ReleaseStream(); | |
123 DCHECK(stream_.get()); | |
124 stream_->SetDelegate(this); | |
125 } | |
126 DCHECK(delegate_); | |
127 delegate_->OnCreatedSpdyStream(result); | |
128 } | |
129 | |
130 } // namespace net | |
OLD | NEW |