- add sources.
[platform/framework/web/crosswalk.git] / src / net / spdy / spdy_websocket_stream.cc
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     : weak_ptr_factory_(this),
23       spdy_session_(spdy_session),
24       pending_send_data_length_(0),
25       delegate_(delegate) {
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