[cosmetics] update date in GPL header
[vuplus_xbmc] / xbmc / network / websocket / WebSocketManager.cpp
1 /*
2  *      Copyright (C) 2011-2013 Team XBMC
3  *      http://www.xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include <string>
22
23 #include "WebSocketManager.h"
24 #include "WebSocket.h"
25 #include "WebSocketV8.h"
26 #include "WebSocketV13.h"
27 #include "utils/HttpParser.h"
28 #include "utils/HttpResponse.h"
29 #include "utils/log.h"
30
31 #define WS_HTTP_METHOD          "GET"
32 #define WS_HTTP_TAG             "HTTP/"
33 #define WS_SUPPORTED_VERSIONS   "8, 13"
34
35 #define WS_HEADER_VERSION       "Sec-WebSocket-Version"
36 #define WS_HEADER_VERSION_LC    "sec-websocket-version"     // "Sec-WebSocket-Version"
37
38 using namespace std;
39
40 CWebSocket* CWebSocketManager::Handle(const char* data, unsigned int length, string &response)
41 {
42   if (data == NULL || length <= 0)
43     return NULL;
44
45   HttpParser header;
46   HttpParser::status_t status = header.addBytes(data, length);
47   switch (status)
48   {
49     case HttpParser::Error:
50     case HttpParser::Incomplete:
51       response.clear();
52       return NULL;
53
54     case HttpParser::Done:
55     default:
56       break;
57   }
58
59   // There must be a "Sec-WebSocket-Version" header
60   const char* value = header.getValue(WS_HEADER_VERSION_LC);
61   if (value == NULL)
62   {
63     CLog::Log(LOGINFO, "WebSocket: missing Sec-WebSocket-Version");
64     CHttpResponse httpResponse(HTTP::Get, HTTP::BadRequest, HTTP::Version1_1);
65     char *responseBuffer;
66     int responseLength = httpResponse.Create(responseBuffer);
67     response = std::string(responseBuffer, responseLength);
68
69     return NULL;
70   }
71   
72   CWebSocket *websocket = NULL;
73   if (strncmp(value, "8", 1) == 0)
74     websocket = new CWebSocketV8();
75   else if (strncmp(value, "13", 2) == 0)
76     websocket = new CWebSocketV13();
77
78   if (websocket == NULL)
79   {
80     CLog::Log(LOGINFO, "WebSocket: Unsupported Sec-WebSocket-Version %s", value);
81     CHttpResponse httpResponse(HTTP::Get, HTTP::UpgradeRequired, HTTP::Version1_1);
82     httpResponse.AddHeader(WS_HEADER_VERSION, WS_SUPPORTED_VERSIONS);
83     char *responseBuffer;
84     int responseLength = httpResponse.Create(responseBuffer);
85     response = std::string(responseBuffer, responseLength);
86
87     return NULL;
88   }
89
90   if (websocket->Handshake(data, length, response))
91     return websocket;
92
93   return NULL;
94 }