Another take on menu's. This uses the hosting menu scroll view container as a menuba...
[chromium-blink-merge.git] / net / websockets / websocket_handshake_draft75.cc
blob78805fb27fc3445ba8a0b00313e587384ee9c8ea
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.
5 #include "net/websockets/websocket_handshake_draft75.h"
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"
12 namespace net {
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;
19 const char WebSocketHandshakeDraft75::kUpgradeHeader[] =
20 "Upgrade: WebSocket\r\n";
21 const size_t WebSocketHandshakeDraft75::kUpgradeHeaderLength =
22 sizeof(kUpgradeHeader) - 1;
24 const char WebSocketHandshakeDraft75::kConnectionHeader[] =
25 "Connection: Upgrade\r\n";
26 const size_t WebSocketHandshakeDraft75::kConnectionHeaderLength =
27 sizeof(kConnectionHeader) - 1;
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) {
37 WebSocketHandshakeDraft75::~WebSocketHandshakeDraft75() {
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";
58 // TODO(ukai): Add cookie if necessary.
59 msg += "\r\n";
60 return msg;
63 int WebSocketHandshakeDraft75::ReadServerHandshake(
64 const char* data, size_t len) {
65 mode_ = MODE_INCOMPLETE;
66 if (len < kServerHandshakeHeaderLength) {
67 return -1;
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;
77 const char* p = data + kServerHandshakeHeaderLength;
78 const char* end = data + len;
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;
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;
100 p += kConnectionHeaderLength;
103 int eoh = HttpUtil::LocateEndOfHeaders(data, len);
104 if (eoh == -1)
105 return eoh;
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;
114 switch (mode_) {
115 case MODE_NORMAL:
116 if (CheckResponseHeaders()) {
117 mode_ = MODE_CONNECTED;
118 } else {
119 mode_ = MODE_FAILED;
121 break;
122 default:
123 mode_ = MODE_FAILED;
124 break;
126 return eoh;
129 bool WebSocketHandshakeDraft75::ProcessHeaders(
130 const HttpResponseHeaders& headers) {
131 if (!GetSingleHeader(headers, "websocket-origin", &ws_origin_))
132 return false;
134 if (!GetSingleHeader(headers, "websocket-location", &ws_location_))
135 return false;
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;
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;
156 } // namespace net