< Previous by Date Date Index Next by Date >
  Thread Index Next in Thread >

[reSIProcate] [resip/stack][patch 1/2] Code cleanup for ConnectionBase.cxx


Hi all,

This patch removes an entire portion of wsProcessHandshake() that
deals with an deprecated protocol. [1]
There is also a bit of refactoring. Scanning the message header is its
own function now. Making the handshake response is also its own
function, which handles instances when a header can not be found.

[1] http://www.whatwg.org/specs/web-socket-protocol/

Best,
Zhi An

---diff starts below---
Index: ConnectionBase.cxx
===================================================================
--- ConnectionBase.cxx (revision 10202)
+++ ConnectionBase.cxx (working copy)
@@ -556,104 +556,30 @@
    mMessage->setSource(mWho);
    mMessage->setTlsDomain(mWho.transport->tlsDomain());

-   mMsgHeaderScanner.prepareForMessage(mMessage);
-   char *unprocessedCharPtr;
-   MsgHeaderScanner::ScanChunkResult scanResult =
mMsgHeaderScanner.scanChunk(mBuffer, mBufferPos + bytesRead,
&unprocessedCharPtr);
-   if (scanResult != MsgHeaderScanner::scrEnd)
-   {
-      if(scanResult != MsgHeaderScanner::scrNextChunk)
-      {
-         StackLog(<<"Failed to parse message, more bytes needed");
-         StackLog(<< Data(mBuffer, bytesRead));
-      }
-      delete mMessage;
-      mMessage=0;
-      mBufferPos += bytesRead;
+   if (!scanMsgHeader(bytesRead)) {
       return false;
    }

    try
    {
-      Data wsResponse;
-      wsResponse = "HTTP/1.1 101 WebSocket Protocol Handshake\r\n"
-            "Upgrade: WebSocket\r\n"
-            "Connection: Upgrade\r\n"
-            "Sec-WebSocket-Protocol: sip\r\n";
-
-      if(mMessage->exists(h_SecWebSocketKey1) &&
mMessage->exists(h_SecWebSocketKey2))
+      Data wsResponse = makeWsHandshakeResponse();
+      if (!wsResponse.empty())
       {
-         Data SecWebSocketKey1 =
mMessage->const_header(h_SecWebSocketKey1).value();
-         Data SecWebSocketKey2 =
mMessage->const_header(h_SecWebSocketKey2).value();
-         Data Digits1, Digits2;
-         unsigned int SpacesCount1 = 0, SpacesCount2 = 0;
-         unsigned int Value1, Value2;
-         for(unsigned int i = 0; i < SecWebSocketKey1.size(); ++i)
-         {
-            if(SecWebSocketKey1[i] == ' ') ++SpacesCount1;
-            if(isdigit(SecWebSocketKey1[i])) Digits1 += SecWebSocketKey1[i];
-         }
-         Value1 = htonl(Digits1.convertUnsignedLong() / SpacesCount1);
-         for(unsigned int i = 0; i < SecWebSocketKey2.size(); ++i)
-         {
-            if(SecWebSocketKey2[i] == ' ') ++SpacesCount2;
-            if(isdigit(SecWebSocketKey2[i])) Digits2 += SecWebSocketKey2[i];
-         }
-         Value2 = htonl(Digits2.convertUnsignedLong() / SpacesCount2);
-
-         MD5Stream wsMD5Stream;
-         char tmp[9] = { '\0' };
-         memcpy(tmp, &Value1, 4);
-         memcpy(&tmp[4], &Value2, 4);
-         wsMD5Stream << tmp;
-         if(unprocessedCharPtr < (mBuffer + mBufferPos + bytesRead))
-         {
-            unsigned int dataLen = (mBuffer + mBufferPos + bytesRead)
- unprocessedCharPtr;
-            Data content(unprocessedCharPtr, dataLen);
-            wsMD5Stream << content;
-         }
-
-         if(mMessage->exists(h_Origin))
-         {
-            wsResponse += "Sec-WebSocket-Origin: " +
mMessage->const_header(h_Origin).value() + "\r\n";
-         }
-         if(mMessage->exists(h_Host))
-         {
-            wsResponse += Data("Sec-WebSocket-Location: ") +
Data(transport()->transport() == resip::WSS ? "wss://" : "ws://") +
mMessage->const_header(h_Host).value() + Data("/\r\n");
-         }
-         wsResponse += "\r\n" + wsMD5Stream.getBin();
-         ErrLog(<<"WS client wants to use depracated protocol
version, unsupported");
-         delete mMessage;
-         mMessage = 0;
-         mBufferPos = 0;
-         dropConnection = true;
-         return false;
+         mOutstandingSends.push_back(new SendData(
+                  who(),
+                  wsResponse,
+                  Data::Empty,
+                  Data::Empty,
+                  true));
       }
-      else if(mMessage->exists(h_SecWebSocketKey))
-      {
-#ifdef USE_SSL
-         SHA1Stream wsSha1Stream;
-         wsSha1Stream <<
(mMessage->const_header(h_SecWebSocketKey).value() +
Data("258EAFA5-E914-47DA-95CA-C5AB0DC85B11"));
-         Data wsAcceptKey = wsSha1Stream.getBin(160).base64encode();
-         wsResponse += "Sec-WebSocket-Accept: "+ wsAcceptKey +"\r\n"
-               "\r\n";
-#endif
-      }
       else
       {
-         ErrLog(<<"No SecWebSocketKey header");
+         dropConnection = true;
          delete mMessage;
          mMessage = 0;
          mBufferPos = 0;
-         dropConnection = true;
          return false;
       }
-
-      mOutstandingSends.push_back(new SendData(
-            who(),
-            wsResponse,
-            Data::Empty,
-            Data::Empty,
-            true));
    }
    catch(resip::ParseException& e)
    {
@@ -661,7 +587,6 @@
       delete mMessage;
       mMessage = 0;
       mBufferPos = 0;
-      dropConnection = true;
       return false;
    }

@@ -672,7 +597,67 @@
    return true;
 }

+Data
+ConnectionBase::makeWsHandshakeResponse()
+{
+   Data response = "HTTP/1.1 101 WebSocket Protocol Handshake\r\n"
+      "Upgrade: WebSocket\r\n"
+      "Connection: Upgrade\r\n"
+      "Sec-WebSocket-Protocol: sip\r\n";
+
+   if(isUsingSecWebSocketKey())
+   {
+#ifdef USE_SSL
+      SHA1Stream wsSha1Stream;
+      wsSha1Stream <<
(mMessage->const_header(h_SecWebSocketKey).value() +
Data("258EAFA5-E914-47DA-95CA-C5AB0DC85B11"));
+      Data wsAcceptKey = wsSha1Stream.getBin(160).base64encode();
+      response += "Sec-WebSocket-Accept: " + wsAcceptKey + "\r\n\r\n";
+#endif
+      return response;
+   }
+   else if(isUsingDeprecatedSecWebSocketKeys())
+   {
+      ErrLog(<<"WS client wants to use depracated protocol version,
unsupported");
+   }
+   else
+   {
+      ErrLog(<<"No SecWebSocketKey header");
+   }
+   return NULL;
+}
+
 bool
+ConnectionBase::scanMsgHeader(int bytesRead)
+{
+   mMsgHeaderScanner.prepareForMessage(mMessage);
+   char *unprocessedCharPtr;
+   MsgHeaderScanner::ScanChunkResult scanResult =
mMsgHeaderScanner.scanChunk(mBuffer, mBufferPos + bytesRead,
&unprocessedCharPtr);
+   if (scanResult != MsgHeaderScanner::scrEnd)
+   {
+      if(scanResult != MsgHeaderScanner::scrNextChunk)
+      {
+         StackLog(<<"Failed to parse message, more bytes needed");
+         StackLog(<< Data(mBuffer, bytesRead));
+      }
+      delete mMessage;
+      mMessage=0;
+      mBufferPos += bytesRead;
+      return false;
+   }
+}
+
+bool ConnectionBase::isUsingDeprecatedSecWebSocketKeys()
+{
+   return mMessage->exists(h_SecWebSocketKey1) &&
+      mMessage->exists(h_SecWebSocketKey2);
+}
+
+bool ConnectionBase::isUsingSecWebSocketKey()
+{
+   return mMessage->exists(h_SecWebSocketKey);
+}
+
+bool
 ConnectionBase::wsProcessData(int bytesRead)
 {
    bool dropConnection = false;