Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / modules / websockets / WebSocketHandshake.cpp
index df0830c..edb9a8d 100644 (file)
 #include "core/dom/Document.h"
 #include "core/inspector/ScriptCallStack.h"
 #include "core/loader/CookieJar.h"
-#include "modules/websockets/WebSocket.h"
+#include "modules/websockets/DOMWebSocket.h"
 #include "platform/Cookie.h"
+#include "platform/Crypto.h"
 #include "platform/Logging.h"
 #include "platform/network/HTTPHeaderMap.h"
 #include "platform/network/HTTPParsers.h"
 #include "platform/weborigin/SecurityOrigin.h"
 #include "public/platform/Platform.h"
 #include "wtf/CryptographicallyRandomNumber.h"
-#include "wtf/SHA1.h"
 #include "wtf/StdLibExtras.h"
 #include "wtf/StringExtras.h"
 #include "wtf/Vector.h"
 #include "wtf/text/StringBuilder.h"
 #include "wtf/unicode/CharacterNames.h"
 
-namespace WebCore {
-
-namespace {
-
-// FIXME: The spec says that the Sec-WebSocket-Protocol header in a handshake
-// response can't be null if the header in a request is not null.
-// Some servers are not accustomed to the shutdown,
-// so we provide an adhoc white-list for it tentatively.
-const char* const missingProtocolWhiteList[] = {
-    "ica.citrix.com",
-};
+namespace blink {
 
 String formatHandshakeFailureReason(const String& detail)
 {
     return "Error during WebSocket handshake: " + detail;
 }
 
-} // namespace
-
 static String resourceName(const KURL& url)
 {
     StringBuilder name;
@@ -119,14 +107,17 @@ static String generateSecWebSocketKey()
 String WebSocketHandshake::getExpectedWebSocketAccept(const String& secWebSocketKey)
 {
     static const char webSocketKeyGUID[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
-    SHA1 sha1;
     CString keyData = secWebSocketKey.ascii();
-    sha1.addBytes(reinterpret_cast<const uint8_t*>(keyData.data()), keyData.length());
-    sha1.addBytes(reinterpret_cast<const uint8_t*>(webSocketKeyGUID), strlen(webSocketKeyGUID));
-    Vector<uint8_t, SHA1::outputSizeBytes> hash;
-    sha1.computeHash(hash);
-    return base64Encode(reinterpret_cast<const char*>(hash.data()),
-        SHA1::outputSizeBytes);
+
+    StringBuilder digestable;
+    digestable.append(secWebSocketKey);
+    digestable.append(webSocketKeyGUID, strlen(webSocketKeyGUID));
+    CString digestableCString = digestable.toString().utf8();
+    DigestValue digest;
+    bool digestSuccess = computeDigest(HashAlgorithmSha1, digestableCString.data(), digestableCString.length(), digest);
+    RELEASE_ASSERT(digestSuccess);
+
+    return base64Encode(reinterpret_cast<const char*>(digest.data()), sha1HashSize);
 }
 
 WebSocketHandshake::WebSocketHandshake(const KURL& url, const String& protocol, Document* document)
@@ -142,7 +133,7 @@ WebSocketHandshake::WebSocketHandshake(const KURL& url, const String& protocol,
 
 WebSocketHandshake::~WebSocketHandshake()
 {
-    blink::Platform::current()->histogramEnumeration("WebCore.WebSocket.HandshakeResult", m_mode, WebSocketHandshake::ModeMax);
+    Platform::current()->histogramEnumeration("WebCore.WebSocket.HandshakeResult", m_mode, WebSocketHandshake::ModeMax);
 }
 
 const KURL& WebSocketHandshake::url() const
@@ -209,13 +200,6 @@ CString WebSocketHandshake::clientHandshakeMessage() const
     if (!m_clientProtocol.isEmpty())
         fields.append("Sec-WebSocket-Protocol: " + m_clientProtocol);
 
-    KURL url = httpURLForAuthenticationAndCookies();
-
-    String cookie = cookieRequestHeaderFieldValue(m_document, url);
-    if (!cookie.isEmpty())
-        fields.append("Cookie: " + cookie);
-    // Set "Cookie2: <cookie>" if cookies 2 exists for url?
-
     // Add no-cache headers to avoid compatibility issue.
     // There are some proxies that rewrite "Connection: upgrade"
     // to "Connection: close" in the response if a request doesn't contain
@@ -289,7 +273,7 @@ void WebSocketHandshake::reset()
 
 void WebSocketHandshake::clearDocument()
 {
-    m_document = 0;
+    m_document = nullptr;
 }
 
 int WebSocketHandshake::readServerHandshake(const char* header, size_t len)
@@ -349,16 +333,6 @@ const AtomicString& WebSocketHandshake::serverWebSocketProtocol() const
     return m_response.headerFields().get("sec-websocket-protocol");
 }
 
-const AtomicString& WebSocketHandshake::serverSetCookie() const
-{
-    return m_response.headerFields().get("set-cookie");
-}
-
-const AtomicString& WebSocketHandshake::serverSetCookie2() const
-{
-    return m_response.headerFields().get("set-cookie2");
-}
-
 const AtomicString& WebSocketHandshake::serverUpgrade() const
 {
     return m_response.headerFields().get("upgrade");
@@ -478,7 +452,7 @@ const char* WebSocketHandshake::readHTTPHeaders(const char* start, const char* e
     bool sawSecWebSocketAcceptHeaderField = false;
     bool sawSecWebSocketProtocolHeaderField = false;
     const char* p = start;
-    for (; p < end; p++) {
+    while (p < end) {
         size_t consumedLength = parseHTTPHeader(p, end - p, m_failureReason, name, value);
         if (!consumedLength)
             return 0;
@@ -559,28 +533,21 @@ bool WebSocketHandshake::checkResponseHeaders()
             return false;
         }
         Vector<String> result;
-        m_clientProtocol.split(String(WebSocket::subProtocolSeperator()), result);
+        m_clientProtocol.split(String(DOMWebSocket::subprotocolSeperator()), result);
         if (!result.contains(serverWebSocketProtocol)) {
             m_failureReason = formatHandshakeFailureReason("'Sec-WebSocket-Protocol' header value '" + serverWebSocketProtocol + "' in response does not match any of sent values");
             return false;
         }
     } else if (!m_clientProtocol.isEmpty()) {
-        // FIXME: Some servers are not accustomed to this failure, so we provide an adhoc white-list for it tentatively.
-        Vector<String> protocols;
-        m_clientProtocol.split(String(WebSocket::subProtocolSeperator()), protocols);
-        bool match = false;
-        for (size_t i = 0; i < protocols.size() && !match; ++i) {
-            for (size_t j = 0; j < WTF_ARRAY_LENGTH(missingProtocolWhiteList) && !match; ++j) {
-                if (protocols[i] == missingProtocolWhiteList[j])
-                    match = true;
-            }
-        }
-        if (!match) {
-            m_failureReason = formatHandshakeFailureReason("Sent non-empty 'Sec-WebSocket-Protocol' header but no response was received");
-            return false;
-        }
+        m_failureReason = formatHandshakeFailureReason("Sent non-empty 'Sec-WebSocket-Protocol' header but no response was received");
+        return false;
     }
     return true;
 }
 
-} // namespace WebCore
+void WebSocketHandshake::trace(Visitor* visitor)
+{
+    visitor->trace(m_document);
+}
+
+} // namespace blink