GainSpan Wi-Fi library see: http://mbed.org/users/gsfan/notebook/gainspan_wifi/
Dependents: GSwifi_httpd GSwifi_websocket GSwifi_tcpclient GSwifi_tcpserver ... more
Fork of GSwifi by
GSwifi_httpd.cpp
00001 /* Copyright (C) 2013 gsfan, MIT License 00002 * 00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00004 * and associated documentation files (the "Software"), to deal in the Software without restriction, 00005 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 00006 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 00007 * furnished to do so, subject to the following conditions: 00008 * 00009 * The above copyright notice and this permission notice shall be included in all copies or 00010 * substantial portions of the Software. 00011 * 00012 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00013 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00014 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00015 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00016 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00017 */ 00018 /** @file 00019 * @brief Gainspan wi-fi module library for mbed 00020 * GS1011MIC, GS1011MIP, GainSpan WiFi Breakout, etc. 00021 */ 00022 00023 #include "GSwifi_conf.h" 00024 #ifdef GS_ENABLE_HTTPD 00025 00026 #include "dbg.h" 00027 #include "mbed.h" 00028 #include "GSwifi.h" 00029 #include "sha1.h" 00030 #include <string.h> 00031 00032 #define MIMETABLE_NUM 9 00033 static const struct { 00034 char ext[5]; 00035 char type[24]; 00036 } mimetable[MIMETABLE_NUM] = { 00037 {"txt", "text/plain"}, // default 00038 {"html", "text/html"}, 00039 {"htm", "text/html"}, 00040 {"css", "text/css"}, 00041 {"js", "application/javascript"}, 00042 {"jpg", "image/jpeg"}, 00043 {"png", "image/png"}, 00044 {"gif", "image/gif"}, 00045 {"ico", "image/x-icon"}, 00046 }; 00047 00048 int GSwifi::httpd (int port) { 00049 int i; 00050 char cmd[GS_CMD_SIZE]; 00051 00052 if (! _connect || _status != GSSTAT_READY) return -1; 00053 00054 memset(&_httpd, 0, sizeof(_httpd)); 00055 for (i = 0; i < 16; i ++) { 00056 _httpd[i].mode = GSHTTPDMODE_REQUEST; 00057 } 00058 _handler_count = 0; 00059 00060 sprintf(cmd, "AT+NSTCP=%d", port); 00061 if (command(cmd, GSRES_CONNECT)) return -1; 00062 00063 newSock(_cid, GSTYPE_SERVER, GSPROT_HTTPD, this, &GSwifi::poll_httpd); 00064 return _cid; 00065 } 00066 00067 void GSwifi::poll_httpd (int cid, int len) { 00068 int i, j, flg = 0; 00069 char c; 00070 00071 if (len == 0) { 00072 // start request 00073 _httpd[cid].mode = GSHTTPDMODE_REQUEST; 00074 _httpd[cid].len = 0; 00075 _httpd[cid].keepalive = 0; 00076 #ifdef GS_ENABLE_WEBSOCKET 00077 _httpd[cid].websocket = 0; 00078 #endif 00079 return; 00080 } 00081 00082 #ifdef GS_ENABLE_WEBSOCKET 00083 if (_httpd[cid].mode >= GSHTTPDMODE_WEBSOCKET) { 00084 poll_websocket(cid, len); 00085 return; 00086 } 00087 #endif 00088 00089 while (_gs_sock[cid].connect && (! _gs_sock[cid].data->isEmpty())) { 00090 flg = 0; 00091 if (_httpd[cid].buf == NULL) { 00092 _httpd[cid].buf = (char*)malloc(HTTPD_BUF_SIZE); 00093 } 00094 // get 1 line 00095 for (j = 0; j < len; j ++) { 00096 _gs_sock[cid].data->dequeue(&c); 00097 if (c == '\r') continue; 00098 if (c == '\n' && _httpd[cid].mode != GSHTTPDMODE_BODY) break; 00099 00100 if (_httpd[cid].len < HTTPD_BUF_SIZE - 1) { 00101 _httpd[cid].buf[_httpd[cid].len] = c; 00102 } 00103 _httpd[cid].len ++; 00104 if (_httpd[cid].mode == GSHTTPDMODE_BODY && _httpd[cid].len >= _httpd[cid].length) break; // end of body 00105 } 00106 if (j >= len) return; // continue 00107 if (_httpd[cid].len < HTTPD_BUF_SIZE) { 00108 _httpd[cid].buf[_httpd[cid].len] = 0; 00109 DBG("httpd %d: %d %s (%d)\r\n", cid, _httpd[cid].mode, _httpd[cid].buf, _httpd[cid].len); 00110 } 00111 00112 // parse 00113 switch (_httpd[cid].mode) { 00114 case GSHTTPDMODE_REQUEST: 00115 if (strnicmp(_httpd[cid].buf, "GET ", 4) == 0) { 00116 _httpd[cid].type = GSPROT_HTTPGET; 00117 j = 4; 00118 } else 00119 if (strnicmp(_httpd[cid].buf, "POST ", 5) == 0) { 00120 _httpd[cid].type = GSPROT_HTTPPOST; 00121 j = 5; 00122 } else { 00123 _httpd[cid].mode = GSHTTPDMODE_ERROR; 00124 break; 00125 } 00126 00127 // get uri 00128 for (i = j; i < _httpd[cid].len; i ++) { 00129 if (_httpd[cid].buf[i] == ' ') break; 00130 } 00131 i = i - j; 00132 if (i) { 00133 if (_httpd[cid].uri == NULL) { 00134 _httpd[cid].uri = (char*)malloc(HTTPD_URI_SIZE); 00135 } 00136 strncpy(_httpd[cid].uri, &_httpd[cid].buf[j], i); 00137 _httpd[cid].uri[i] = 0; 00138 } 00139 _httpd[cid].mode = GSHTTPDMODE_HEAD; 00140 _httpd[cid].length = 0; 00141 DBG("uri: %s\r\n", _httpd[cid].uri); 00142 break; 00143 00144 case GSHTTPDMODE_HEAD: 00145 if (_httpd[cid].len == 0) { 00146 // blank line (end of header) 00147 _httpd[cid].mode = GSHTTPDMODE_BODY; 00148 if (_httpd[cid].length == 0) flg = 1; // no body 00149 #ifdef GS_ENABLE_WEBSOCKET 00150 if (_httpd[cid].websocket && _httpd[cid].websocket_key) { 00151 // enter websocket 00152 _httpd[cid].mode = GSHTTPDMODE_WEBSOCKET; 00153 _httpd[cid].len = 0; 00154 flg = 1; 00155 } 00156 #endif 00157 } else 00158 if (strnicmp(_httpd[cid].buf, "Content-Length: ", 16) == 0) { 00159 _httpd[cid].length = atoi(&_httpd[cid].buf[16]); 00160 } else 00161 if (strnicmp(_httpd[cid].buf, "Connection: Keep-Alive", 22) == 0) { 00162 if (! _httpd[cid].keepalive) { 00163 _httpd[cid].keepalive = HTTPD_KEEPALIVE; 00164 } 00165 #ifdef GS_ENABLE_WEBSOCKET 00166 } else 00167 if (strnicmp(_httpd[cid].buf, "Upgrade: websocket", 18) == 0) { 00168 if (! _httpd[cid].websocket) _httpd[cid].websocket = 1; 00169 } else 00170 if (strnicmp(_httpd[cid].buf, "Sec-WebSocket-Version: ", 23) == 0) { 00171 _httpd[cid].websocket = atoi(&_httpd[cid].buf[23]); 00172 } else 00173 if (strnicmp(_httpd[cid].buf, "Sec-WebSocket-Key: ", 19) == 0) { 00174 if (_httpd[cid].websocket_key == NULL) { 00175 _httpd[cid].websocket_key = (char*)malloc(30); 00176 } 00177 strncpy(_httpd[cid].websocket_key, &_httpd[cid].buf[19], 30); 00178 #endif 00179 } 00180 break; 00181 00182 case GSHTTPDMODE_BODY: 00183 if (_httpd[cid].len >= _httpd[cid].length) { 00184 DBG("body: %s\r\n", _httpd[cid].buf); 00185 flg = 1; 00186 } 00187 break; 00188 00189 } 00190 00191 #ifdef GS_ENABLE_WEBSOCKET 00192 if (flg && _httpd[cid].mode == GSHTTPDMODE_WEBSOCKET) { 00193 // websocket 00194 i = get_handler(_httpd[cid].uri); 00195 if (i >= 0 && _handler[i].onHttpCgi) { 00196 _httpd[cid].host = _gs_sock[cid].host; 00197 _httpd[cid].file = NULL; 00198 _httpd[cid].query = NULL; 00199 00200 send_websocket_accept(cid); 00201 } else { 00202 // not found 00203 send_httpd_error(cid, 403); 00204 } 00205 break; // exit while 00206 00207 } else 00208 #endif 00209 if (flg) { 00210 // http request 00211 _httpd[cid].buf[_httpd[cid].len] = 0; 00212 00213 i = get_handler(_httpd[cid].uri); 00214 if (i >= 0) { 00215 _httpd[cid].host = _gs_sock[cid].host; 00216 j = strlen(_handler[i].uri); 00217 _httpd[cid].file = &_httpd[cid].uri[j]; 00218 _httpd[cid].query = NULL; 00219 for (; j < strlen(_httpd[cid].uri); j ++) { 00220 if (_httpd[cid].uri[j] == '?') { 00221 // query string 00222 _httpd[cid].uri[j] = 0; 00223 _httpd[cid].query = &_httpd[cid].uri[j + 1]; 00224 break; 00225 } 00226 } 00227 00228 if (_handler[i].dir) { 00229 // file 00230 httpd_request(cid, &_httpd[cid], _handler[i].dir); 00231 flg = 1; 00232 } else 00233 if (_handler[i].onHttpCgi) { 00234 // cgi 00235 _handler[i].onHttpCgi(cid, &_httpd[cid]); 00236 _httpd[cid].keepalive = 0; 00237 LOG("%d.%d.%d.%d ", _httpd[cid].host.getIp()[0], _httpd[cid].host.getIp()[1], _httpd[cid].host.getIp()[2], _httpd[cid].host.getIp()[3]); 00238 LOG("%s %s %d 200 -\r\n", _httpd[cid].type == GSPROT_HTTPGET ? "GET" : "POST", _httpd[cid].uri, _httpd[cid].length); 00239 flg = 1; 00240 } 00241 } else { 00242 // not found 00243 send_httpd_error(cid, 403); 00244 } 00245 00246 if (_httpd[cid].keepalive) { 00247 _httpd[cid].mode = GSHTTPDMODE_REQUEST; 00248 _httpd[cid].len = 0; 00249 _httpd[cid].length = 0; 00250 _httpd[cid].keepalive --; 00251 } else { 00252 close(cid); 00253 } 00254 } 00255 00256 if (_httpd[cid].mode == GSHTTPDMODE_ERROR) { 00257 send_httpd_error(cid, 400); 00258 } 00259 00260 _httpd[cid].len = 0; 00261 } // while 00262 } 00263 00264 int GSwifi::get_handler (char *uri) { 00265 int i, j; 00266 00267 for (i = 0; i < _handler_count; i ++) { 00268 j = strlen(_handler[i].uri); 00269 if (strncmp(uri, _handler[i].uri, j) == NULL) { 00270 // found 00271 return i; 00272 } 00273 } 00274 return -1; 00275 } 00276 00277 int GSwifi::httpd_request (int cid, GS_httpd *gshttpd, char *dir) { 00278 FILE *fp; 00279 int i, len; 00280 char buf[HTTPD_BUF_SIZE]; 00281 char file[HTTPD_URI_SIZE]; 00282 00283 strcpy(file, dir); 00284 strcat(file, gshttpd->file); 00285 if (file[strlen(file) - 1] == '/') { 00286 strcat(file, "index.html"); 00287 } 00288 DBG("file: %s\r\n", file); 00289 00290 fp = fopen(file, "r"); 00291 if (fp) { 00292 send(cid, "HTTP/1.1 200 OK\r\n", 17); 00293 { 00294 // file size 00295 i = ftell(fp); 00296 fseek(fp, 0, SEEK_END); 00297 len = ftell(fp); 00298 fseek(fp, i, SEEK_SET); 00299 } 00300 sprintf(buf, "Content-Length: %d\r\n", len); 00301 send(cid, buf, strlen(buf)); 00302 sprintf(buf, "Content-Type: %s\r\n", mimetype(file)); 00303 send(cid, buf, strlen(buf)); 00304 if (gshttpd->keepalive) { 00305 strcpy(buf, "Connection: Keep-Alive\r\n"); 00306 } else { 00307 strcpy(buf, "Connection: close\r\n"); 00308 } 00309 send(cid, buf, strlen(buf)); 00310 strcpy(buf, "Server: GSwifi httpd\r\n"); 00311 send(cid, buf, strlen(buf)); 00312 send(cid, "\r\n", 2); 00313 00314 for (;;) { 00315 i = fread(buf, sizeof(char), sizeof(buf), fp); 00316 if (i <= 0) break; 00317 if (! _gs_sock[cid].connect) break; 00318 send(cid, buf, i); 00319 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) 00320 if (feof(fp)) break; 00321 #endif 00322 } 00323 fclose(fp); 00324 LOG("%d.%d.%d.%d ", _httpd[cid].host.getIp()[0], _httpd[cid].host.getIp()[1], _httpd[cid].host.getIp()[2], _httpd[cid].host.getIp()[3]); 00325 LOG("%s %s %d 200 %d\r\n", _httpd[cid].type == GSPROT_HTTPGET ? "GET" : "POST", _httpd[cid].uri, _httpd[cid].length, len); 00326 return 0; 00327 } 00328 00329 send_httpd_error(cid, 404); 00330 return -1; 00331 } 00332 00333 char *GSwifi::mimetype (char *file) { 00334 int i, j; 00335 00336 DBG("<%s>\r\n", file); 00337 for (i = 0; i < MIMETABLE_NUM; i ++) { 00338 j = strlen(mimetable[i].ext); 00339 if (file[strlen(file) - j - 1] == '.' && 00340 strnicmp(&file[strlen(file) - j], mimetable[i].ext, j) == NULL) { 00341 return (char*)mimetable[i].type; 00342 } 00343 } 00344 return (char*)mimetable[0].type; 00345 } 00346 00347 int GSwifi::strnicmp (const char *p1, const char *p2, int n) { 00348 int i, r = -1; 00349 char c1, c2; 00350 00351 for (i = 0; i < n; i ++) { 00352 c1 = (p1[i] >= 'a' && p1[i] <= 'z') ? p1[i] - ('a' - 'A'): p1[i]; 00353 c2 = (p2[i] >= 'a' && p2[i] <= 'z') ? p2[i] - ('a' - 'A'): p2[i]; 00354 r = c1 - c2; 00355 if (r) break; 00356 } 00357 return r; 00358 } 00359 00360 void GSwifi::send_httpd_error (int cid, int err) { 00361 char buf[100], msg[30]; 00362 00363 switch (err) { 00364 case 400: 00365 strcpy(msg, "Bad Request"); 00366 break; 00367 case 403: 00368 strcpy(msg, "Forbidden"); 00369 break; 00370 case 404: 00371 strcpy(msg, "Not Found"); 00372 break; 00373 case 500: 00374 default: 00375 strcpy(msg, "Internal Server Error"); 00376 break; 00377 } 00378 DBG("httpd error: %d %d %s\r\n", cid, err, msg); 00379 00380 sprintf(buf, "HTTP/1.1 %d %s\r\n", err, msg); 00381 send(cid, buf, strlen(buf)); 00382 strcpy(buf, "Content-Type: text/html\r\n"); 00383 send(cid, buf, strlen(buf)); 00384 send(cid, "\r\n", 2); 00385 00386 sprintf(buf, "<html><head><title>%d %s</title></head>\r\n", err, msg); 00387 send(cid, buf, strlen(buf)); 00388 sprintf(buf, "<body><h1>%s</h1></body></html>\r\n", msg); 00389 send(cid, buf, strlen(buf)); 00390 close(cid); 00391 LOG("%d.%d.%d.%d ", _httpd[cid].host.getIp()[0], _httpd[cid].host.getIp()[1], _httpd[cid].host.getIp()[2], _httpd[cid].host.getIp()[3]); 00392 LOG("%s %s %d %d -\r\n", _httpd[cid].type == GSPROT_HTTPGET ? "GET" : "POST", _httpd[cid].uri, _httpd[cid].length, err); 00393 } 00394 00395 int GSwifi::attach_httpd (const char *uri, const char *dir) { 00396 if (_handler_count < HTTPD_HANDLE) { 00397 _handler[_handler_count].uri = (char*)malloc(strlen(uri) + 1); 00398 strcpy(_handler[_handler_count].uri, uri); 00399 _handler[_handler_count].dir = (char*)malloc(strlen(dir) + 1); 00400 strcpy(_handler[_handler_count].dir, dir); 00401 _handler[_handler_count].onHttpCgi = NULL; 00402 _handler_count ++; 00403 return 0; 00404 } else { 00405 return -1; 00406 } 00407 } 00408 00409 int GSwifi::attach_httpd (const char *uri, onHttpdCgiFunc ponHttpCgi) { 00410 if (_handler_count < HTTPD_HANDLE) { 00411 _handler[_handler_count].uri = (char*)malloc(strlen(uri) + 1); 00412 strcpy(_handler[_handler_count].uri, uri); 00413 _handler[_handler_count].dir = NULL; 00414 _handler[_handler_count].onHttpCgi = ponHttpCgi; 00415 _handler_count ++; 00416 return 0; 00417 } else { 00418 return -1; 00419 } 00420 } 00421 00422 #ifdef GS_ENABLE_WEBSOCKET 00423 void GSwifi::poll_websocket (int cid, int len) { 00424 int i, j, flg; 00425 unsigned char c; 00426 00427 while (_gs_sock[cid].connect && (! _gs_sock[cid].data->isEmpty())) { 00428 flg = 0; 00429 // get 1 line 00430 for (j = 0; j < len; j ++) { 00431 _gs_sock[cid].data->dequeue((char*)&c); 00432 // DBG("_%c", c); 00433 00434 switch (_httpd[cid].mode) { 00435 case GSHTTPDMODE_WEBSOCKET: 00436 if (_httpd[cid].len == 0) { 00437 // flag 00438 _httpd[cid].type = c & 0x0f; 00439 _httpd[cid].websocket_flg = c << 8; 00440 _httpd[cid].len ++; 00441 } else 00442 if (_httpd[cid].len == 1) { 00443 // length 7bit 00444 _httpd[cid].websocket_flg |= c; 00445 _httpd[cid].length = c & 0x7f; 00446 _httpd[cid].len ++; 00447 if (_httpd[cid].length < 126) { 00448 _httpd[cid].len = 0; 00449 if (_httpd[cid].websocket_flg & 0x0080) { 00450 _httpd[cid].mode = GSHTTPDMODE_WEBSOCKET_MASK; 00451 } else { 00452 _httpd[cid].mode = GSHTTPDMODE_WEBSOCKET_BODY; 00453 } 00454 DBG("ws length %d\r\n", _httpd[cid].length); 00455 } 00456 } else { 00457 // length 16bit,64bit 00458 if (_httpd[cid].len == 2) { 00459 _httpd[cid].length = c; 00460 _httpd[cid].len ++; 00461 } else 00462 if (_httpd[cid].len < 9 && (_httpd[cid].websocket_flg & 0x7f) == 127) { 00463 // 64bit 00464 _httpd[cid].length = (_httpd[cid].length << 8) | c; 00465 _httpd[cid].len ++; 00466 } else { 00467 // end 00468 _httpd[cid].length = (_httpd[cid].length << 8) | c; 00469 _httpd[cid].len = 0; 00470 if (_httpd[cid].websocket_flg & 0x0080) { 00471 _httpd[cid].mode = GSHTTPDMODE_WEBSOCKET_MASK; 00472 } else { 00473 _httpd[cid].mode = GSHTTPDMODE_WEBSOCKET_BODY; 00474 } 00475 DBG("ws length2 %d\r\n", _httpd[cid].length); 00476 } 00477 } 00478 break; 00479 00480 case GSHTTPDMODE_WEBSOCKET_MASK: 00481 // masking key 00482 _httpd[cid].websocket_mask[_httpd[cid].len] = c; 00483 _httpd[cid].len ++; 00484 if (_httpd[cid].len >= 4) { 00485 _httpd[cid].len = 0; 00486 _httpd[cid].mode = GSHTTPDMODE_WEBSOCKET_BODY; 00487 DBG("ws mask\r\n"); 00488 } 00489 break; 00490 00491 case GSHTTPDMODE_WEBSOCKET_BODY: 00492 // payload 00493 if (_httpd[cid].len < HTTPD_BUF_SIZE - 1) { 00494 if (_httpd[cid].websocket_flg & 0x0080) { 00495 // un-mask 00496 _httpd[cid].buf[_httpd[cid].len] = c ^ _httpd[cid].websocket_mask[_httpd[cid].len & 0x03]; 00497 } else { 00498 _httpd[cid].buf[_httpd[cid].len] = c; 00499 } 00500 _httpd[cid].len ++; 00501 } 00502 break; 00503 } 00504 00505 if (_httpd[cid].mode == GSHTTPDMODE_WEBSOCKET_BODY && _httpd[cid].len >= _httpd[cid].length) { 00506 flg = 1; 00507 break; 00508 } 00509 } 00510 if (j >= len) return; // continue 00511 if (_httpd[cid].len < HTTPD_BUF_SIZE) { 00512 _httpd[cid].buf[_httpd[cid].len] = 0; 00513 DBG("websocket %d: (%d)\r\n", cid, _httpd[cid].len); 00514 } 00515 00516 if (flg) { 00517 // websocket request 00518 DBG("ws type %d\r\n", _httpd[cid].type); 00519 switch (_httpd[cid].type) { 00520 case 0x00: // continuation 00521 case 0x01: // text 00522 case 0x02: // binary 00523 i = get_handler(_httpd[cid].uri); 00524 if (i >= 0) { 00525 if (_handler[i].onHttpCgi) { 00526 // cgi 00527 _handler[i].onHttpCgi(cid, &_httpd[cid]); 00528 LOG("%d.%d.%d.%d ", _httpd[cid].host.getIp()[0], _httpd[cid].host.getIp()[1], _httpd[cid].host.getIp()[2], _httpd[cid].host.getIp()[3]); 00529 LOG("%s %s %d 200 -\r\n", "WEBSOCKET", _httpd[cid].uri, _httpd[cid].length); 00530 flg = 1; 00531 } 00532 } 00533 break; 00534 00535 case 0x08: // close 00536 close(cid); 00537 break; 00538 00539 case 0x09: // ping 00540 { 00541 char pong[_httpd[cid].len + 2]; 00542 pong[0] = 0x8a; 00543 pong[1] = 0x04; 00544 memcpy(&pong[2], _httpd[cid].buf, _httpd[cid].len); 00545 send(cid, pong, _httpd[cid].len + 2); 00546 } 00547 break; 00548 00549 case 0x0a: // pong 00550 break; 00551 } 00552 _httpd[cid].mode = GSHTTPDMODE_WEBSOCKET; 00553 _httpd[cid].len = 0; 00554 _httpd[cid].length = 0; 00555 } 00556 } // while 00557 } 00558 00559 void GSwifi::send_websocket_accept (int cid) { 00560 char buf[100], buf2[20]; 00561 00562 DBG("websocket accept: %d\r\n", cid); 00563 00564 send(cid, "HTTP/1.1 101 Switching Protocols\r\n", 34); 00565 send(cid, "Upgrade: websocket\r\n", 20); 00566 send(cid, "Connection: Upgrade\r\n", 21); 00567 00568 send(cid, "Sec-WebSocket-Accept: ", 22); 00569 strcpy(buf, _httpd[cid].websocket_key); 00570 strcat(buf, "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); 00571 sha1(buf, strlen(buf), buf2); 00572 base64encode(buf2, 20, buf, sizeof(buf)); 00573 send(cid, buf, strlen(buf)); 00574 send(cid, "\r\n", 2); 00575 // send(cid, "Sec-WebSocket-Protocol: chat\r\n", 30); 00576 send(cid, "\r\n", 2); 00577 LOG("%d.%d.%d.%d ", _httpd[cid].host.getIp()[0], _httpd[cid].host.getIp()[1], _httpd[cid].host.getIp()[2], _httpd[cid].host.getIp()[3]); 00578 LOG("%s %s %d 101 - %s\r\n", _httpd[cid].type == GSPROT_HTTPGET ? "GET" : "POST", _httpd[cid].uri, _httpd[cid].length, buf); 00579 } 00580 #endif // GS_ENABLE_WEBSOCKET 00581 00582 #endif
Generated on Tue Jul 12 2022 22:02:57 by 1.7.2