OLD | NEW |
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/server/web_socket.h" | 5 #include "net/server/web_socket.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "base/base64.h" | 9 #include "base/base64.h" |
10 #include "base/rand_util.h" | 10 #include "base/rand_util.h" |
(...skipping 28 matching lines...) Expand all Loading... |
39 if (!base::StringToInt64(result, &number)) | 39 if (!base::StringToInt64(result, &number)) |
40 return 0; | 40 return 0; |
41 return base::HostToNet32(static_cast<uint32>(number / spaces)); | 41 return base::HostToNet32(static_cast<uint32>(number / spaces)); |
42 } | 42 } |
43 | 43 |
44 class WebSocketHixie76 : public net::WebSocket { | 44 class WebSocketHixie76 : public net::WebSocket { |
45 public: | 45 public: |
46 static net::WebSocket* Create(HttpConnection* connection, | 46 static net::WebSocket* Create(HttpConnection* connection, |
47 const HttpServerRequestInfo& request, | 47 const HttpServerRequestInfo& request, |
48 size_t* pos) { | 48 size_t* pos) { |
49 if (connection->recv_data().length() < *pos + kWebSocketHandshakeBodyLen) | 49 if (connection->read_buf()->GetUnconsumedSize() |
| 50 < *pos + kWebSocketHandshakeBodyLen) |
50 return NULL; | 51 return NULL; |
51 return new WebSocketHixie76(connection, request, pos); | 52 return new WebSocketHixie76(connection, request, pos); |
52 } | 53 } |
53 | 54 |
54 virtual void Accept(const HttpServerRequestInfo& request) OVERRIDE { | 55 virtual void Accept(const HttpServerRequestInfo& request) OVERRIDE { |
55 std::string key1 = request.GetHeaderValue("sec-websocket-key1"); | 56 std::string key1 = request.GetHeaderValue("sec-websocket-key1"); |
56 std::string key2 = request.GetHeaderValue("sec-websocket-key2"); | 57 std::string key2 = request.GetHeaderValue("sec-websocket-key2"); |
57 | 58 |
58 uint32 fp1 = WebSocketKeyFingerprint(key1); | 59 uint32 fp1 = WebSocketKeyFingerprint(key1); |
59 uint32 fp2 = WebSocketKeyFingerprint(key2); | 60 uint32 fp2 = WebSocketKeyFingerprint(key2); |
(...skipping 16 matching lines...) Expand all Loading... |
76 "Sec-WebSocket-Origin: %s\r\n" | 77 "Sec-WebSocket-Origin: %s\r\n" |
77 "Sec-WebSocket-Location: %s\r\n" | 78 "Sec-WebSocket-Location: %s\r\n" |
78 "\r\n", | 79 "\r\n", |
79 origin.c_str(), | 80 origin.c_str(), |
80 location.c_str())); | 81 location.c_str())); |
81 connection_->Send(reinterpret_cast<char*>(digest.a), 16); | 82 connection_->Send(reinterpret_cast<char*>(digest.a), 16); |
82 } | 83 } |
83 | 84 |
84 virtual ParseResult Read(std::string* message) OVERRIDE { | 85 virtual ParseResult Read(std::string* message) OVERRIDE { |
85 DCHECK(message); | 86 DCHECK(message); |
86 const std::string& data = connection_->recv_data(); | 87 HttpConnection::ReadIOBuffer* read_buf = connection_->read_buf(); |
87 if (data[0]) | 88 if (read_buf->data()[0]) |
88 return FRAME_ERROR; | 89 return FRAME_ERROR; |
89 | 90 |
| 91 std::string data(read_buf->data(), read_buf->GetUnconsumedSize()); |
90 size_t pos = data.find('\377', 1); | 92 size_t pos = data.find('\377', 1); |
91 if (pos == std::string::npos) | 93 if (pos == std::string::npos) |
92 return FRAME_INCOMPLETE; | 94 return FRAME_INCOMPLETE; |
93 | 95 |
94 std::string buffer(data.begin() + 1, data.begin() + pos); | 96 message->assign(read_buf->data() + 1, pos - 1); |
95 message->swap(buffer); | 97 read_buf->DidConsume(pos + 1); |
96 connection_->Shift(pos + 1); | |
97 | 98 |
98 return FRAME_OK; | 99 return FRAME_OK; |
99 } | 100 } |
100 | 101 |
101 virtual void Send(const std::string& message) OVERRIDE { | 102 virtual void Send(const std::string& message) OVERRIDE { |
102 char message_start = 0; | 103 char message_start = 0; |
103 char message_end = -1; | 104 char message_end = -1; |
104 connection_->Send(&message_start, 1); | 105 connection_->Send(&message_start, 1); |
105 connection_->Send(message); | 106 connection_->Send(message); |
106 connection_->Send(&message_end, 1); | 107 connection_->Send(&message_end, 1); |
(...skipping 15 matching lines...) Expand all Loading... |
122 return; | 123 return; |
123 } | 124 } |
124 | 125 |
125 if (key2.empty()) { | 126 if (key2.empty()) { |
126 connection->Send(HttpServerResponseInfo::CreateFor500( | 127 connection->Send(HttpServerResponseInfo::CreateFor500( |
127 "Invalid request format. Sec-WebSocket-Key2 is empty or isn't " | 128 "Invalid request format. Sec-WebSocket-Key2 is empty or isn't " |
128 "specified.")); | 129 "specified.")); |
129 return; | 130 return; |
130 } | 131 } |
131 | 132 |
132 key3_ = connection->recv_data().substr( | 133 key3_.assign(connection->read_buf()->data() + *pos, |
133 *pos, | 134 kWebSocketHandshakeBodyLen); |
134 *pos + kWebSocketHandshakeBodyLen); | |
135 *pos += kWebSocketHandshakeBodyLen; | 135 *pos += kWebSocketHandshakeBodyLen; |
136 } | 136 } |
137 | 137 |
138 std::string key3_; | 138 std::string key3_; |
139 | 139 |
140 DISALLOW_COPY_AND_ASSIGN(WebSocketHixie76); | 140 DISALLOW_COPY_AND_ASSIGN(WebSocketHixie76); |
141 }; | 141 }; |
142 | 142 |
143 const int WebSocketHixie76::kWebSocketHandshakeBodyLen = 8; | 143 const int WebSocketHixie76::kWebSocketHandshakeBodyLen = 8; |
144 | 144 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 "HTTP/1.1 101 WebSocket Protocol Handshake\r\n" | 198 "HTTP/1.1 101 WebSocket Protocol Handshake\r\n" |
199 "Upgrade: WebSocket\r\n" | 199 "Upgrade: WebSocket\r\n" |
200 "Connection: Upgrade\r\n" | 200 "Connection: Upgrade\r\n" |
201 "Sec-WebSocket-Accept: %s\r\n" | 201 "Sec-WebSocket-Accept: %s\r\n" |
202 "\r\n", | 202 "\r\n", |
203 encoded_hash.c_str()); | 203 encoded_hash.c_str()); |
204 connection_->Send(response); | 204 connection_->Send(response); |
205 } | 205 } |
206 | 206 |
207 virtual ParseResult Read(std::string* message) OVERRIDE { | 207 virtual ParseResult Read(std::string* message) OVERRIDE { |
208 const std::string& frame = connection_->recv_data(); | 208 HttpConnection::ReadIOBuffer* read_buf = connection_->read_buf(); |
| 209 const std::string frame(read_buf->data(), read_buf->GetUnconsumedSize()); |
209 int bytes_consumed = 0; | 210 int bytes_consumed = 0; |
210 | 211 |
211 ParseResult result = | 212 ParseResult result = |
212 WebSocket::DecodeFrameHybi17(frame, true, &bytes_consumed, message); | 213 WebSocket::DecodeFrameHybi17(frame, true, &bytes_consumed, message); |
213 if (result == FRAME_OK) | 214 if (result == FRAME_OK) |
214 connection_->Shift(bytes_consumed); | 215 read_buf->DidConsume(bytes_consumed); |
215 if (result == FRAME_CLOSE) | 216 if (result == FRAME_CLOSE) |
216 closed_ = true; | 217 closed_ = true; |
217 return result; | 218 return result; |
218 } | 219 } |
219 | 220 |
220 virtual void Send(const std::string& message) OVERRIDE { | 221 virtual void Send(const std::string& message) OVERRIDE { |
221 if (closed_) | 222 if (closed_) |
222 return; | 223 return; |
223 std::string data = WebSocket::EncodeFrameHybi17(message, 0); | 224 std::string data = WebSocket::EncodeFrameHybi17(message, 0); |
224 connection_->Send(data); | 225 connection_->Send(data); |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
397 } else { | 398 } else { |
398 frame.insert(frame.end(), data, data + data_length); | 399 frame.insert(frame.end(), data, data + data_length); |
399 } | 400 } |
400 return std::string(&frame[0], frame.size()); | 401 return std::string(&frame[0], frame.size()); |
401 } | 402 } |
402 | 403 |
403 WebSocket::WebSocket(HttpConnection* connection) : connection_(connection) { | 404 WebSocket::WebSocket(HttpConnection* connection) : connection_(connection) { |
404 } | 405 } |
405 | 406 |
406 } // namespace net | 407 } // namespace net |
OLD | NEW |