Network Services

Dependents:   PwrCond_mbed5

Fork of W5500Interface_K22F by Andrew McCartney

Committer:
dgriffin65
Date:
Thu Jun 15 20:29:03 2017 +0000
Revision:
15:14382459c8b7
Converted to a single library

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 }