Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(196)

Side by Side Diff: net/websockets/websocket_handshake_draft75.cc

Issue 1108002: Implement new websocket handshake based on draft-hixie-thewebsocketprotocol-76 (Closed)
Patch Set: fix for review comments Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2010 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/websockets/websocket_handshake_draft75.h"
6
7 #include "base/ref_counted.h"
8 #include "base/string_util.h"
9 #include "net/http/http_response_headers.h"
10 #include "net/http/http_util.h"
11
12 namespace net {
13
14 const char WebSocketHandshakeDraft75::kServerHandshakeHeader[] =
15 "HTTP/1.1 101 Web Socket Protocol Handshake\r\n";
16 const size_t WebSocketHandshakeDraft75::kServerHandshakeHeaderLength =
17 sizeof(kServerHandshakeHeader) - 1;
18
19 const char WebSocketHandshakeDraft75::kUpgradeHeader[] =
20 "Upgrade: WebSocket\r\n";
21 const size_t WebSocketHandshakeDraft75::kUpgradeHeaderLength =
22 sizeof(kUpgradeHeader) - 1;
23
24 const char WebSocketHandshakeDraft75::kConnectionHeader[] =
25 "Connection: Upgrade\r\n";
26 const size_t WebSocketHandshakeDraft75::kConnectionHeaderLength =
27 sizeof(kConnectionHeader) - 1;
28
29 WebSocketHandshakeDraft75::WebSocketHandshakeDraft75(
30 const GURL& url,
31 const std::string& origin,
32 const std::string& location,
33 const std::string& protocol)
34 : WebSocketHandshake(url, origin, location, protocol) {
35 }
36
37 WebSocketHandshakeDraft75::~WebSocketHandshakeDraft75() {
38 }
39
40 std::string WebSocketHandshakeDraft75::CreateClientHandshakeMessage() {
41 std::string msg;
42 msg = "GET ";
43 msg += GetResourceName();
44 msg += " HTTP/1.1\r\n";
45 msg += kUpgradeHeader;
46 msg += kConnectionHeader;
47 msg += "Host: ";
48 msg += GetHostFieldValue();
49 msg += "\r\n";
50 msg += "Origin: ";
51 msg += GetOriginFieldValue();
52 msg += "\r\n";
53 if (!protocol_.empty()) {
54 msg += "WebSocket-Protocol: ";
55 msg += protocol_;
56 msg += "\r\n";
57 }
58 // TODO(ukai): Add cookie if necessary.
59 msg += "\r\n";
60 return msg;
61 }
62
63 int WebSocketHandshakeDraft75::ReadServerHandshake(
64 const char* data, size_t len) {
65 mode_ = MODE_INCOMPLETE;
66 if (len < kServerHandshakeHeaderLength) {
67 return -1;
68 }
69 if (!memcmp(data, kServerHandshakeHeader, kServerHandshakeHeaderLength)) {
70 mode_ = MODE_NORMAL;
71 } else {
72 int eoh = HttpUtil::LocateEndOfHeaders(data, len);
73 if (eoh < 0)
74 return -1;
75 return eoh;
76 }
77 const char* p = data + kServerHandshakeHeaderLength;
78 const char* end = data + len;
79
80 if (mode_ == MODE_NORMAL) {
81 size_t header_size = end - p;
82 if (header_size < kUpgradeHeaderLength)
83 return -1;
84 if (memcmp(p, kUpgradeHeader, kUpgradeHeaderLength)) {
85 mode_ = MODE_FAILED;
86 DLOG(INFO) << "Bad Upgrade Header "
87 << std::string(p, kUpgradeHeaderLength);
88 return p - data;
89 }
90 p += kUpgradeHeaderLength;
91 header_size = end - p;
92 if (header_size < kConnectionHeaderLength)
93 return -1;
94 if (memcmp(p, kConnectionHeader, kConnectionHeaderLength)) {
95 mode_ = MODE_FAILED;
96 DLOG(INFO) << "Bad Connection Header "
97 << std::string(p, kConnectionHeaderLength);
98 return p - data;
99 }
100 p += kConnectionHeaderLength;
101 }
102
103 int eoh = HttpUtil::LocateEndOfHeaders(data, len);
104 if (eoh == -1)
105 return eoh;
106
107 scoped_refptr<HttpResponseHeaders> headers(
108 new HttpResponseHeaders(HttpUtil::AssembleRawHeaders(data, eoh)));
109 if (!ProcessHeaders(*headers)) {
110 DLOG(INFO) << "Process Headers failed: "
111 << std::string(data, eoh);
112 mode_ = MODE_FAILED;
113 }
114 switch (mode_) {
115 case MODE_NORMAL:
116 if (CheckResponseHeaders()) {
117 mode_ = MODE_CONNECTED;
118 } else {
119 mode_ = MODE_FAILED;
120 }
121 break;
122 default:
123 mode_ = MODE_FAILED;
124 break;
125 }
126 return eoh;
127 }
128
129 bool WebSocketHandshakeDraft75::ProcessHeaders(
130 const HttpResponseHeaders& headers) {
131 if (!GetSingleHeader(headers, "websocket-origin", &ws_origin_))
132 return false;
133
134 if (!GetSingleHeader(headers, "websocket-location", &ws_location_))
135 return false;
136
137 // If |protocol_| is not specified by client, we don't care if there's
138 // protocol field or not as specified in the spec.
139 if (!protocol_.empty()
140 && !GetSingleHeader(headers, "websocket-protocol", &ws_protocol_))
141 return false;
142 return true;
143 }
144
145 bool WebSocketHandshakeDraft75::CheckResponseHeaders() const {
146 DCHECK(mode_ == MODE_NORMAL);
147 if (!LowerCaseEqualsASCII(origin_, ws_origin_.c_str()))
148 return false;
149 if (location_ != ws_location_)
150 return false;
151 if (!protocol_.empty() && protocol_ != ws_protocol_)
152 return false;
153 return true;
154 }
155
156 } // namespace net
OLDNEW
« no previous file with comments | « net/websockets/websocket_handshake_draft75.h ('k') | net/websockets/websocket_handshake_draft75_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698