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.
5 #include "net/spdy/spdy_websocket_stream.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"
20 SpdyWebSocketStream::SpdyWebSocketStream(
21 const base::WeakPtr
<SpdySession
>& spdy_session
, Delegate
* delegate
)
22 : spdy_session_(spdy_session
),
23 pending_send_data_length_(0),
25 weak_ptr_factory_(this) {
26 DCHECK(spdy_session_
.get());
30 SpdyWebSocketStream::~SpdyWebSocketStream() {
35 int SpdyWebSocketStream::InitializeStream(const GURL
& url
,
36 RequestPriority request_priority
,
37 const BoundNetLog
& net_log
) {
39 return ERR_SOCKET_NOT_CONNECTED
;
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()));
47 stream_
= stream_request_
.ReleaseStream();
48 DCHECK(stream_
.get());
49 stream_
->SetDelegate(this);
54 int SpdyWebSocketStream::SendRequest(scoped_ptr
<SpdyHeaderBlock
> headers
) {
57 return ERR_UNEXPECTED
;
59 int result
= stream_
->SendRequestHeaders(headers
.Pass(), MORE_DATA_TO_SEND
);
60 if (result
< OK
&& result
!= ERR_IO_PENDING
)
65 int SpdyWebSocketStream::SendData(const char* data
, int length
) {
68 return ERR_UNEXPECTED
;
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
;
78 void SpdyWebSocketStream::Close() {
81 DCHECK(!stream_
.get());
85 void SpdyWebSocketStream::OnRequestHeadersSent() {
87 delegate_
->OnSentSpdyHeaders();
90 SpdyResponseHeadersStatus
SpdyWebSocketStream::OnResponseHeadersUpdated(
91 const SpdyHeaderBlock
& response_headers
) {
93 delegate_
->OnSpdyResponseHeadersUpdated(response_headers
);
94 return RESPONSE_HEADERS_ARE_COMPLETE
;
97 void SpdyWebSocketStream::OnDataReceived(scoped_ptr
<SpdyBuffer
> buffer
) {
99 delegate_
->OnReceivedSpdyData(buffer
.Pass());
102 void SpdyWebSocketStream::OnDataSent() {
104 delegate_
->OnSentSpdyData(pending_send_data_length_
);
105 pending_send_data_length_
= 0;
108 void SpdyWebSocketStream::OnClose(int status
) {
111 // Destruction without Close() call OnClose() with delegate_ being NULL.
114 Delegate
* delegate
= delegate_
;
116 delegate
->OnCloseSpdyStream();
119 void SpdyWebSocketStream::OnSpdyStreamCreated(int result
) {
120 DCHECK_NE(ERR_IO_PENDING
, result
);
122 stream_
= stream_request_
.ReleaseStream();
123 DCHECK(stream_
.get());
124 stream_
->SetDelegate(this);
127 delegate_
->OnCreatedSpdyStream(result
);