The library with which to configure a Web Socket Server on a Mbed. This lib was coded by a day at least one year before when this description is written. It will be updated adopting mbed os 5.

Dependencies:   mbedTLSLibrary

Dependents:   SIMPLE_WSS

Committer:
aktk
Date:
Sat Mar 03 18:47:34 2018 +0000
Revision:
1:73f2f67d1732
Parent:
0:86a479dd1814
Private (1 vs 1) ws-com seems to have been implemented on Dec 08, 2016.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
aktk 0:86a479dd1814 1 #include "WS_SERVER.h"
aktk 0:86a479dd1814 2 #define DEBUG
aktk 0:86a479dd1814 3
aktk 0:86a479dd1814 4 //Serial wspc(USBTX, USBRX);
aktk 0:86a479dd1814 5 namespace WS_SERVER
aktk 0:86a479dd1814 6 {
aktk 0:86a479dd1814 7 void DEBUG_PRINT_LINE(const char* arg_line)
aktk 0:86a479dd1814 8 {
aktk 0:86a479dd1814 9 #ifdef DEBUG
aktk 0:86a479dd1814 10 printf("(WSS) ");
aktk 0:86a479dd1814 11 printf(arg_line);
aktk 0:86a479dd1814 12 printf("\r\n");
aktk 0:86a479dd1814 13 #endif
aktk 0:86a479dd1814 14 }
aktk 0:86a479dd1814 15 template<typename T>
aktk 0:86a479dd1814 16 void DEBUG_PRINT_LINE(const char* arg_line, T arg_t)
aktk 0:86a479dd1814 17 {
aktk 0:86a479dd1814 18 #ifdef DEBUG
aktk 0:86a479dd1814 19 printf("(WSS) ");
aktk 0:86a479dd1814 20 printf(arg_line, arg_t);
aktk 0:86a479dd1814 21 printf("\r\n");
aktk 0:86a479dd1814 22 #endif
aktk 0:86a479dd1814 23 }
aktk 0:86a479dd1814 24 template<typename T1, typename T2>
aktk 0:86a479dd1814 25 void DEBUG_PRINT_LINE(const char* arg_line, T1 arg_t1, T2 arg_t2)
aktk 0:86a479dd1814 26 {
aktk 0:86a479dd1814 27 #ifdef DEBUG
aktk 0:86a479dd1814 28 printf("(WSS) ");
aktk 0:86a479dd1814 29 printf(arg_line, arg_t1, arg_t2);
aktk 0:86a479dd1814 30 printf("\r\n");
aktk 0:86a479dd1814 31 #endif
aktk 0:86a479dd1814 32 }
aktk 1:73f2f67d1732 33 template<typename T1, typename T2, typename T3>
aktk 1:73f2f67d1732 34 void DEBUG_PRINT_LINE(const char* arg_line, T1 arg_t1, T2 arg_t2, T3 arg_t3)
aktk 1:73f2f67d1732 35 {
aktk 1:73f2f67d1732 36 #ifdef DEBUG
aktk 1:73f2f67d1732 37 printf("(WSS) ");
aktk 1:73f2f67d1732 38 printf(arg_line, arg_t1, arg_t2, arg_t3);
aktk 1:73f2f67d1732 39 printf("\r\n");
aktk 1:73f2f67d1732 40 #endif
aktk 1:73f2f67d1732 41 }
aktk 0:86a479dd1814 42 }
aktk 0:86a479dd1814 43 using namespace WS_SERVER;
aktk 0:86a479dd1814 44
aktk 0:86a479dd1814 45 WSS::WSS()
aktk 0:86a479dd1814 46 :m_RxBufferSize(1024)
aktk 0:86a479dd1814 47 ,m_PortNumber(8085)
aktk 0:86a479dd1814 48 {
aktk 0:86a479dd1814 49 m_ListeningFlag = (false);
aktk 1:73f2f67d1732 50 m_RxBuffer = new uint8_t[1024];
aktk 0:86a479dd1814 51 m_restAppDataLen = 0;
aktk 0:86a479dd1814 52
aktk 0:86a479dd1814 53 m_DiscontiuanceFlag = false;
aktk 0:86a479dd1814 54 m_EODFlag = false;
aktk 0:86a479dd1814 55 }
aktk 0:86a479dd1814 56
aktk 0:86a479dd1814 57 WSS::WSS(uint32_t arg_RxBufferSize, uint32_t arg_PortNumber)
aktk 0:86a479dd1814 58 :m_RxBufferSize(arg_RxBufferSize)
aktk 0:86a479dd1814 59 ,m_PortNumber(arg_PortNumber)
aktk 0:86a479dd1814 60 {
aktk 0:86a479dd1814 61 m_ListeningFlag = (false);
aktk 1:73f2f67d1732 62 m_RxBuffer = new uint8_t[arg_RxBufferSize];
aktk 0:86a479dd1814 63 m_restAppDataLen = 0;
aktk 0:86a479dd1814 64
aktk 0:86a479dd1814 65 m_DiscontiuanceFlag = false;
aktk 0:86a479dd1814 66 m_EODFlag = false;
aktk 0:86a479dd1814 67 }
aktk 0:86a479dd1814 68
aktk 0:86a479dd1814 69 WSS::~WSS()
aktk 0:86a479dd1814 70 {
aktk 0:86a479dd1814 71 delete(m_RxBuffer);
aktk 0:86a479dd1814 72 }
aktk 0:86a479dd1814 73
aktk 0:86a479dd1814 74 bool WSS::init()
aktk 0:86a479dd1814 75 {
aktk 0:86a479dd1814 76 DEBUG_PRINT_LINE("DEBUG MODE");
aktk 0:86a479dd1814 77
aktk 0:86a479dd1814 78 // Ethernet Initialization
aktk 0:86a479dd1814 79 if(m_eth.init()) {
aktk 0:86a479dd1814 80 printf("(WSS) Error!@EthernetInterface::init()\r\n");
aktk 0:86a479dd1814 81 return false;
aktk 0:86a479dd1814 82 }
aktk 0:86a479dd1814 83 // Ethernet Connecting setup
aktk 0:86a479dd1814 84 if(m_eth.connect()) {
aktk 0:86a479dd1814 85 printf("(WSS) Error!@EthernetInterface::connect()\r\n");
aktk 0:86a479dd1814 86 return false;
aktk 0:86a479dd1814 87 } else {
aktk 0:86a479dd1814 88 printf("(WSS) IP Address is %s\r\n", m_eth.getIPAddress());
aktk 0:86a479dd1814 89 }
aktk 0:86a479dd1814 90
aktk 0:86a479dd1814 91
aktk 0:86a479dd1814 92 // TCP Socket setup
aktk 0:86a479dd1814 93 // To open Server-side PORT
aktk 0:86a479dd1814 94 if(m_tcpsvr.bind(m_PortNumber)< 0) {
aktk 0:86a479dd1814 95 printf("(WSS) Error!@TCPSocketServer::bind()\r\n");
aktk 0:86a479dd1814 96 return false;
aktk 0:86a479dd1814 97 } else {
aktk 0:86a479dd1814 98 printf("(WSS) TCP Server has bounden!\r\n");
aktk 0:86a479dd1814 99 }
aktk 0:86a479dd1814 100 // Server start listening Request from a web browser.
aktk 0:86a479dd1814 101 if(m_tcpsvr.listen(1) < 0) {
aktk 0:86a479dd1814 102 printf("(WSS) TCP server listen failed.\r\n");
aktk 0:86a479dd1814 103 return false;
aktk 0:86a479dd1814 104 } else {
aktk 0:86a479dd1814 105 m_ListeningFlag = true;
aktk 0:86a479dd1814 106 printf("(WSS) TCP server is listening...\r\n");
aktk 0:86a479dd1814 107 }
aktk 0:86a479dd1814 108
aktk 0:86a479dd1814 109 return true;
aktk 0:86a479dd1814 110 }
aktk 0:86a479dd1814 111
aktk 0:86a479dd1814 112 bool WSS::isListening()
aktk 0:86a479dd1814 113 {
aktk 0:86a479dd1814 114 return m_ListeningFlag;
aktk 0:86a479dd1814 115 }
aktk 0:86a479dd1814 116
aktk 0:86a479dd1814 117 void WSS::run()
aktk 0:86a479dd1814 118 {
aktk 0:86a479dd1814 119 DigitalOut led3(LED3);
aktk 0:86a479dd1814 120 DigitalOut led4(LED4);
aktk 0:86a479dd1814 121
aktk 0:86a479dd1814 122 while (m_ListeningFlag) {
aktk 0:86a479dd1814 123 led3 = true;
aktk 0:86a479dd1814 124 // blocking mode (never timeout)
aktk 0:86a479dd1814 125 // waiting client connection
aktk 0:86a479dd1814 126 printf("(WSS) Waiting Connection\r\n");
aktk 0:86a479dd1814 127 if(m_tcpsvr.accept(m_tcpcon) < 0) {
aktk 0:86a479dd1814 128 printf("(WSS) Failed to accept connection.\r\n");
aktk 0:86a479dd1814 129 } else {
aktk 0:86a479dd1814 130 printf("(WSS) Connection Success!\r\n");
aktk 0:86a479dd1814 131 printf("(WSS) IP: %s\r\n",m_tcpcon.get_address());
aktk 0:86a479dd1814 132
aktk 0:86a479dd1814 133 led4 = true;
aktk 0:86a479dd1814 134 }
aktk 0:86a479dd1814 135 // When conected
aktk 0:86a479dd1814 136 // Main WSS Communication----------------------------------
aktk 0:86a479dd1814 137 while(m_tcpcon.is_connected()) {
aktk 0:86a479dd1814 138 DEBUG_PRINT_LINE("(WSS) Connected");
aktk 1:73f2f67d1732 139 if(handshake())
aktk 1:73f2f67d1732 140 while(!m_DiscontiuanceFlag)rxMessage();
aktk 0:86a479dd1814 141 DEBUG_PRINT_LINE("(WSS) Closing");
aktk 0:86a479dd1814 142 // txClosing(1002, "RecievedNot Masked Data");
aktk 0:86a479dd1814 143 }
aktk 0:86a479dd1814 144 // ^^^^^^^^^^^^^^^^^^^^^^----------------------------------
aktk 0:86a479dd1814 145 printf("(WSS) Close connection.\r\ntcp server is listening...\r\n");
aktk 0:86a479dd1814 146 m_tcpcon.close();
aktk 0:86a479dd1814 147 led4 = false;
aktk 0:86a479dd1814 148
aktk 0:86a479dd1814 149 // When any critical errors are occured.
aktk 0:86a479dd1814 150 //if(/*anyerror*/) m_ListeningFlag = false;
aktk 0:86a479dd1814 151 }
aktk 0:86a479dd1814 152 m_tcpsvr.close();
aktk 0:86a479dd1814 153 led3 = false;
aktk 0:86a479dd1814 154 while(1);
aktk 0:86a479dd1814 155 }
aktk 0:86a479dd1814 156
aktk 0:86a479dd1814 157 bool WSS::isReadable()
aktk 0:86a479dd1814 158 {
aktk 0:86a479dd1814 159 if(m_restAppDataLen > 0)
aktk 0:86a479dd1814 160 return true;
aktk 0:86a479dd1814 161 else
aktk 0:86a479dd1814 162 return false;
aktk 0:86a479dd1814 163 }
aktk 0:86a479dd1814 164
aktk 0:86a479dd1814 165 int8_t WSS::getRxData()
aktk 0:86a479dd1814 166 {
aktk 0:86a479dd1814 167 if(m_restAppDataLen > 0) {
aktk 0:86a479dd1814 168 int l_index = m_ApplicationLen - m_restAppDataLen;
aktk 0:86a479dd1814 169 m_restAppDataLen--;
aktk 0:86a479dd1814 170 return m_PayloadData[l_index] ^ m_Masking_key[l_index % 4];
aktk 0:86a479dd1814 171 } else
aktk 0:86a479dd1814 172 return 0x00;
aktk 0:86a479dd1814 173 }
aktk 0:86a479dd1814 174
aktk 0:86a479dd1814 175 void WSS::discardRxBuffer()
aktk 0:86a479dd1814 176 {
aktk 0:86a479dd1814 177 m_RxBuffer = NULL;
aktk 0:86a479dd1814 178 m_restAppDataLen = 0;
aktk 0:86a479dd1814 179 }
aktk 0:86a479dd1814 180
aktk 0:86a479dd1814 181 void WSS::txPing()
aktk 0:86a479dd1814 182 {
aktk 0:86a479dd1814 183 DEBUG_PRINT_LINE("Ping Pong Debug");
aktk 0:86a479dd1814 184 }
aktk 0:86a479dd1814 185 int8_t WSS::rxMessage()
aktk 0:86a479dd1814 186 {
aktk 0:86a479dd1814 187 int64_t l_RxDataLen = 0;
aktk 0:86a479dd1814 188 int64_t l_MesuredDataLen = 0;
aktk 0:86a479dd1814 189
aktk 0:86a479dd1814 190 if(isReadable()) return -1;
aktk 0:86a479dd1814 191 //
aktk 0:86a479dd1814 192 // A (part of) data is recieved here.
aktk 0:86a479dd1814 193 //
aktk 0:86a479dd1814 194 m_DiscontiuanceFlag = false;
aktk 0:86a479dd1814 195 switch(l_RxDataLen = m_tcpcon.receive((char*)m_RxBuffer, m_RxBufferSize)) {
aktk 0:86a479dd1814 196 case 0:
aktk 0:86a479dd1814 197 DEBUG_PRINT_LINE("Recieved buffer is empty.");
aktk 0:86a479dd1814 198 m_DiscontiuanceFlag = true;
aktk 0:86a479dd1814 199 break;
aktk 0:86a479dd1814 200 case -1:
aktk 0:86a479dd1814 201 DEBUG_PRINT_LINE("Failed to read data from client.");
aktk 0:86a479dd1814 202 m_DiscontiuanceFlag = true;
aktk 0:86a479dd1814 203 break;
aktk 0:86a479dd1814 204 default:
aktk 0:86a479dd1814 205 DEBUG_PRINT_LINE("Massege Has Received");
aktk 0:86a479dd1814 206 break;
aktk 0:86a479dd1814 207 }
aktk 0:86a479dd1814 208 DEBUG_PRINT_LINE("Data size: %d Bytes", strlen((char*) m_RxBuffer));
aktk 0:86a479dd1814 209 for(int i = 0; i < strlen((char*) m_RxBuffer); i++)
aktk 1:73f2f67d1732 210 DEBUG_PRINT_LINE("Data%5d: %2x (%3d)", i, m_RxBuffer[i], m_RxBuffer[i]);
aktk 0:86a479dd1814 211 //
aktk 0:86a479dd1814 212 // Data Parsing
aktk 0:86a479dd1814 213 //
aktk 0:86a479dd1814 214 l_MesuredDataLen++;
aktk 0:86a479dd1814 215 m_FIN_RSV = m_RxBuffer[0] >> 4;
aktk 0:86a479dd1814 216 //If FIN is 1, the data is the last of a sequence.
aktk 0:86a479dd1814 217 if(m_FIN_RSV >> 3)
aktk 0:86a479dd1814 218 m_EODFlag = true;
aktk 0:86a479dd1814 219 //IF RSV1, 2, or 3 is 1, communication should be discontinued, because there is no negotiation.
aktk 0:86a479dd1814 220 if(m_FIN_RSV & 0x07)
aktk 0:86a479dd1814 221 m_DiscontiuanceFlag = true;
aktk 0:86a479dd1814 222 m_Opcode = m_RxBuffer[0] & 0x0F;
aktk 0:86a479dd1814 223 switch((OpCode)m_Opcode) {
aktk 0:86a479dd1814 224 case cont:
aktk 0:86a479dd1814 225 case txt:
aktk 0:86a479dd1814 226 case bin:
aktk 0:86a479dd1814 227 case close:
aktk 0:86a479dd1814 228 case ping:
aktk 0:86a479dd1814 229 case pong: {
aktk 0:86a479dd1814 230 m_FrameOpcode = (OpCode)m_Opcode;
aktk 0:86a479dd1814 231 break;
aktk 0:86a479dd1814 232 }
aktk 0:86a479dd1814 233 default: {
aktk 0:86a479dd1814 234 m_DiscontiuanceFlag = true;
aktk 0:86a479dd1814 235 break;
aktk 0:86a479dd1814 236 }
aktk 0:86a479dd1814 237 }
aktk 0:86a479dd1814 238 DEBUG_PRINT_LINE("Data parsing ... 1/3");
aktk 0:86a479dd1814 239 DEBUG_PRINT_LINE("FIN RSV: %x", m_FIN_RSV);
aktk 0:86a479dd1814 240 DEBUG_PRINT_LINE("Opcode : %x", m_Opcode);
aktk 0:86a479dd1814 241 l_MesuredDataLen++;
aktk 0:86a479dd1814 242 // サーバは、マスクされていないフレームを受信した際には,接続を close しなければならない。
aktk 0:86a479dd1814 243 // この場合,サーバは、 7.4.1 節 の定義に従って,ステータスコード 1002 (プロトコル­エラー)を伴う Close フレームを送信してもよい。
aktk 0:86a479dd1814 244 m_Mask = m_RxBuffer[1] >> 7;
aktk 0:86a479dd1814 245 if(m_Mask == 0) {
aktk 0:86a479dd1814 246 m_DiscontiuanceFlag = true;
aktk 0:86a479dd1814 247 }
aktk 1:73f2f67d1732 248 DEBUG_PRINT_LINE("Mask : %x", m_Opcode);
aktk 1:73f2f67d1732 249 m_PayloadLen = (uint64_t)(m_RxBuffer[1] & 0x7f);
aktk 0:86a479dd1814 250 if(m_PayloadLen < 0x07e) {
aktk 0:86a479dd1814 251 l_MesuredDataLen += m_PayloadLen;
aktk 0:86a479dd1814 252 // Buffer [2] [3] [4] [5] have Masking_Key
aktk 0:86a479dd1814 253 l_MesuredDataLen += 4;
aktk 0:86a479dd1814 254 if(m_Mask) for(int i = 0; i < 4; i++) m_Masking_key[i] = (m_RxBuffer[2 + i]);
aktk 0:86a479dd1814 255 // The Head of Payload data is at buffer[6]
aktk 0:86a479dd1814 256 m_PayloadData = m_RxBuffer + 6;
aktk 1:73f2f67d1732 257 DEBUG_PRINT_LINE("PL Len : %x", (uint32_t)m_PayloadLen);
aktk 0:86a479dd1814 258 } else if (m_PayloadLen == 0x07e) {
aktk 0:86a479dd1814 259 l_MesuredDataLen += m_PayloadLen;
aktk 0:86a479dd1814 260 // Two succeeded bytes buffer [2] and [3] have SubPayload
aktk 0:86a479dd1814 261 l_MesuredDataLen += 2;
aktk 0:86a479dd1814 262 m_PayloadLen = (uint64_t)((m_RxBuffer[2] << 8)|(m_RxBuffer[3]&0xff));
aktk 0:86a479dd1814 263 // Buffer [4] [5] [6] [7] have Masking_Key
aktk 0:86a479dd1814 264 l_MesuredDataLen += 4;
aktk 0:86a479dd1814 265 if(m_Mask) for(int i = 0; i < 4; i++) m_Masking_key[i] = (m_RxBuffer[4 + i]);
aktk 0:86a479dd1814 266 // The Head of Payload data is at buffer[8]
aktk 0:86a479dd1814 267 m_PayloadData = m_RxBuffer + 8;
aktk 1:73f2f67d1732 268 DEBUG_PRINT_LINE("PL Len : %x", (uint32_t)m_PayloadLen);
aktk 0:86a479dd1814 269 } else if (m_PayloadLen == 0x07f) {
aktk 0:86a479dd1814 270 l_MesuredDataLen += m_PayloadLen;
aktk 0:86a479dd1814 271 // Eight succeeded bytes buffer [2], [3], [4], [5], [6], [7], [8], and [9] have SubPayload
aktk 0:86a479dd1814 272 l_MesuredDataLen += 8;
aktk 0:86a479dd1814 273 m_PayloadLen = (uint64_t)(m_RxBuffer[2] & 0xff);
aktk 0:86a479dd1814 274 for(int i = 0; i < 7; i++)
aktk 0:86a479dd1814 275 m_PayloadLen = (uint64_t)((m_PayloadLen << 8) | (m_RxBuffer[3 + i] & 0xff));
aktk 0:86a479dd1814 276 l_MesuredDataLen += 4;
aktk 0:86a479dd1814 277 // Buffer [10] [11] [12] [13] have Masking_Key
aktk 0:86a479dd1814 278 if(m_Mask) for(int i = 0; i < 4; i++) m_Masking_key[i] = (m_RxBuffer[10 + i]);
aktk 0:86a479dd1814 279 // The Head of Payload data is at buffer[14]
aktk 0:86a479dd1814 280 m_PayloadData = m_RxBuffer + 14;
aktk 1:73f2f67d1732 281 DEBUG_PRINT_LINE("PL Len : %x%x", (uint32_t)(m_PayloadLen>>32),(uint32_t)(m_PayloadLen&0xffffffff));
aktk 0:86a479dd1814 282 }
aktk 0:86a479dd1814 283 DEBUG_PRINT_LINE("Data parsing ... 2/3");
aktk 1:73f2f67d1732 284
aktk 0:86a479dd1814 285 // Because there is no negotiation of Extention, Extention data is regarded as none.
aktk 0:86a479dd1814 286 m_ExtensionLen = 0;
aktk 0:86a479dd1814 287 m_ApplicationLen = m_PayloadLen - m_ExtensionLen;
aktk 0:86a479dd1814 288 m_restAppDataLen = m_ApplicationLen;
aktk 0:86a479dd1814 289 DEBUG_PRINT_LINE("Data parsing ... 3/3");
aktk 1:73f2f67d1732 290 DEBUG_PRINT_LINE("Application Data Len: %08x%08x Byte", (uint32_t)(m_ApplicationLen>>32), (uint32_t)(m_ApplicationLen &0xffffffff));
aktk 1:73f2f67d1732 291
aktk 0:86a479dd1814 292 if(l_MesuredDataLen != l_RxDataLen) {
aktk 0:86a479dd1814 293 m_DiscontiuanceFlag = true;
aktk 0:86a479dd1814 294 }
aktk 0:86a479dd1814 295
aktk 0:86a479dd1814 296 return m_DiscontiuanceFlag ? 1 : 0;
aktk 0:86a479dd1814 297 }
aktk 0:86a479dd1814 298
aktk 0:86a479dd1814 299 bool WSS::handshake()
aktk 0:86a479dd1814 300 {
aktk 0:86a479dd1814 301 char* httpmethod = NULL;
aktk 0:86a479dd1814 302 char* filepath = NULL;
aktk 0:86a479dd1814 303 char* http_ver = NULL;
aktk 0:86a479dd1814 304 char* header_field_name = NULL;
aktk 0:86a479dd1814 305 char* header_field_val = NULL;
aktk 0:86a479dd1814 306
aktk 0:86a479dd1814 307 //
aktk 0:86a479dd1814 308 // Handshake HTTP Request Analysis
aktk 0:86a479dd1814 309 //
aktk 0:86a479dd1814 310 switch(m_tcpcon.receive((char*)m_RxBuffer, 1023)) {
aktk 0:86a479dd1814 311 case 0:
aktk 0:86a479dd1814 312 DEBUG_PRINT_LINE("Recieved buffer is empty.");
aktk 0:86a479dd1814 313 m_msger.setStatusLine(400, "No Request");
aktk 0:86a479dd1814 314 httpmethod = NULL;
aktk 0:86a479dd1814 315 filepath = NULL;
aktk 0:86a479dd1814 316 http_ver = NULL;
aktk 0:86a479dd1814 317 break;
aktk 0:86a479dd1814 318 case -1:
aktk 0:86a479dd1814 319 DEBUG_PRINT_LINE("Failed to read data from client.");
aktk 0:86a479dd1814 320 m_msger.setStatusLine(500, "Internal Server Error");
aktk 0:86a479dd1814 321 httpmethod = NULL;
aktk 0:86a479dd1814 322 filepath = NULL;
aktk 0:86a479dd1814 323 http_ver = NULL;
aktk 0:86a479dd1814 324 break;
aktk 0:86a479dd1814 325 default:
aktk 0:86a479dd1814 326 DEBUG_PRINT_LINE("Recieved Data: %d\r\n-->",strlen((char*)m_RxBuffer));
aktk 0:86a479dd1814 327 DEBUG_PRINT_LINE("%.*s[End of Request]", strlen((char*)m_RxBuffer),(char*)m_RxBuffer);
aktk 0:86a479dd1814 328 // get HTTP method, File path, HTTP version
aktk 0:86a479dd1814 329 httpmethod = strtok((char*)m_RxBuffer," ");
aktk 0:86a479dd1814 330 filepath = strtok(NULL, " ");
aktk 0:86a479dd1814 331 http_ver = strtok(NULL, "\r\n");
aktk 0:86a479dd1814 332 DEBUG_PRINT_LINE("httpmethod: %s", httpmethod);
aktk 0:86a479dd1814 333 DEBUG_PRINT_LINE("file path: %s", filepath);
aktk 0:86a479dd1814 334 DEBUG_PRINT_LINE("http ver : %s", http_ver);
aktk 0:86a479dd1814 335 break;
aktk 0:86a479dd1814 336 }
aktk 0:86a479dd1814 337
aktk 0:86a479dd1814 338 //
aktk 0:86a479dd1814 339 // Handshake Response Form
aktk 0:86a479dd1814 340 //
aktk 0:86a479dd1814 341 if (strcmp(httpmethod,"GET") == 0 ) {
aktk 0:86a479dd1814 342 DEBUG_PRINT_LINE("GET request incomming.");
aktk 0:86a479dd1814 343 // Define behaviour of server according to Request Header lines
aktk 0:86a479dd1814 344 // Apply request header field to response header field
aktk 0:86a479dd1814 345 char* field_Connection = NULL;
aktk 0:86a479dd1814 346 char* field_Upgrade = NULL;
aktk 0:86a479dd1814 347 char* field_Sec_WebSocket_Key = NULL;
aktk 0:86a479dd1814 348 char* field_Sec_WebSocket_Version = NULL;
aktk 0:86a479dd1814 349 char* field_Origin = NULL;
aktk 0:86a479dd1814 350 do {
aktk 0:86a479dd1814 351 //Analyze the header feilds
aktk 0:86a479dd1814 352 header_field_name = strtok(NULL, ":");
aktk 0:86a479dd1814 353 header_field_name++;
aktk 0:86a479dd1814 354 header_field_val = strtok(NULL, "\r\n");
aktk 0:86a479dd1814 355 header_field_val++;
aktk 0:86a479dd1814 356
aktk 0:86a479dd1814 357 if(header_field_name - 1 != NULL) {
aktk 0:86a479dd1814 358 if(!strcmp(header_field_name, "Connection")) {
aktk 0:86a479dd1814 359 field_Connection = header_field_val;
aktk 0:86a479dd1814 360 } else if(!strcmp(header_field_name, "Upgrade")) {
aktk 0:86a479dd1814 361 field_Upgrade = header_field_val;
aktk 0:86a479dd1814 362 } else if(!strcmp(header_field_name, "Sec-WebSocket-Key") ) {
aktk 0:86a479dd1814 363 field_Sec_WebSocket_Key = header_field_val;
aktk 0:86a479dd1814 364 } else if(!strcmp(header_field_name, "Sec-WebSocket-Version") ) {
aktk 0:86a479dd1814 365 field_Sec_WebSocket_Version = header_field_val;
aktk 0:86a479dd1814 366 } else if(!strcmp(header_field_name, "Origin") ) {
aktk 0:86a479dd1814 367 field_Origin = header_field_val;
aktk 0:86a479dd1814 368 }
aktk 0:86a479dd1814 369 DEBUG_PRINT_LINE("*header_field_name adr: %d %s", header_field_name - 1, header_field_name);
aktk 0:86a479dd1814 370 DEBUG_PRINT_LINE(" header_field_val adr: %d %s", header_field_val - 1, header_field_val);
aktk 0:86a479dd1814 371 } else {
aktk 0:86a479dd1814 372 break;
aktk 0:86a479dd1814 373 }
aktk 0:86a479dd1814 374 } while(1);
aktk 0:86a479dd1814 375
aktk 0:86a479dd1814 376 DEBUG_PRINT_LINE("Parsing has been done");
aktk 0:86a479dd1814 377 // if the request is to switching to the WebSocket Server
aktk 0:86a479dd1814 378 if(!strcmp((char*)field_Connection, "Upgrade")) {
aktk 0:86a479dd1814 379 if( !strcmp(field_Upgrade, "websocket") &&
aktk 0:86a479dd1814 380 field_Sec_WebSocket_Key != NULL &&
aktk 0:86a479dd1814 381 !strcmp(field_Sec_WebSocket_Version, "13") &&
aktk 0:86a479dd1814 382 field_Origin != NULL) {
aktk 0:86a479dd1814 383 DEBUG_PRINT_LINE("Prepering for Update");
aktk 0:86a479dd1814 384 //
aktk 0:86a479dd1814 385 // Calcurate the key
aktk 0:86a479dd1814 386 //
aktk 0:86a479dd1814 387 // concat the input key and the str.
aktk 0:86a479dd1814 388 unsigned char SecWebSocketAccept[256];
aktk 0:86a479dd1814 389 sprintf((char*)SecWebSocketAccept, "%s%s", field_Sec_WebSocket_Key, "258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
aktk 0:86a479dd1814 390 DEBUG_PRINT_LINE("Appended Key: %s", (char*)SecWebSocketAccept);
aktk 0:86a479dd1814 391 // evaluate SHA1
aktk 0:86a479dd1814 392 unsigned char sha1Output[20];
aktk 0:86a479dd1814 393 sha1(SecWebSocketAccept, strlen((char*)SecWebSocketAccept), sha1Output);
aktk 0:86a479dd1814 394 DEBUG_PRINT_LINE("SHA1 hashed Key:");
aktk 0:86a479dd1814 395 for(int i = 0; i < 20; i++) DEBUG_PRINT_LINE("%x", sha1Output[i]);
aktk 0:86a479dd1814 396 // encode the hash into base 64
aktk 0:86a479dd1814 397 {
aktk 0:86a479dd1814 398 size_t sizeofbuffer = strlen((char*)SecWebSocketAccept);
aktk 0:86a479dd1814 399 if(base64_encode(SecWebSocketAccept, &sizeofbuffer, sha1Output, 20) != 0)DEBUG_PRINT_LINE("something wrong@base64_encode");
aktk 0:86a479dd1814 400 DEBUG_PRINT_LINE((char*)SecWebSocketAccept);
aktk 0:86a479dd1814 401 }
aktk 0:86a479dd1814 402 // --- end of culculation of the key ---
aktk 0:86a479dd1814 403 //
aktk 0:86a479dd1814 404 // Format HTTP response of ACK
aktk 0:86a479dd1814 405 //
aktk 0:86a479dd1814 406 DEBUG_PRINT_LINE("Communication Protocol will be Upgraded to Websocket!");
aktk 0:86a479dd1814 407 m_msger.resetHeader();
aktk 0:86a479dd1814 408 m_msger.setStatusLine(101, "Switching Protocols");
aktk 0:86a479dd1814 409 if(m_msger.setHeaderField("Connection", "Upgrade")) DEBUG_PRINT_LINE("buffer over flow@ResposeMessenger");
aktk 0:86a479dd1814 410 if(m_msger.setHeaderField("Upgrade", "websocket")) DEBUG_PRINT_LINE("buffer over flow@ResposeMessenger");
aktk 0:86a479dd1814 411 if(m_msger.setHeaderField("Sec-WebSocket-Accept", (char*)SecWebSocketAccept)) DEBUG_PRINT_LINE("buffer over flow@ResposeMessenger");
aktk 0:86a479dd1814 412 if(m_msger.setHeaderField("Access-Control-Allow-Origin", m_tcpcon.get_address())) DEBUG_PRINT_LINE("buffer over flow@ResposeMessenger");
aktk 0:86a479dd1814 413 // --- end of formatting ---
aktk 0:86a479dd1814 414 } else {
aktk 0:86a479dd1814 415 //
aktk 0:86a479dd1814 416 // Format HTTP Response of NACK
aktk 0:86a479dd1814 417 //
aktk 0:86a479dd1814 418 DEBUG_PRINT_LINE("Communication Protocol won't be Upgraded.");
aktk 0:86a479dd1814 419 m_msger.setStatusLine(426, "Upgrade Required");
aktk 0:86a479dd1814 420 if(m_msger.setHeaderField("Connection", "Close"))DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
aktk 0:86a479dd1814 421 // --- end of formatting ---
aktk 0:86a479dd1814 422 }
aktk 0:86a479dd1814 423 }
aktk 0:86a479dd1814 424 // send valid response
aktk 0:86a479dd1814 425 m_msger.sendHTTPResponse(m_tcpcon);
aktk 0:86a479dd1814 426 m_msger.resetHeader();
aktk 0:86a479dd1814 427 DEBUG_PRINT_LINE("echo back done.");
aktk 0:86a479dd1814 428 }
aktk 0:86a479dd1814 429 if (httpmethod == NULL) {
aktk 0:86a479dd1814 430 // send error response
aktk 0:86a479dd1814 431 m_msger.sendHTTPResponse(m_tcpcon);
aktk 0:86a479dd1814 432 m_msger.resetHeader();
aktk 0:86a479dd1814 433 DEBUG_PRINT_LINE("echo back done.");
aktk 0:86a479dd1814 434 }
aktk 0:86a479dd1814 435 DEBUG_PRINT_LINE("Response to Request has done");
aktk 0:86a479dd1814 436 // ----Handshake Response End----
aktk 0:86a479dd1814 437
aktk 0:86a479dd1814 438 return true;
aktk 0:86a479dd1814 439 }