NetworkServices with NUCLEO-L476RG and W5500 by SeeedStudio stack.

Dependents:   coap-example Borsch coap-example

Fork of NetworkServices by AMETEK Powervar

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 #include <ctype.h>
dgriffin65 15:14382459c8b7 21 #include <stdlib.h>
dgriffin65 15:14382459c8b7 22 #include <string.h>
dgriffin65 15:14382459c8b7 23
dgriffin65 15:14382459c8b7 24 #define MIMETABLE_NUM 9
dgriffin65 15:14382459c8b7 25 static const struct {
dgriffin65 15:14382459c8b7 26 char ext[5];
dgriffin65 15:14382459c8b7 27 char type[24];
dgriffin65 15:14382459c8b7 28 } mimetable[MIMETABLE_NUM] = {
dgriffin65 15:14382459c8b7 29 {"txt", "text/plain"}, // default
dgriffin65 15:14382459c8b7 30 {"html", "text/html"},
dgriffin65 15:14382459c8b7 31 {"htm", "text/html"},
dgriffin65 15:14382459c8b7 32 {"css", "text/css"},
dgriffin65 15:14382459c8b7 33 {"js", "application/javascript"},
dgriffin65 15:14382459c8b7 34 {"jpg", "image/jpeg"},
dgriffin65 15:14382459c8b7 35 {"png", "image/png"},
dgriffin65 15:14382459c8b7 36 {"gif", "image/gif"},
dgriffin65 15:14382459c8b7 37 {"ico", "image/x-icon"},
dgriffin65 15:14382459c8b7 38 };
dgriffin65 15:14382459c8b7 39
dgriffin65 15:14382459c8b7 40 char *HTTPD::getUri (int id) {
dgriffin65 15:14382459c8b7 41 return _state[id].uri;
dgriffin65 15:14382459c8b7 42 }
dgriffin65 15:14382459c8b7 43
dgriffin65 15:14382459c8b7 44 char *HTTPD::getFilename (int id) {
dgriffin65 15:14382459c8b7 45 return _state[id].filename;
dgriffin65 15:14382459c8b7 46 }
dgriffin65 15:14382459c8b7 47
dgriffin65 15:14382459c8b7 48 char *HTTPD::getQueryString (int id) {
dgriffin65 15:14382459c8b7 49 return _state[id].querystring;
dgriffin65 15:14382459c8b7 50 }
dgriffin65 15:14382459c8b7 51
dgriffin65 15:14382459c8b7 52 int HTTPD::receive (int id, char *buf, int len) {
dgriffin65 15:14382459c8b7 53 int i;
dgriffin65 15:14382459c8b7 54
dgriffin65 15:14382459c8b7 55 for (i = 0; i < len; i ++) {
dgriffin65 15:14382459c8b7 56 if (_state[id].buf->dequeue(&buf[i]) == false) break;
dgriffin65 15:14382459c8b7 57 }
dgriffin65 15:14382459c8b7 58 return i;
dgriffin65 15:14382459c8b7 59 }
dgriffin65 15:14382459c8b7 60
dgriffin65 15:14382459c8b7 61 int HTTPD::send (int id, const char *body, int len, const char *header) {
dgriffin65 15:14382459c8b7 62 char buf[HTTPD_CMD_SIZE];
dgriffin65 15:14382459c8b7 63
dgriffin65 15:14382459c8b7 64 strcpy(buf, "HTTP/1.1 200 OK\r\n");
dgriffin65 15:14382459c8b7 65 _state[id].client->send(buf, strlen(buf));
dgriffin65 15:14382459c8b7 66 strcpy(buf, "Server: GSwifi httpd\r\n");
dgriffin65 15:14382459c8b7 67 _state[id].client->send(buf, strlen(buf));
dgriffin65 15:14382459c8b7 68 if (_state[id].keepalive) {
dgriffin65 15:14382459c8b7 69 strcpy(buf, "Connection: Keep-Alive\r\n");
dgriffin65 15:14382459c8b7 70 } else {
dgriffin65 15:14382459c8b7 71 strcpy(buf, "Connection: close\r\n");
dgriffin65 15:14382459c8b7 72 }
dgriffin65 15:14382459c8b7 73 _state[id].client->send(buf, strlen(buf));
dgriffin65 15:14382459c8b7 74 if (header) {
dgriffin65 15:14382459c8b7 75 _state[id].client->send((char*)header, strlen(header));
dgriffin65 15:14382459c8b7 76 }
dgriffin65 15:14382459c8b7 77 sprintf(buf, "Content-Length: %d\r\n\r\n", len);
dgriffin65 15:14382459c8b7 78 _state[id].client->send(buf, strlen(buf));
dgriffin65 15:14382459c8b7 79
dgriffin65 15:14382459c8b7 80 return _state[id].client->send((char*)body, len);
dgriffin65 15:14382459c8b7 81 }
dgriffin65 15:14382459c8b7 82
dgriffin65 15:14382459c8b7 83 int HTTPD::sendstr (int id, const char *buf) {
dgriffin65 15:14382459c8b7 84 return _state[id].client->send((char*)buf, strlen(buf));
dgriffin65 15:14382459c8b7 85 }
dgriffin65 15:14382459c8b7 86
dgriffin65 15:14382459c8b7 87
dgriffin65 15:14382459c8b7 88 int HTTPD::hprintf(int id, const char* format, ...) {
dgriffin65 15:14382459c8b7 89 //FIX ME: This could result in memory overruns if the buffer size is exceeded
dgriffin65 15:14382459c8b7 90 static Mutex _mtx;
dgriffin65 15:14382459c8b7 91 static char _buf[1024];
dgriffin65 15:14382459c8b7 92
dgriffin65 15:14382459c8b7 93 std::va_list arg;
dgriffin65 15:14382459c8b7 94
dgriffin65 15:14382459c8b7 95 _mtx.lock();
dgriffin65 15:14382459c8b7 96
dgriffin65 15:14382459c8b7 97 va_start(arg, format);
dgriffin65 15:14382459c8b7 98 vsprintf(_buf, format, arg);
dgriffin65 15:14382459c8b7 99 va_end(arg);
dgriffin65 15:14382459c8b7 100
dgriffin65 15:14382459c8b7 101 int r = _state[id].client->send(_buf, strlen(_buf));
dgriffin65 15:14382459c8b7 102
dgriffin65 15:14382459c8b7 103 _mtx.unlock();
dgriffin65 15:14382459c8b7 104 return r;
dgriffin65 15:14382459c8b7 105 }
dgriffin65 15:14382459c8b7 106
dgriffin65 15:14382459c8b7 107 int HTTPD::getHandler (const char *uri) {
dgriffin65 15:14382459c8b7 108 int i;
dgriffin65 15:14382459c8b7 109
dgriffin65 15:14382459c8b7 110 for (i = 0; i < _handler_count; i ++) {
dgriffin65 15:14382459c8b7 111 if (strncmp(uri, _handler[i].uri, strlen(_handler[i].uri)) == NULL) {
dgriffin65 15:14382459c8b7 112 // found
dgriffin65 15:14382459c8b7 113 return i;
dgriffin65 15:14382459c8b7 114 }
dgriffin65 15:14382459c8b7 115 }
dgriffin65 15:14382459c8b7 116 return -1;
dgriffin65 15:14382459c8b7 117 }
dgriffin65 15:14382459c8b7 118
dgriffin65 15:14382459c8b7 119 int HTTPD::attach (const char *uri, const char *dir) {
dgriffin65 15:14382459c8b7 120 if (_handler_count < HTTPD_MAX_HANDLES) {
dgriffin65 15:14382459c8b7 121 _handler[_handler_count].uri = (char*)malloc(strlen(uri) + 1);
dgriffin65 15:14382459c8b7 122 strcpy(_handler[_handler_count].uri, uri);
dgriffin65 15:14382459c8b7 123 _handler[_handler_count].dir = (char*)malloc(strlen(dir) + 1);
dgriffin65 15:14382459c8b7 124 strcpy(_handler[_handler_count].dir, dir);
dgriffin65 15:14382459c8b7 125 _handler[_handler_count].funcCgi = NULL;
dgriffin65 15:14382459c8b7 126 _handler_count ++;
dgriffin65 15:14382459c8b7 127 return 0;
dgriffin65 15:14382459c8b7 128 } else {
dgriffin65 15:14382459c8b7 129 return -1;
dgriffin65 15:14382459c8b7 130 }
dgriffin65 15:14382459c8b7 131 }
dgriffin65 15:14382459c8b7 132
dgriffin65 15:14382459c8b7 133 int HTTPD::attach (const char *uri, void (*funcCgi)(int)) {
dgriffin65 15:14382459c8b7 134 if (_handler_count < HTTPD_MAX_HANDLES) {
dgriffin65 15:14382459c8b7 135 _handler[_handler_count].uri = (char*)malloc(strlen(uri) + 1);
dgriffin65 15:14382459c8b7 136 strcpy(_handler[_handler_count].uri, uri);
dgriffin65 15:14382459c8b7 137 _handler[_handler_count].dir = NULL;
dgriffin65 15:14382459c8b7 138 _handler[_handler_count].funcCgi = funcCgi;
dgriffin65 15:14382459c8b7 139 _handler_count ++;
dgriffin65 15:14382459c8b7 140 return 0;
dgriffin65 15:14382459c8b7 141 } else {
dgriffin65 15:14382459c8b7 142 return -1;
dgriffin65 15:14382459c8b7 143 }
dgriffin65 15:14382459c8b7 144 }
dgriffin65 15:14382459c8b7 145
dgriffin65 15:14382459c8b7 146
dgriffin65 15:14382459c8b7 147 char *HTTPD::mimetype (char *file) {
dgriffin65 15:14382459c8b7 148 int i, j;
dgriffin65 15:14382459c8b7 149
dgriffin65 15:14382459c8b7 150 for (i = 0; i < MIMETABLE_NUM; i ++) {
dgriffin65 15:14382459c8b7 151 j = strlen(mimetable[i].ext);
dgriffin65 15:14382459c8b7 152 if (file[strlen(file) - j - 1] == '.' &&
dgriffin65 15:14382459c8b7 153 strnicmp(&file[strlen(file) - j], mimetable[i].ext, j) == NULL) {
dgriffin65 15:14382459c8b7 154 return (char*)mimetable[i].type;
dgriffin65 15:14382459c8b7 155 }
dgriffin65 15:14382459c8b7 156 }
dgriffin65 15:14382459c8b7 157 return (char*)mimetable[0].type;
dgriffin65 15:14382459c8b7 158 }
dgriffin65 15:14382459c8b7 159
dgriffin65 15:14382459c8b7 160 int HTTPD::strnicmp (const char *p1, const char *p2, int n) {
dgriffin65 15:14382459c8b7 161 int i, r = -1;
dgriffin65 15:14382459c8b7 162 char c1, c2;
dgriffin65 15:14382459c8b7 163
dgriffin65 15:14382459c8b7 164 for (i = 0; i < n; i ++) {
dgriffin65 15:14382459c8b7 165 c1 = (p1[i] >= 'a' && p1[i] <= 'z') ? p1[i] - ('a' - 'A'): p1[i];
dgriffin65 15:14382459c8b7 166 c2 = (p2[i] >= 'a' && p2[i] <= 'z') ? p2[i] - ('a' - 'A'): p2[i];
dgriffin65 15:14382459c8b7 167 r = c1 - c2;
dgriffin65 15:14382459c8b7 168 if (r) break;
dgriffin65 15:14382459c8b7 169 }
dgriffin65 15:14382459c8b7 170 return r;
dgriffin65 15:14382459c8b7 171 }
dgriffin65 15:14382459c8b7 172
dgriffin65 15:14382459c8b7 173
dgriffin65 15:14382459c8b7 174 /* base64encode code from
dgriffin65 15:14382459c8b7 175 * Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
dgriffin65 15:14382459c8b7 176 */
dgriffin65 15:14382459c8b7 177 int HTTPD::base64encode (const char *input, int length, char *output, int len) {
dgriffin65 15:14382459c8b7 178 static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
dgriffin65 15:14382459c8b7 179 unsigned int c, c1, c2, c3;
dgriffin65 15:14382459c8b7 180
dgriffin65 15:14382459c8b7 181 if (len < ((((length-1)/3)+1)<<2)) return -1;
dgriffin65 15:14382459c8b7 182 for(unsigned int i = 0, j = 0; i<length; i+=3,j+=4) {
dgriffin65 15:14382459c8b7 183 c1 = ((((unsigned char)*((unsigned char *)&input[i]))));
dgriffin65 15:14382459c8b7 184 c2 = (length>i+1)?((((unsigned char)*((unsigned char *)&input[i+1])))):0;
dgriffin65 15:14382459c8b7 185 c3 = (length>i+2)?((((unsigned char)*((unsigned char *)&input[i+2])))):0;
dgriffin65 15:14382459c8b7 186
dgriffin65 15:14382459c8b7 187 c = ((c1 & 0xFC) >> 2);
dgriffin65 15:14382459c8b7 188 output[j+0] = base64[c];
dgriffin65 15:14382459c8b7 189 c = ((c1 & 0x03) << 4) | ((c2 & 0xF0) >> 4);
dgriffin65 15:14382459c8b7 190 output[j+1] = base64[c];
dgriffin65 15:14382459c8b7 191 c = ((c2 & 0x0F) << 2) | ((c3 & 0xC0) >> 6);
dgriffin65 15:14382459c8b7 192 output[j+2] = (length>i+1)?base64[c]:'=';
dgriffin65 15:14382459c8b7 193 c = (c3 & 0x3F);
dgriffin65 15:14382459c8b7 194 output[j+3] = (length>i+2)?base64[c]:'=';
dgriffin65 15:14382459c8b7 195 }
dgriffin65 15:14382459c8b7 196 output[(((length-1)/3)+1)<<2] = '\0';
dgriffin65 15:14382459c8b7 197 return 0;
dgriffin65 15:14382459c8b7 198 }
dgriffin65 15:14382459c8b7 199
dgriffin65 15:14382459c8b7 200
dgriffin65 15:14382459c8b7 201 /* urlencode code from
dgriffin65 15:14382459c8b7 202 * Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
dgriffin65 15:14382459c8b7 203 */
dgriffin65 15:14382459c8b7 204 int HTTPD::urlencode (const char *str, char *buf, int len) {
dgriffin65 15:14382459c8b7 205 // char *pstr = str, *buf = (char*)malloc(strlen(str) * 3 + 1), *pbuf = buf;
dgriffin65 15:14382459c8b7 206 const char *pstr = str;
dgriffin65 15:14382459c8b7 207 char *pbuf = buf;
dgriffin65 15:14382459c8b7 208
dgriffin65 15:14382459c8b7 209 if (len < (strlen(str) * 3 + 1)) return -1;
dgriffin65 15:14382459c8b7 210 while (*pstr) {
dgriffin65 15:14382459c8b7 211 if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~')
dgriffin65 15:14382459c8b7 212 *pbuf++ = *pstr;
dgriffin65 15:14382459c8b7 213 else if (*pstr == ' ')
dgriffin65 15:14382459c8b7 214 *pbuf++ = '+';
dgriffin65 15:14382459c8b7 215 else
dgriffin65 15:14382459c8b7 216 *pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15);
dgriffin65 15:14382459c8b7 217 pstr++;
dgriffin65 15:14382459c8b7 218 }
dgriffin65 15:14382459c8b7 219 *pbuf = '\0';
dgriffin65 15:14382459c8b7 220 return 0;
dgriffin65 15:14382459c8b7 221 }
dgriffin65 15:14382459c8b7 222
dgriffin65 15:14382459c8b7 223 /* urldecode code from
dgriffin65 15:14382459c8b7 224 * Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
dgriffin65 15:14382459c8b7 225 */
dgriffin65 15:14382459c8b7 226 int HTTPD::urldecode (const char *str, char *buf, int len) {
dgriffin65 15:14382459c8b7 227 // char *pstr = str, *buf = (char*)malloc(strlen(str) + 1), *pbuf = buf;
dgriffin65 15:14382459c8b7 228 const char *pstr = str;
dgriffin65 15:14382459c8b7 229 char *pbuf = buf;
dgriffin65 15:14382459c8b7 230
dgriffin65 15:14382459c8b7 231 if (len < (strlen(str) / 3 - 1)) return -1;
dgriffin65 15:14382459c8b7 232 while (*pstr) {
dgriffin65 15:14382459c8b7 233 if (*pstr == '%') {
dgriffin65 15:14382459c8b7 234 if (pstr[1] && pstr[2]) {
dgriffin65 15:14382459c8b7 235 *pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]);
dgriffin65 15:14382459c8b7 236 pstr += 2;
dgriffin65 15:14382459c8b7 237 }
dgriffin65 15:14382459c8b7 238 } else if (*pstr == '+') {
dgriffin65 15:14382459c8b7 239 *pbuf++ = ' ';
dgriffin65 15:14382459c8b7 240 } else {
dgriffin65 15:14382459c8b7 241 *pbuf++ = *pstr;
dgriffin65 15:14382459c8b7 242 }
dgriffin65 15:14382459c8b7 243 pstr++;
dgriffin65 15:14382459c8b7 244 }
dgriffin65 15:14382459c8b7 245 *pbuf = '\0';
dgriffin65 15:14382459c8b7 246 return 0;
dgriffin65 15:14382459c8b7 247 }
dgriffin65 15:14382459c8b7 248
dgriffin65 15:14382459c8b7 249 int HTTPD::from_hex (int ch) {
dgriffin65 15:14382459c8b7 250 return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
dgriffin65 15:14382459c8b7 251 }
dgriffin65 15:14382459c8b7 252
dgriffin65 15:14382459c8b7 253 int HTTPD::to_hex (int code) {
dgriffin65 15:14382459c8b7 254 static char hex[] = "0123456789abcdef";
dgriffin65 15:14382459c8b7 255 return hex[code & 15];
dgriffin65 15:14382459c8b7 256 }