private fork
Fork of GSwifiInterface by
GSwifi/GSwifi_httpd_util.cpp@15:086d1a33a197, 2014-01-30 (annotated)
- Committer:
- gsfan
- Date:
- Thu Jan 30 15:10:14 2014 +0000
- Revision:
- 15:086d1a33a197
- Parent:
- 12:057089026a20
- Child:
- 20:9bfb8a13010c
fix httpd, WebSocket server, gpio rts/cts, and some bugs.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
gsfan | 12:057089026a20 | 1 | /* Copyright (C) 2013 gsfan, MIT License |
gsfan | 12:057089026a20 | 2 | * |
gsfan | 12:057089026a20 | 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software |
gsfan | 12:057089026a20 | 4 | * and associated documentation files (the "Software"), to deal in the Software without restriction, |
gsfan | 12:057089026a20 | 5 | * including without limitation the rights to use, copy, modify, merge, publish, distribute, |
gsfan | 12:057089026a20 | 6 | * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
gsfan | 12:057089026a20 | 7 | * furnished to do so, subject to the following conditions: |
gsfan | 12:057089026a20 | 8 | * |
gsfan | 12:057089026a20 | 9 | * The above copyright notice and this permission notice shall be included in all copies or |
gsfan | 12:057089026a20 | 10 | * substantial portions of the Software. |
gsfan | 12:057089026a20 | 11 | * |
gsfan | 12:057089026a20 | 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING |
gsfan | 12:057089026a20 | 13 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
gsfan | 12:057089026a20 | 14 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
gsfan | 12:057089026a20 | 15 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
gsfan | 12:057089026a20 | 16 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
gsfan | 12:057089026a20 | 17 | */ |
gsfan | 12:057089026a20 | 18 | |
gsfan | 12:057089026a20 | 19 | #include "GSwifi.h" |
gsfan | 12:057089026a20 | 20 | |
gsfan | 12:057089026a20 | 21 | #ifdef CFG_ENABLE_HTTPD |
gsfan | 12:057089026a20 | 22 | |
gsfan | 12:057089026a20 | 23 | int GSwifi::httpdFile (int cid, char *dir) { |
gsfan | 12:057089026a20 | 24 | FILE *fp; |
gsfan | 12:057089026a20 | 25 | int i, len; |
gsfan | 12:057089026a20 | 26 | char buf[CFG_DATA_SIZE]; |
gsfan | 12:057089026a20 | 27 | char file[CFG_CMD_SIZE]; |
gsfan | 12:057089026a20 | 28 | |
gsfan | 12:057089026a20 | 29 | INFO("httpdFile %d %s", cid, dir); |
gsfan | 12:057089026a20 | 30 | |
gsfan | 12:057089026a20 | 31 | strcpy(file, dir); |
gsfan | 12:057089026a20 | 32 | strcat(file, _httpd[cid].filename); |
gsfan | 12:057089026a20 | 33 | if (file[strlen(file) - 1] == '/') { |
gsfan | 12:057089026a20 | 34 | strcat(file, "index.html"); |
gsfan | 12:057089026a20 | 35 | } |
gsfan | 12:057089026a20 | 36 | DBG("file: %s\r\n", file); |
gsfan | 12:057089026a20 | 37 | |
gsfan | 12:057089026a20 | 38 | fp = fopen(file, "r"); |
gsfan | 12:057089026a20 | 39 | if (fp) { |
gsfan | 12:057089026a20 | 40 | strcpy(buf, "HTTP/1.1 200 OK\r\n"); |
gsfan | 12:057089026a20 | 41 | send(cid, buf, strlen(buf)); |
gsfan | 12:057089026a20 | 42 | { |
gsfan | 12:057089026a20 | 43 | // file size |
gsfan | 12:057089026a20 | 44 | i = ftell(fp); |
gsfan | 12:057089026a20 | 45 | fseek(fp, 0, SEEK_END); |
gsfan | 12:057089026a20 | 46 | len = ftell(fp); |
gsfan | 12:057089026a20 | 47 | fseek(fp, i, SEEK_SET); |
gsfan | 12:057089026a20 | 48 | } |
gsfan | 12:057089026a20 | 49 | |
gsfan | 12:057089026a20 | 50 | strcpy(buf, "Server: GSwifi httpd\r\n"); |
gsfan | 12:057089026a20 | 51 | send(cid, buf, strlen(buf)); |
gsfan | 12:057089026a20 | 52 | if (_httpd[cid].keepalive) { |
gsfan | 12:057089026a20 | 53 | strcpy(buf, "Connection: Keep-Alive\r\n"); |
gsfan | 12:057089026a20 | 54 | } else { |
gsfan | 12:057089026a20 | 55 | strcpy(buf, "Connection: close\r\n"); |
gsfan | 12:057089026a20 | 56 | } |
gsfan | 12:057089026a20 | 57 | send(cid, buf, strlen(buf)); |
gsfan | 12:057089026a20 | 58 | sprintf(buf, "Content-Type: %s\r\n", mimetype(file)); |
gsfan | 12:057089026a20 | 59 | send(cid, buf, strlen(buf)); |
gsfan | 12:057089026a20 | 60 | sprintf(buf, "Content-Length: %d\r\n\r\n", len); |
gsfan | 12:057089026a20 | 61 | send(cid, buf, strlen(buf)); |
gsfan | 12:057089026a20 | 62 | |
gsfan | 12:057089026a20 | 63 | for (;;) { |
gsfan | 12:057089026a20 | 64 | i = fread(buf, sizeof(char), sizeof(buf), fp); |
gsfan | 12:057089026a20 | 65 | if (i <= 0) break; |
gsfan | 12:057089026a20 | 66 | send(cid, buf, i); |
gsfan | 12:057089026a20 | 67 | #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) |
gsfan | 12:057089026a20 | 68 | if (feof(fp)) break; |
gsfan | 12:057089026a20 | 69 | #endif |
gsfan | 12:057089026a20 | 70 | } |
gsfan | 12:057089026a20 | 71 | fclose(fp); |
gsfan | 12:057089026a20 | 72 | return 0; |
gsfan | 12:057089026a20 | 73 | } |
gsfan | 12:057089026a20 | 74 | |
gsfan | 12:057089026a20 | 75 | httpdError(cid, 404); |
gsfan | 12:057089026a20 | 76 | return -1; |
gsfan | 12:057089026a20 | 77 | } |
gsfan | 12:057089026a20 | 78 | |
gsfan | 12:057089026a20 | 79 | void GSwifi::httpdError (int cid, int err) { |
gsfan | 12:057089026a20 | 80 | char buf[CFG_CMD_SIZE], msg[30]; |
gsfan | 12:057089026a20 | 81 | |
gsfan | 12:057089026a20 | 82 | switch (err) { |
gsfan | 12:057089026a20 | 83 | case 400: |
gsfan | 12:057089026a20 | 84 | strcpy(msg, "Bad Request"); |
gsfan | 12:057089026a20 | 85 | break; |
gsfan | 12:057089026a20 | 86 | case 403: |
gsfan | 12:057089026a20 | 87 | strcpy(msg, "Forbidden"); |
gsfan | 12:057089026a20 | 88 | break; |
gsfan | 12:057089026a20 | 89 | case 404: |
gsfan | 12:057089026a20 | 90 | strcpy(msg, "Not Found"); |
gsfan | 12:057089026a20 | 91 | break; |
gsfan | 12:057089026a20 | 92 | case 500: |
gsfan | 12:057089026a20 | 93 | default: |
gsfan | 12:057089026a20 | 94 | strcpy(msg, "Internal Server Error"); |
gsfan | 12:057089026a20 | 95 | break; |
gsfan | 12:057089026a20 | 96 | } |
gsfan | 12:057089026a20 | 97 | DBG("httpd error: %d %d %s\r\n", cid, err, msg); |
gsfan | 12:057089026a20 | 98 | |
gsfan | 12:057089026a20 | 99 | sprintf(buf, "HTTP/1.1 %d %s\r\n", err, msg); |
gsfan | 12:057089026a20 | 100 | send(cid, buf, strlen(buf)); |
gsfan | 12:057089026a20 | 101 | strcpy(buf, "Content-Type: text/html\r\n\r\n"); |
gsfan | 12:057089026a20 | 102 | send(cid, buf, strlen(buf)); |
gsfan | 12:057089026a20 | 103 | |
gsfan | 12:057089026a20 | 104 | sprintf(buf, "<html><head><title>%d %s</title></head>\r\n", err, msg); |
gsfan | 12:057089026a20 | 105 | send(cid, buf, strlen(buf)); |
gsfan | 12:057089026a20 | 106 | sprintf(buf, "<body><h1>%s</h1></body></html>\r\n", msg); |
gsfan | 12:057089026a20 | 107 | send(cid, buf, strlen(buf)); |
gsfan | 12:057089026a20 | 108 | wait_ms(100); |
gsfan | 12:057089026a20 | 109 | close(cid); |
gsfan | 12:057089026a20 | 110 | // 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]); |
gsfan | 12:057089026a20 | 111 | // WARN("%s %s %d %d -\r\n", _httpd[cid].type == GSPROT_HTTPGET ? "GET" : "POST", _httpd[cid].uri, _httpd[cid].length, err); |
gsfan | 12:057089026a20 | 112 | } |
gsfan | 12:057089026a20 | 113 | |
gsfan | 12:057089026a20 | 114 | int GSwifi::httpdGetHandler (const char *uri) { |
gsfan | 12:057089026a20 | 115 | int i; |
gsfan | 12:057089026a20 | 116 | |
gsfan | 12:057089026a20 | 117 | for (i = 0; i < _handler_count; i ++) { |
gsfan | 12:057089026a20 | 118 | if (strncmp(uri, _httpd_handler[i].uri, strlen(_httpd_handler[i].uri)) == NULL) { |
gsfan | 12:057089026a20 | 119 | // found |
gsfan | 12:057089026a20 | 120 | return i; |
gsfan | 12:057089026a20 | 121 | } |
gsfan | 12:057089026a20 | 122 | } |
gsfan | 12:057089026a20 | 123 | return -1; |
gsfan | 12:057089026a20 | 124 | } |
gsfan | 12:057089026a20 | 125 | |
gsfan | 12:057089026a20 | 126 | int GSwifi::httpdAttach (const char *uri, const char *dir) { |
gsfan | 12:057089026a20 | 127 | if (_handler_count < CFG_HTTPD_HANDLER_NUM) { |
gsfan | 12:057089026a20 | 128 | _httpd_handler[_handler_count].uri = (char*)malloc(strlen(uri) + 1); |
gsfan | 12:057089026a20 | 129 | strcpy(_httpd_handler[_handler_count].uri, uri); |
gsfan | 12:057089026a20 | 130 | _httpd_handler[_handler_count].dir = (char*)malloc(strlen(dir) + 1); |
gsfan | 12:057089026a20 | 131 | strcpy(_httpd_handler[_handler_count].dir, dir); |
gsfan | 12:057089026a20 | 132 | _httpd_handler[_handler_count].func = NULL; |
gsfan | 15:086d1a33a197 | 133 | _httpd_handler[_handler_count].ws = 0; |
gsfan | 12:057089026a20 | 134 | DBG("httpdAttach %s %s\r\n", _httpd_handler[_handler_count].uri, _httpd_handler[_handler_count].dir); |
gsfan | 12:057089026a20 | 135 | _handler_count ++; |
gsfan | 12:057089026a20 | 136 | return 0; |
gsfan | 12:057089026a20 | 137 | } else { |
gsfan | 12:057089026a20 | 138 | return -1; |
gsfan | 12:057089026a20 | 139 | } |
gsfan | 12:057089026a20 | 140 | } |
gsfan | 12:057089026a20 | 141 | |
gsfan | 15:086d1a33a197 | 142 | int GSwifi::httpdAttach (const char *uri, void (*funcCgi)(int), int ws) { |
gsfan | 12:057089026a20 | 143 | if (_handler_count < CFG_HTTPD_HANDLER_NUM) { |
gsfan | 12:057089026a20 | 144 | _httpd_handler[_handler_count].uri = (char*)malloc(strlen(uri) + 1); |
gsfan | 12:057089026a20 | 145 | strcpy(_httpd_handler[_handler_count].uri, uri); |
gsfan | 12:057089026a20 | 146 | _httpd_handler[_handler_count].dir = NULL; |
gsfan | 12:057089026a20 | 147 | _httpd_handler[_handler_count].func = funcCgi; |
gsfan | 15:086d1a33a197 | 148 | _httpd_handler[_handler_count].ws = ws; |
gsfan | 12:057089026a20 | 149 | DBG("httpdAttach %s %08x\r\n", _httpd_handler[_handler_count].uri, _httpd_handler[_handler_count].func); |
gsfan | 12:057089026a20 | 150 | _handler_count ++; |
gsfan | 12:057089026a20 | 151 | return 0; |
gsfan | 12:057089026a20 | 152 | } else { |
gsfan | 12:057089026a20 | 153 | return -1; |
gsfan | 12:057089026a20 | 154 | } |
gsfan | 12:057089026a20 | 155 | } |
gsfan | 12:057089026a20 | 156 | |
gsfan | 15:086d1a33a197 | 157 | const char *GSwifi::httpdGetFilename (int cid) { |
gsfan | 15:086d1a33a197 | 158 | return _httpd[cid].filename; |
gsfan | 15:086d1a33a197 | 159 | } |
gsfan | 15:086d1a33a197 | 160 | |
gsfan | 15:086d1a33a197 | 161 | const char *GSwifi::httpdGetQuerystring (int cid) { |
gsfan | 15:086d1a33a197 | 162 | return _httpd[cid].querystring; |
gsfan | 15:086d1a33a197 | 163 | } |
gsfan | 12:057089026a20 | 164 | |
gsfan | 12:057089026a20 | 165 | #define MIMETABLE_NUM 9 |
gsfan | 12:057089026a20 | 166 | char *GSwifi::mimetype (char *file) { |
gsfan | 12:057089026a20 | 167 | static const struct MIMETABLE { |
gsfan | 12:057089026a20 | 168 | const char ext[5]; |
gsfan | 12:057089026a20 | 169 | const char type[24]; |
gsfan | 12:057089026a20 | 170 | } mimetable[MIMETABLE_NUM] = { |
gsfan | 12:057089026a20 | 171 | {"txt", "text/plain"}, // default |
gsfan | 12:057089026a20 | 172 | {"html", "text/html"}, |
gsfan | 12:057089026a20 | 173 | {"htm", "text/html"}, |
gsfan | 12:057089026a20 | 174 | {"css", "text/css"}, |
gsfan | 12:057089026a20 | 175 | {"js", "application/javascript"}, |
gsfan | 12:057089026a20 | 176 | {"jpg", "image/jpeg"}, |
gsfan | 12:057089026a20 | 177 | {"png", "image/png"}, |
gsfan | 12:057089026a20 | 178 | {"gif", "image/gif"}, |
gsfan | 12:057089026a20 | 179 | {"ico", "image/x-icon"}, |
gsfan | 12:057089026a20 | 180 | }; |
gsfan | 12:057089026a20 | 181 | int i, j; |
gsfan | 12:057089026a20 | 182 | |
gsfan | 12:057089026a20 | 183 | for (i = 0; i < MIMETABLE_NUM; i ++) { |
gsfan | 12:057089026a20 | 184 | j = strlen(mimetable[i].ext); |
gsfan | 12:057089026a20 | 185 | if (file[strlen(file) - j - 1] == '.' && |
gsfan | 12:057089026a20 | 186 | strnicmp(&file[strlen(file) - j], mimetable[i].ext, j) == NULL) { |
gsfan | 12:057089026a20 | 187 | return (char*)mimetable[i].type; |
gsfan | 12:057089026a20 | 188 | } |
gsfan | 12:057089026a20 | 189 | } |
gsfan | 12:057089026a20 | 190 | return (char*)mimetable[0].type; |
gsfan | 12:057089026a20 | 191 | } |
gsfan | 12:057089026a20 | 192 | |
gsfan | 12:057089026a20 | 193 | int GSwifi::strnicmp (const char *p1, const char *p2, int n) { |
gsfan | 12:057089026a20 | 194 | int i, r = -1; |
gsfan | 12:057089026a20 | 195 | char c1, c2; |
gsfan | 12:057089026a20 | 196 | |
gsfan | 12:057089026a20 | 197 | for (i = 0; i < n; i ++) { |
gsfan | 12:057089026a20 | 198 | c1 = (p1[i] >= 'a' && p1[i] <= 'z') ? p1[i] - ('a' - 'A'): p1[i]; |
gsfan | 12:057089026a20 | 199 | c2 = (p2[i] >= 'a' && p2[i] <= 'z') ? p2[i] - ('a' - 'A'): p2[i]; |
gsfan | 12:057089026a20 | 200 | r = c1 - c2; |
gsfan | 12:057089026a20 | 201 | if (r) break; |
gsfan | 12:057089026a20 | 202 | } |
gsfan | 12:057089026a20 | 203 | return r; |
gsfan | 12:057089026a20 | 204 | } |
gsfan | 12:057089026a20 | 205 | #endif |