NetworkServices with NUCLEO-L476RG and W5500 by SeeedStudio stack.

Dependents:   coap-example Borsch coap-example

Fork of NetworkServices by AMETEK Powervar

Committer:
sgnezdov
Date:
Wed Jul 05 18:34:39 2017 +0000
Revision:
17:c976088bf39d
Parent:
15:14382459c8b7
Changed setup interface to take MAC address, because W5500 may use software defined MAC when obtaining IP.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dgriffin65 15:14382459c8b7 1 /* Copyright (C) 2013 Hiroshi Suga, MIT License
dgriffin65 15:14382459c8b7 2 *
dgriffin65 15:14382459c8b7 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
dgriffin65 15:14382459c8b7 4 * and associated documentation files (the "Software"), to deal in the Software without restriction,
dgriffin65 15:14382459c8b7 5 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
dgriffin65 15:14382459c8b7 6 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
dgriffin65 15:14382459c8b7 7 * furnished to do so, subject to the following conditions:
dgriffin65 15:14382459c8b7 8 *
dgriffin65 15:14382459c8b7 9 * The above copyright notice and this permission notice shall be included in all copies or
dgriffin65 15:14382459c8b7 10 * substantial portions of the Software.
dgriffin65 15:14382459c8b7 11 *
dgriffin65 15:14382459c8b7 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
dgriffin65 15:14382459c8b7 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
dgriffin65 15:14382459c8b7 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
dgriffin65 15:14382459c8b7 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
dgriffin65 15:14382459c8b7 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
dgriffin65 15:14382459c8b7 17 */
dgriffin65 15:14382459c8b7 18
dgriffin65 15:14382459c8b7 19 #include "HTTPD.h"
dgriffin65 15:14382459c8b7 20
dgriffin65 15:14382459c8b7 21
dgriffin65 15:14382459c8b7 22 int HTTPD::httpdFile (int id, char *dir) {
dgriffin65 15:14382459c8b7 23 FILE *fp;
dgriffin65 15:14382459c8b7 24 int i, len;
dgriffin65 15:14382459c8b7 25 char buf[HTTPD_BUF_SIZE];
dgriffin65 15:14382459c8b7 26 char file[HTTPD_CMD_SIZE];
dgriffin65 15:14382459c8b7 27
dgriffin65 15:14382459c8b7 28 INFO("httpdFile %d %s", id, dir);
dgriffin65 15:14382459c8b7 29
dgriffin65 15:14382459c8b7 30 strcpy(file, dir);
dgriffin65 15:14382459c8b7 31 strcat(file, _state[id].filename);
dgriffin65 15:14382459c8b7 32 if (file[strlen(file) - 1] == '/') {
dgriffin65 15:14382459c8b7 33 strcat(file, "index.html");
dgriffin65 15:14382459c8b7 34 }
dgriffin65 15:14382459c8b7 35 DBG("file: %s\r\n", file);
dgriffin65 15:14382459c8b7 36
dgriffin65 15:14382459c8b7 37 fp = fopen(file, "r");
dgriffin65 15:14382459c8b7 38 if (fp) {
dgriffin65 15:14382459c8b7 39 strcpy(buf, "HTTP/1.1 200 OK\r\n");
dgriffin65 15:14382459c8b7 40 _state[id].client->send(buf, strlen(buf));
dgriffin65 15:14382459c8b7 41 {
dgriffin65 15:14382459c8b7 42 // file size
dgriffin65 15:14382459c8b7 43 i = ftell(fp);
dgriffin65 15:14382459c8b7 44 fseek(fp, 0, SEEK_END);
dgriffin65 15:14382459c8b7 45 len = ftell(fp);
dgriffin65 15:14382459c8b7 46 fseek(fp, i, SEEK_SET);
dgriffin65 15:14382459c8b7 47 }
dgriffin65 15:14382459c8b7 48
dgriffin65 15:14382459c8b7 49 strcpy(buf, "Server: GSwifi httpd\r\n");
dgriffin65 15:14382459c8b7 50 _state[id].client->send(buf, strlen(buf));
dgriffin65 15:14382459c8b7 51 if (_state[id].keepalive) {
dgriffin65 15:14382459c8b7 52 strcpy(buf, "Connection: Keep-Alive\r\n");
dgriffin65 15:14382459c8b7 53 } else {
dgriffin65 15:14382459c8b7 54 strcpy(buf, "Connection: close\r\n");
dgriffin65 15:14382459c8b7 55 }
dgriffin65 15:14382459c8b7 56 _state[id].client->send(buf, strlen(buf));
dgriffin65 15:14382459c8b7 57 sprintf(buf, "Content-Type: %s\r\n", mimetype(file));
dgriffin65 15:14382459c8b7 58 _state[id].client->send(buf, strlen(buf));
dgriffin65 15:14382459c8b7 59 sprintf(buf, "Content-Length: %d\r\n\r\n", len);
dgriffin65 15:14382459c8b7 60 _state[id].client->send(buf, strlen(buf));
dgriffin65 15:14382459c8b7 61
dgriffin65 15:14382459c8b7 62 for (;;) {
dgriffin65 15:14382459c8b7 63 i = fread(buf, sizeof(char), sizeof(buf), fp);
dgriffin65 15:14382459c8b7 64 if (i <= 0) break;
dgriffin65 15:14382459c8b7 65 _state[id].client->send(buf, i);
dgriffin65 15:14382459c8b7 66 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
dgriffin65 15:14382459c8b7 67 if (feof(fp)) break;
dgriffin65 15:14382459c8b7 68 #endif
dgriffin65 15:14382459c8b7 69 }
dgriffin65 15:14382459c8b7 70 fclose(fp);
dgriffin65 15:14382459c8b7 71 return 0;
dgriffin65 15:14382459c8b7 72 }
dgriffin65 15:14382459c8b7 73
dgriffin65 15:14382459c8b7 74 httpdError(id, 404);
dgriffin65 15:14382459c8b7 75 return -1;
dgriffin65 15:14382459c8b7 76 }
dgriffin65 15:14382459c8b7 77
dgriffin65 15:14382459c8b7 78 void HTTPD::httpdError (int id, int err) {
dgriffin65 15:14382459c8b7 79 char buf[HTTPD_CMD_SIZE], msg[30];
dgriffin65 15:14382459c8b7 80
dgriffin65 15:14382459c8b7 81 switch (err) {
dgriffin65 15:14382459c8b7 82 case 400:
dgriffin65 15:14382459c8b7 83 strcpy(msg, "Bad Request");
dgriffin65 15:14382459c8b7 84 break;
dgriffin65 15:14382459c8b7 85 case 403:
dgriffin65 15:14382459c8b7 86 strcpy(msg, "Forbidden");
dgriffin65 15:14382459c8b7 87 break;
dgriffin65 15:14382459c8b7 88 case 404:
dgriffin65 15:14382459c8b7 89 strcpy(msg, "Not Found");
dgriffin65 15:14382459c8b7 90 break;
dgriffin65 15:14382459c8b7 91 case 500:
dgriffin65 15:14382459c8b7 92 default:
dgriffin65 15:14382459c8b7 93 strcpy(msg, "Internal Server Error");
dgriffin65 15:14382459c8b7 94 break;
dgriffin65 15:14382459c8b7 95 }
dgriffin65 15:14382459c8b7 96 DBG("httpd error: %d %d %s\r\n", id, err, msg);
dgriffin65 15:14382459c8b7 97
dgriffin65 15:14382459c8b7 98 sprintf(buf, "HTTP/1.1 %d %s\r\n", err, msg);
dgriffin65 15:14382459c8b7 99 _state[id].client->send(buf, strlen(buf));
dgriffin65 15:14382459c8b7 100 strcpy(buf, "Content-Type: text/html\r\n\r\n");
dgriffin65 15:14382459c8b7 101 _state[id].client->send(buf, strlen(buf));
dgriffin65 15:14382459c8b7 102
dgriffin65 15:14382459c8b7 103 sprintf(buf, "<html><head><title>%d %s</title></head>\r\n", err, msg);
dgriffin65 15:14382459c8b7 104 _state[id].client->send(buf, strlen(buf));
dgriffin65 15:14382459c8b7 105 sprintf(buf, "<body><h1>%s</h1></body></html>\r\n", msg);
dgriffin65 15:14382459c8b7 106 _state[id].client->send(buf, strlen(buf));
dgriffin65 15:14382459c8b7 107 wait_ms(100);
dgriffin65 15:14382459c8b7 108 _state[id].client->close();
dgriffin65 15:14382459c8b7 109 //WARN("%d.%d.%d.%d ", _httpd[cid].host.getIp()[0], _httpd[cid].host.getIp()[1], _httpd[cid].host.getIp()[2], _httpd[cid].host.getIp()[3]);
dgriffin65 15:14382459c8b7 110 //WARN("%s %s %d %d -\r\n", _httpd[cid].type == GSPROT_HTTPGET ? "GET" : "POST", _httpd[cid].uri, _httpd[cid].length, err);
dgriffin65 15:14382459c8b7 111 }
dgriffin65 15:14382459c8b7 112
dgriffin65 15:14382459c8b7 113 void HTTPD::recvData (int id, char c) {
dgriffin65 15:14382459c8b7 114
dgriffin65 15:14382459c8b7 115 switch (_state[id].mode) {
dgriffin65 15:14382459c8b7 116 case MODE_REQUEST:
dgriffin65 15:14382459c8b7 117 if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
dgriffin65 15:14382459c8b7 118 _state[id].buf->flush();
dgriffin65 15:14382459c8b7 119 _state[id].buf->queue(c);
dgriffin65 15:14382459c8b7 120 _state[id].mode = MODE_REQSTR;
dgriffin65 15:14382459c8b7 121 } else {
dgriffin65 15:14382459c8b7 122 _state[id].buf->flush();
dgriffin65 15:14382459c8b7 123 }
dgriffin65 15:14382459c8b7 124 break;
dgriffin65 15:14382459c8b7 125 case MODE_REQSTR:
dgriffin65 15:14382459c8b7 126 switch (c) {
dgriffin65 15:14382459c8b7 127 case 0:
dgriffin65 15:14382459c8b7 128 break;
dgriffin65 15:14382459c8b7 129 case 0x0a: // LF
dgriffin65 15:14382459c8b7 130 case 0x0d: // CR
dgriffin65 15:14382459c8b7 131 if (parseRequest(id)) {
dgriffin65 15:14382459c8b7 132 _state[id].mode = MODE_REQSTR;
dgriffin65 15:14382459c8b7 133 } else {
dgriffin65 15:14382459c8b7 134 _state[id].mode = MODE_HEADER;
dgriffin65 15:14382459c8b7 135 }
dgriffin65 15:14382459c8b7 136 _state[id].enter = 0;
dgriffin65 15:14382459c8b7 137 break;
dgriffin65 15:14382459c8b7 138 default:
dgriffin65 15:14382459c8b7 139 _state[id].buf->queue(c);
dgriffin65 15:14382459c8b7 140 break;
dgriffin65 15:14382459c8b7 141 }
dgriffin65 15:14382459c8b7 142 break;
dgriffin65 15:14382459c8b7 143 case MODE_HEADER:
dgriffin65 15:14382459c8b7 144 switch (c) {
dgriffin65 15:14382459c8b7 145 case 0:
dgriffin65 15:14382459c8b7 146 break;
dgriffin65 15:14382459c8b7 147 case 0x0a: // LF
dgriffin65 15:14382459c8b7 148 case 0x0d: // CR
dgriffin65 15:14382459c8b7 149 if (_state[id].buf->available() == 0) {
dgriffin65 15:14382459c8b7 150 if ((_state[id].enter == 0x0d && c == 0x0a) || (_state[id].enter == 0x0a && c == 0x0a)) {
dgriffin65 15:14382459c8b7 151 _state[id].buf->flush();
dgriffin65 15:14382459c8b7 152 if (_state[id].websocket) {
dgriffin65 15:14382459c8b7 153 INFO("MODE_WEBSOCKET");
dgriffin65 15:14382459c8b7 154 acceptWebsocket(id);
dgriffin65 15:14382459c8b7 155 _state[id].mode = MODE_WEBSOCKET;
dgriffin65 15:14382459c8b7 156 } else
dgriffin65 15:14382459c8b7 157 if (_state[id].length) {
dgriffin65 15:14382459c8b7 158 INFO("MODE_BODY");
dgriffin65 15:14382459c8b7 159 _state[id].mode = MODE_BODY;
dgriffin65 15:14382459c8b7 160 } else {
dgriffin65 15:14382459c8b7 161 INFO("MODE_ENTER");
dgriffin65 15:14382459c8b7 162 _state[id].mode = MODE_ENTER;
dgriffin65 15:14382459c8b7 163 }
dgriffin65 15:14382459c8b7 164 }
dgriffin65 15:14382459c8b7 165 _state[id].enter = c;
dgriffin65 15:14382459c8b7 166 _state[id].buf->flush();
dgriffin65 15:14382459c8b7 167 break;
dgriffin65 15:14382459c8b7 168 }
dgriffin65 15:14382459c8b7 169
dgriffin65 15:14382459c8b7 170 parseHeader(id);
dgriffin65 15:14382459c8b7 171 _state[id].enter = 0;
dgriffin65 15:14382459c8b7 172 break;
dgriffin65 15:14382459c8b7 173 default:
dgriffin65 15:14382459c8b7 174 _state[id].buf->queue(c);
dgriffin65 15:14382459c8b7 175 _state[id].enter = 0;
dgriffin65 15:14382459c8b7 176 break;
dgriffin65 15:14382459c8b7 177 }
dgriffin65 15:14382459c8b7 178 break;
dgriffin65 15:14382459c8b7 179 case MODE_BODY:
dgriffin65 15:14382459c8b7 180 _state[id].buf->queue(c);
dgriffin65 15:14382459c8b7 181 if (_state[id].buf->available() >= _state[id].length) {
dgriffin65 15:14382459c8b7 182 _state[id].mode = MODE_ENTER;
dgriffin65 15:14382459c8b7 183 }
dgriffin65 15:14382459c8b7 184 break;
dgriffin65 15:14382459c8b7 185 case MODE_WEBSOCKET:
dgriffin65 15:14382459c8b7 186 case MODE_WEBSOCKET_MASK:
dgriffin65 15:14382459c8b7 187 case MODE_WEBSOCKET_BODY:
dgriffin65 15:14382459c8b7 188 recvWS(id, c);
dgriffin65 15:14382459c8b7 189 break;
dgriffin65 15:14382459c8b7 190 }
dgriffin65 15:14382459c8b7 191
dgriffin65 15:14382459c8b7 192 if (_state[id].mode == MODE_ENTER) {
dgriffin65 15:14382459c8b7 193 int i = getHandler(_state[id].uri);
dgriffin65 15:14382459c8b7 194 printf("handler = %d, uri = %s\r\n", i, _state[id].uri);
dgriffin65 15:14382459c8b7 195 if (i >= 0) {
dgriffin65 15:14382459c8b7 196 if (_handler[i].dir) {
dgriffin65 15:14382459c8b7 197 // file
dgriffin65 15:14382459c8b7 198 httpdFile(id, _handler[i].dir);
dgriffin65 15:14382459c8b7 199 } else if (_handler[i].funcCgi) {
dgriffin65 15:14382459c8b7 200 // cgi
dgriffin65 15:14382459c8b7 201 _handler[i].funcCgi(id);
dgriffin65 15:14382459c8b7 202 _state[id].keepalive = 0;
dgriffin65 15:14382459c8b7 203 } else {
dgriffin65 15:14382459c8b7 204 httpdError(id, 403);
dgriffin65 15:14382459c8b7 205 }
dgriffin65 15:14382459c8b7 206 } else {
dgriffin65 15:14382459c8b7 207 httpdError(id, 404);
dgriffin65 15:14382459c8b7 208 }
dgriffin65 15:14382459c8b7 209
dgriffin65 15:14382459c8b7 210 if (_state[id].keepalive) {
dgriffin65 15:14382459c8b7 211 DBG("keepalive %d", _state[id].keepalive);
dgriffin65 15:14382459c8b7 212 _state[id].keepalive--;
dgriffin65 15:14382459c8b7 213 } else {
dgriffin65 15:14382459c8b7 214 _state[id].client->close();
dgriffin65 15:14382459c8b7 215 }
dgriffin65 15:14382459c8b7 216 _state[id].mode = MODE_REQUEST;
dgriffin65 15:14382459c8b7 217 } else
dgriffin65 15:14382459c8b7 218 if (_state[id].mode == MODE_WEBSOCKET_ENTER) {
dgriffin65 15:14382459c8b7 219 parseWebsocket(id);
dgriffin65 15:14382459c8b7 220 _state[id].mode = MODE_WEBSOCKET;
dgriffin65 15:14382459c8b7 221 }
dgriffin65 15:14382459c8b7 222 }
dgriffin65 15:14382459c8b7 223
dgriffin65 15:14382459c8b7 224 int HTTPD::parseRequest (int id) {
dgriffin65 15:14382459c8b7 225 int i, j, len;
dgriffin65 15:14382459c8b7 226 char buf[HTTPD_CMD_SIZE];
dgriffin65 15:14382459c8b7 227
dgriffin65 15:14382459c8b7 228 for (len = 0; len < sizeof(buf); len++) {
dgriffin65 15:14382459c8b7 229 if (_state[id].buf->dequeue(&buf[len]) == false) break;
dgriffin65 15:14382459c8b7 230 }
dgriffin65 15:14382459c8b7 231 buf[len] = 0;
dgriffin65 15:14382459c8b7 232
dgriffin65 15:14382459c8b7 233 if (strnicmp(buf, "GET ", 4) == 0) {
dgriffin65 15:14382459c8b7 234 _state[id].req = REQ_HTTPGET;
dgriffin65 15:14382459c8b7 235 j = 4;
dgriffin65 15:14382459c8b7 236 } else
dgriffin65 15:14382459c8b7 237 if (strnicmp(buf, "POST ", 5) == 0) {
dgriffin65 15:14382459c8b7 238 _state[id].req = REQ_HTTPPOST;
dgriffin65 15:14382459c8b7 239 j = 5;
dgriffin65 15:14382459c8b7 240 } else {
dgriffin65 15:14382459c8b7 241 return -1;
dgriffin65 15:14382459c8b7 242 }
dgriffin65 15:14382459c8b7 243
dgriffin65 15:14382459c8b7 244 for (i = 0; i < len - j; i ++) {
dgriffin65 15:14382459c8b7 245 _state[id].uri[i] = buf[i + j];
dgriffin65 15:14382459c8b7 246 if (buf[i + j] == ' ' || i >= sizeof(buf) - 1) {
dgriffin65 15:14382459c8b7 247 _state[id].uri[i] = 0;
dgriffin65 15:14382459c8b7 248 INFO("URI %d '%s'", _state[id].req, _state[id].uri);
dgriffin65 15:14382459c8b7 249 _state[id].mode = MODE_HEADER;
dgriffin65 15:14382459c8b7 250 _state[id].buf->flush();
dgriffin65 15:14382459c8b7 251 _state[id].length = 0;
dgriffin65 15:14382459c8b7 252 _state[id].n = 0;
dgriffin65 15:14382459c8b7 253 _state[id].websocket = 0;
dgriffin65 15:14382459c8b7 254 _state[id].filename = NULL;
dgriffin65 15:14382459c8b7 255 _state[id].querystring = NULL;
dgriffin65 15:14382459c8b7 256 break;
dgriffin65 15:14382459c8b7 257 }
dgriffin65 15:14382459c8b7 258 }
dgriffin65 15:14382459c8b7 259
dgriffin65 15:14382459c8b7 260 i = getHandler(_state[id].uri);
dgriffin65 15:14382459c8b7 261 if (i >= 0) {
dgriffin65 15:14382459c8b7 262 _state[id].filename = &_state[id].uri[strlen(_handler[i].uri)];
dgriffin65 15:14382459c8b7 263 for (i = 0; i < strlen(_state[id].filename); i ++) {
dgriffin65 15:14382459c8b7 264 if (_state[id].filename[i] == '?') {
dgriffin65 15:14382459c8b7 265 _state[id].filename[i] = 0;
dgriffin65 15:14382459c8b7 266 _state[id].querystring = _state[id].filename + i + 1;
dgriffin65 15:14382459c8b7 267 break;
dgriffin65 15:14382459c8b7 268 }
dgriffin65 15:14382459c8b7 269 }
dgriffin65 15:14382459c8b7 270 INFO("FILE '%s' QUERY '%s'", _state[id].filename, _state[id].querystring);
dgriffin65 15:14382459c8b7 271 }
dgriffin65 15:14382459c8b7 272 return 0;
dgriffin65 15:14382459c8b7 273 }
dgriffin65 15:14382459c8b7 274
dgriffin65 15:14382459c8b7 275 #define HEADER_TABLE_NUM 5
dgriffin65 15:14382459c8b7 276 int HTTPD::parseHeader (int id) {
dgriffin65 15:14382459c8b7 277 int i;
dgriffin65 15:14382459c8b7 278 char buf[HTTPD_CMD_SIZE];
dgriffin65 15:14382459c8b7 279 static const struct HEADER_TABLE {
dgriffin65 15:14382459c8b7 280 const char header[24];
dgriffin65 15:14382459c8b7 281 void (HTTPD::*func)(int id, const char*);
dgriffin65 15:14382459c8b7 282 } header_table[HEADER_TABLE_NUM] = {
dgriffin65 15:14382459c8b7 283 {"Content-Length:", &HTTPD::reqContentLength},
dgriffin65 15:14382459c8b7 284 {"Connection:", &HTTPD::reqConnection},
dgriffin65 15:14382459c8b7 285 {"Upgrade: websocket", &HTTPD::reqUpgrade},
dgriffin65 15:14382459c8b7 286 {"Sec-WebSocket-Version:", &HTTPD::reqWebSocketVersion},
dgriffin65 15:14382459c8b7 287 {"Sec-WebSocket-Key:", &HTTPD::reqWebSocketKey},
dgriffin65 15:14382459c8b7 288 };
dgriffin65 15:14382459c8b7 289 for (i = 0; i < sizeof(buf); i++) {
dgriffin65 15:14382459c8b7 290 if (_state[id].buf->dequeue(&buf[i]) == false) break;
dgriffin65 15:14382459c8b7 291 }
dgriffin65 15:14382459c8b7 292 buf[i] = 0;
dgriffin65 15:14382459c8b7 293
dgriffin65 15:14382459c8b7 294 for (i = 0; i < HEADER_TABLE_NUM; i ++) {
dgriffin65 15:14382459c8b7 295 if (strnicmp(buf, header_table[i].header, strlen(header_table[i].header)) == 0) {
dgriffin65 15:14382459c8b7 296 DBG("parse header %d '%s'\r\n", i, buf);
dgriffin65 15:14382459c8b7 297 if (header_table[i].func != NULL) {
dgriffin65 15:14382459c8b7 298 (this->*(header_table[i].func))(id, buf);
dgriffin65 15:14382459c8b7 299 }
dgriffin65 15:14382459c8b7 300 return 0;
dgriffin65 15:14382459c8b7 301 }
dgriffin65 15:14382459c8b7 302 }
dgriffin65 15:14382459c8b7 303
dgriffin65 15:14382459c8b7 304 return -1;
dgriffin65 15:14382459c8b7 305 }
dgriffin65 15:14382459c8b7 306
dgriffin65 15:14382459c8b7 307 void HTTPD::reqContentLength (int id, const char *buf) {
dgriffin65 15:14382459c8b7 308 _state[id].length = atoi(&buf[16]);
dgriffin65 15:14382459c8b7 309 }
dgriffin65 15:14382459c8b7 310
dgriffin65 15:14382459c8b7 311 void HTTPD::reqConnection (int id, const char *buf) {
dgriffin65 15:14382459c8b7 312 if (strnicmp(&buf[12], "Keep-Alive", 10) == 0 && _state[id].keepalive == 0) {
dgriffin65 15:14382459c8b7 313 _state[id].keepalive = HTTPD_KEEPALIVE;
dgriffin65 15:14382459c8b7 314 } else {
dgriffin65 15:14382459c8b7 315 _state[id].keepalive = 0;
dgriffin65 15:14382459c8b7 316 }
dgriffin65 15:14382459c8b7 317 }
dgriffin65 15:14382459c8b7 318
dgriffin65 15:14382459c8b7 319 void HTTPD::reqUpgrade (int id, const char *buf) {
dgriffin65 15:14382459c8b7 320 if (! _state[id].websocket) _state[id].websocket = 1;
dgriffin65 15:14382459c8b7 321 }
dgriffin65 15:14382459c8b7 322
dgriffin65 15:14382459c8b7 323 void HTTPD::reqWebSocketVersion (int id, const char *buf) {
dgriffin65 15:14382459c8b7 324 _state[id].websocket = atoi(&buf[23]);
dgriffin65 15:14382459c8b7 325 }
dgriffin65 15:14382459c8b7 326
dgriffin65 15:14382459c8b7 327 void HTTPD::reqWebSocketKey (int id, const char *buf) {
dgriffin65 15:14382459c8b7 328 if (_state[id].websocket_key == NULL) {
dgriffin65 15:14382459c8b7 329 _state[id].websocket_key = (char*)malloc(30);
dgriffin65 15:14382459c8b7 330 }
dgriffin65 15:14382459c8b7 331 strncpy(_state[id].websocket_key, &buf[19], 30);
dgriffin65 15:14382459c8b7 332 }