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

Side by Side Diff: WebCore/websockets/WebSocketResponse.cpp

Issue 155079: WebSocket implementation in WebKit (Closed)
Patch Set: Rewrite to use SocketStreamHandle Created 11 years, 4 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
« no previous file with comments | « WebCore/websockets/WebSocketResponse.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2009 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "WebSocketResponse.h"
32
33 #include "CString.h"
34 #include "Logging.h"
35
36 #undef LOG
37 #define LOG(channel, ...) do { fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n "); } while (0);
38
39 namespace {
40
41 bool hadResponseHeader(const char *start, const char *end)
42 {
43 for (const char *p = start; p && p < end; p++) {
44 p = static_cast<const char *>(memchr(p, '\r', end - p));
45 if (!p) {
46 return false;
47 }
48 if (p + 3 < end && *(p + 1) == '\n' && *(p + 2) == '\r' && *(p + 3) == ' \n') {
49 return true;
50 }
51 }
52 return false;
53 }
54
55 }
56
57 namespace WebCore {
58
59 const char webSocketResponseHeader[] = "HTTP/1.1 101 Web Socket Protocol Handsha ke\r\n"
60 "Upgrade: WebSocket\r\n"
61 "Connection: Upgrade\r\n";
62
63 WebSocketResponse::WebSocketResponse()
64 : m_valid(false)
65 {
66 }
67
68 WebSocketResponse::~WebSocketResponse()
69 {
70 }
71
72 const char* WebSocketResponse::parseHeader(const char* start, const char* end, V ector<std::pair<String, String> >* headers)
73 {
74 Vector<char> name;
75 Vector<char> value;
76 for (const char* p = start; p < end; p++) {
77 name.clear();
78 value.clear();
79 // LOG(Network, "parseHeader next %s", p);
80 for (; p < end; p++) {
81 switch (*p) {
82 case '\r':
83 if (name.isEmpty()) {
84 if (p + 1 < end && *(p + 1) == '\n')
85 return p + 2;
86 else {
87 LOG(Network, "CF doesn't follow LF p=%p end=%p", p, end);
88 return NULL;
89 }
90 }
91 LOG(Network, "Unexpected CR in name");
92 return NULL;
93 case '\n':
94 LOG(Network, "Unexpected LF in name");
95 return NULL;
96 case ':':
97 break;
98 default:
99 if (*p >= 0x41 && *p <= 0x5a) {
100 name.append(*p + 0x20);
101 } else {
102 name.append(*p);
103 }
104 continue;
105 }
106 if (*p == ':') {
107 // LOG(Network, "colon found after name=%s", name.data());
108 ++p;
109 break;
110 }
111 }
112 // LOG(Network, "skip space: %s", p);
113 for (; p < end && *p == 0x20; p++)
114 ;
115 // LOG(Network, "parse value: %s", p);
116 for (; p < end; p++) {
117 switch (*p) {
118 case '\r':
119 break;
120 case '\n':
121 LOG(Network, "Unexpected LF in value");
122 return NULL;
123 default:
124 value.append(*p);
125 }
126 if (*p == '\r') {
127 // LOG(Network, "CR found after value=%s", value.data());
128 ++p;
129 break;
130 }
131 }
132 if (p >= end || *p != '\n') {
133 LOG(Network, "CR doesn't follow LF after value p=%p end=%p", p, end) ;
134 return NULL;
135 }
136 String name_str = String::fromUTF8(name.data(), name.size());
137 String value_str = String::fromUTF8(value.data(), value.size());
138 LOG(Network, "name=%s value=%s", name_str.utf8().data(), value_str.utf8( ).data());
139 headers->append(std::make_pair(name_str, value_str));
140 }
141 LOG(Network, "Unexpected end of header");
142 return NULL;
143 }
144
145 int WebSocketResponse::readHandshakeResponse(const char* header, int len)
146 {
147 m_valid = false;
148 if (len < sizeof(webSocketResponseHeader)) {
149 LOG(Network, "short response header len=%d", len);
150 return 0;
151 }
152 if (memcmp(header, webSocketResponseHeader, sizeof(webSocketResponseHeader) - 1) != 0) {
153 LOG(Network, "Mismatch response header: %s", header);
154 return len;
155 }
156 const char *p = header + sizeof(webSocketResponseHeader) - 1;
157 const char *end = header + len + 1;
158 if (!hadResponseHeader(p, end)) {
159 LOG(Network, "incomplete response header len=%d", len);
160 return 0;
161 }
162 Vector<std::pair<String, String> > headers;
163 p = parseHeader(p, end, &headers);
164 if (!p) {
165 LOG(Network, "parseHeader failed");
166 return len;
167 }
168 // _Headers processing_
169 for (Vector<std::pair<String, String> >::iterator it = headers.begin(); it ! = headers.end(); ++it) {
170 if (it->first == "websocket-origin") {
171 if (!m_origin.isEmpty())
172 return len;
173 m_origin = it->second;
174 } else if (it->first == "websocket-location") {
175 if (!m_location.isEmpty())
176 return len;
177 m_location = it->second;
178 } else if (it->first == "websocket-protocol") {
179 if (!m_protocol.isEmpty())
180 return len;
181 m_protocol = it->second;
182 }
183 }
184 if (m_origin.isEmpty() || m_location.isEmpty())
185 return len;
186 m_valid = true;
187 return p - header;
188 }
189
190 bool WebSocketResponse::isValidHeader() const
191 {
192 return m_valid;
193 }
194
195 void WebSocketResponse::setIsValidHeader(bool valid)
196 {
197 m_valid = valid;
198 }
199
200 const String& WebSocketResponse::websocket_origin() const
201 {
202 return m_origin;
203 }
204
205 void WebSocketResponse::setWebSocketOrigin(const String& websocket_origin)
206 {
207 m_origin = websocket_origin;
208 }
209
210 const String& WebSocketResponse::websocket_location() const
211 {
212 return m_location;
213 }
214
215 void WebSocketResponse::setWebSocketLocation(const String& websocket_location)
216 {
217 m_location = websocket_location;
218 }
219
220 const String& WebSocketResponse::websocket_protocol() const
221 {
222 return m_protocol;
223 }
224
225 void WebSocketResponse::setWebSocketProtocol(const String& websocket_protocol)
226 {
227 m_protocol = websocket_protocol;
228 }
229
230 } // namespace WebCore
OLDNEW
« no previous file with comments | « WebCore/websockets/WebSocketResponse.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698