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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « WebCore/websockets/WebSocketResponse.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: WebCore/websockets/WebSocketResponse.cpp
diff --git a/WebCore/websockets/WebSocketResponse.cpp b/WebCore/websockets/WebSocketResponse.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c00c6c0d5934fa1c14fb738d0fa8d8068a1d0f6c
--- /dev/null
+++ b/WebCore/websockets/WebSocketResponse.cpp
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "WebSocketResponse.h"
+
+#include "CString.h"
+#include "Logging.h"
+
+#undef LOG
+#define LOG(channel, ...) do { fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); } while (0);
+
+namespace {
+
+bool hadResponseHeader(const char *start, const char *end)
+{
+ for (const char *p = start; p && p < end; p++) {
+ p = static_cast<const char *>(memchr(p, '\r', end - p));
+ if (!p) {
+ return false;
+ }
+ if (p + 3 < end && *(p + 1) == '\n' && *(p + 2) == '\r' && *(p + 3) == '\n') {
+ return true;
+ }
+ }
+ return false;
+}
+
+}
+
+namespace WebCore {
+
+const char webSocketResponseHeader[] = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n"
+ "Upgrade: WebSocket\r\n"
+ "Connection: Upgrade\r\n";
+
+WebSocketResponse::WebSocketResponse()
+ : m_valid(false)
+{
+}
+
+WebSocketResponse::~WebSocketResponse()
+{
+}
+
+const char* WebSocketResponse::parseHeader(const char* start, const char* end, Vector<std::pair<String, String> >* headers)
+{
+ Vector<char> name;
+ Vector<char> value;
+ for (const char* p = start; p < end; p++) {
+ name.clear();
+ value.clear();
+ // LOG(Network, "parseHeader next %s", p);
+ for (; p < end; p++) {
+ switch (*p) {
+ case '\r':
+ if (name.isEmpty()) {
+ if (p + 1 < end && *(p + 1) == '\n')
+ return p + 2;
+ else {
+ LOG(Network, "CF doesn't follow LF p=%p end=%p", p, end);
+ return NULL;
+ }
+ }
+ LOG(Network, "Unexpected CR in name");
+ return NULL;
+ case '\n':
+ LOG(Network, "Unexpected LF in name");
+ return NULL;
+ case ':':
+ break;
+ default:
+ if (*p >= 0x41 && *p <= 0x5a) {
+ name.append(*p + 0x20);
+ } else {
+ name.append(*p);
+ }
+ continue;
+ }
+ if (*p == ':') {
+ // LOG(Network, "colon found after name=%s", name.data());
+ ++p;
+ break;
+ }
+ }
+ // LOG(Network, "skip space: %s", p);
+ for (; p < end && *p == 0x20; p++)
+ ;
+ // LOG(Network, "parse value: %s", p);
+ for (; p < end; p++) {
+ switch (*p) {
+ case '\r':
+ break;
+ case '\n':
+ LOG(Network, "Unexpected LF in value");
+ return NULL;
+ default:
+ value.append(*p);
+ }
+ if (*p == '\r') {
+ // LOG(Network, "CR found after value=%s", value.data());
+ ++p;
+ break;
+ }
+ }
+ if (p >= end || *p != '\n') {
+ LOG(Network, "CR doesn't follow LF after value p=%p end=%p", p, end);
+ return NULL;
+ }
+ String name_str = String::fromUTF8(name.data(), name.size());
+ String value_str = String::fromUTF8(value.data(), value.size());
+ LOG(Network, "name=%s value=%s", name_str.utf8().data(), value_str.utf8().data());
+ headers->append(std::make_pair(name_str, value_str));
+ }
+ LOG(Network, "Unexpected end of header");
+ return NULL;
+}
+
+int WebSocketResponse::readHandshakeResponse(const char* header, int len)
+{
+ m_valid = false;
+ if (len < sizeof(webSocketResponseHeader)) {
+ LOG(Network, "short response header len=%d", len);
+ return 0;
+ }
+ if (memcmp(header, webSocketResponseHeader, sizeof(webSocketResponseHeader) - 1) != 0) {
+ LOG(Network, "Mismatch response header: %s", header);
+ return len;
+ }
+ const char *p = header + sizeof(webSocketResponseHeader) - 1;
+ const char *end = header + len + 1;
+ if (!hadResponseHeader(p, end)) {
+ LOG(Network, "incomplete response header len=%d", len);
+ return 0;
+ }
+ Vector<std::pair<String, String> > headers;
+ p = parseHeader(p, end, &headers);
+ if (!p) {
+ LOG(Network, "parseHeader failed");
+ return len;
+ }
+ // _Headers processing_
+ for (Vector<std::pair<String, String> >::iterator it = headers.begin(); it != headers.end(); ++it) {
+ if (it->first == "websocket-origin") {
+ if (!m_origin.isEmpty())
+ return len;
+ m_origin = it->second;
+ } else if (it->first == "websocket-location") {
+ if (!m_location.isEmpty())
+ return len;
+ m_location = it->second;
+ } else if (it->first == "websocket-protocol") {
+ if (!m_protocol.isEmpty())
+ return len;
+ m_protocol = it->second;
+ }
+ }
+ if (m_origin.isEmpty() || m_location.isEmpty())
+ return len;
+ m_valid = true;
+ return p - header;
+}
+
+bool WebSocketResponse::isValidHeader() const
+{
+ return m_valid;
+}
+
+void WebSocketResponse::setIsValidHeader(bool valid)
+{
+ m_valid = valid;
+}
+
+const String& WebSocketResponse::websocket_origin() const
+{
+ return m_origin;
+}
+
+void WebSocketResponse::setWebSocketOrigin(const String& websocket_origin)
+{
+ m_origin = websocket_origin;
+}
+
+const String& WebSocketResponse::websocket_location() const
+{
+ return m_location;
+}
+
+void WebSocketResponse::setWebSocketLocation(const String& websocket_location)
+{
+ m_location = websocket_location;
+}
+
+const String& WebSocketResponse::websocket_protocol() const
+{
+ return m_protocol;
+}
+
+void WebSocketResponse::setWebSocketProtocol(const String& websocket_protocol)
+{
+ m_protocol = websocket_protocol;
+}
+
+} // namespace WebCore
« 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