GSwifiInterface library (interface for GainSpan Wi-Fi GS1011 modules) Please see https://mbed.org/users/gsfan/notebook/GSwifiInterface/

Dependents:   GSwifiInterface_HelloWorld GSwifiInterface_HelloServo GSwifiInterface_UDPEchoServer GSwifiInterface_UDPEchoClient ... more

Fork of WiflyInterface by mbed official

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers GSwifi_httpd_util.cpp Source File

GSwifi_httpd_util.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 
00019 #include "GSwifi.h"
00020 
00021 #ifdef CFG_ENABLE_HTTPD
00022 
00023 int GSwifi::httpdFile (int cid, char *dir) {
00024     FILE *fp;
00025     int i, len;
00026     char buf[256];
00027     char file[80];
00028 
00029     INFO("httpdFile %d %s", cid, dir);
00030 
00031     strcpy(file, dir);
00032     strncat(file, _httpd[cid].filename, sizeof(file) - strlen(file) - 1);
00033     if (file[strlen(file) - 1] == '/') {
00034         strncat(file, "index.html", sizeof(file) - strlen(file) - 1);
00035     }
00036     DBG("file: %s\r\n", file);
00037 
00038     fp = fopen(file, "r");
00039     if (fp) {
00040         strcpy(buf, "HTTP/1.1 200 OK\r\n");
00041         send(cid, buf, strlen(buf));
00042         {
00043             // file size
00044             i = ftell(fp);
00045             fseek(fp, 0, SEEK_END);
00046             len = ftell(fp);
00047             fseek(fp, i, SEEK_SET);
00048         }
00049 
00050         strcpy(buf, "Server: GSwifi httpd\r\n");
00051         send(cid, buf, strlen(buf));
00052         if (_httpd[cid].keepalive) {
00053             strcpy(buf, "Connection: Keep-Alive\r\n");
00054         } else {
00055             strcpy(buf, "Connection: close\r\n");
00056         }
00057         send(cid, buf, strlen(buf));
00058         sprintf(buf, "Content-Type: %s\r\n", mimetype(file));
00059         send(cid, buf, strlen(buf));
00060         sprintf(buf, "Content-Length: %d\r\n\r\n", len);
00061         send(cid, buf, strlen(buf));
00062 
00063         for (;;) {
00064             i = fread(buf, sizeof(char), sizeof(buf), fp);
00065             if (i <= 0) break;
00066             send(cid, buf, i);
00067 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
00068             if (feof(fp)) break;
00069 #endif
00070         }
00071         fclose(fp);
00072         return 0;
00073     }
00074 
00075     httpdError(cid, 404);
00076     return -1;
00077 }
00078 
00079 void GSwifi::httpdError (int cid, int err) {
00080     char buf[CFG_CMD_SIZE], msg[30];
00081     
00082     switch (err) {
00083     case 400:
00084         strcpy(msg, "Bad Request");
00085         break;
00086     case 403:
00087         strcpy(msg, "Forbidden");
00088         break;
00089     case 404:
00090         strcpy(msg, "Not Found");
00091         break;
00092     case 500:
00093     default:
00094         strcpy(msg, "Internal Server Error");
00095         break;
00096     }
00097     DBG("httpd error: %d %d %s\r\n", cid, err, msg);
00098     
00099     sprintf(buf, "HTTP/1.1 %d %s\r\n", err, msg);
00100     send(cid, buf, strlen(buf));
00101     strcpy(buf, "Content-Type: text/html\r\n\r\n");
00102     send(cid, buf, strlen(buf));
00103 
00104     sprintf(buf, "<html><head><title>%d %s</title></head>\r\n", err, msg);
00105     send(cid, buf, strlen(buf));
00106     sprintf(buf, "<body><h1>%s</h1></body></html>\r\n", msg);
00107     send(cid, buf, strlen(buf));
00108     wait_ms(100);
00109     close(cid);
00110 //    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]);
00111 //    WARN("%s %s %d %d -\r\n", _httpd[cid].type == GSPROT_HTTPGET ? "GET" : "POST", _httpd[cid].uri, _httpd[cid].length, err);
00112 }
00113 
00114 int GSwifi::httpdGetHandler (const char *uri) {
00115     int i;
00116  
00117     for (i = 0; i < _handler_count; i ++) {
00118         if (strncmp(uri, _httpd_handler[i].uri, strlen(_httpd_handler[i].uri)) == NULL) {
00119             // found
00120             return i;
00121         }
00122     }
00123     return -1;
00124 }
00125 
00126 int GSwifi::httpdAttach (const char *uri, const char *dir) {
00127     if (_handler_count < CFG_HTTPD_HANDLER_NUM) {
00128         _httpd_handler[_handler_count].uri = (char*)malloc(strlen(uri) + 1);
00129         strcpy(_httpd_handler[_handler_count].uri, uri);
00130         _httpd_handler[_handler_count].dir = (char*)malloc(strlen(dir) + 1);
00131         strcpy(_httpd_handler[_handler_count].dir, dir);
00132         _httpd_handler[_handler_count].func = NULL;
00133         _httpd_handler[_handler_count].ws = 0;
00134         DBG("httpdAttach %s %s\r\n", _httpd_handler[_handler_count].uri, _httpd_handler[_handler_count].dir);
00135         _handler_count ++;
00136         return 0;
00137     } else {
00138         return -1;
00139     }
00140 }
00141 
00142 int GSwifi::httpdAttach (const char *uri, void (*funcCgi)(int), int ws) {
00143     if (_handler_count < CFG_HTTPD_HANDLER_NUM) {
00144         _httpd_handler[_handler_count].uri = (char*)malloc(strlen(uri) + 1);
00145         strcpy(_httpd_handler[_handler_count].uri, uri);
00146         _httpd_handler[_handler_count].dir = NULL;
00147         _httpd_handler[_handler_count].func = funcCgi;
00148         _httpd_handler[_handler_count].ws = ws;
00149         DBG("httpdAttach %s %08x\r\n", _httpd_handler[_handler_count].uri, _httpd_handler[_handler_count].func);
00150         _handler_count ++;
00151         return 0;
00152     } else {
00153         return -1;
00154     }
00155 }
00156 
00157 const char *GSwifi::httpdGetFilename (int cid) {
00158     return _httpd[cid].filename;
00159 }
00160 
00161 const char *GSwifi::httpdGetQuerystring (int cid) {
00162     return _httpd[cid].querystring;
00163 }
00164 
00165 #define MIMETABLE_NUM 9
00166 char *GSwifi::mimetype (char *file) {
00167     static const struct MIMETABLE {
00168         const char ext[5];
00169         const char type[24];
00170     } mimetable[MIMETABLE_NUM] = {
00171         {"txt", "text/plain"},  // default
00172         {"html", "text/html"},
00173         {"htm", "text/html"},
00174         {"css", "text/css"},
00175         {"js", "application/javascript"},
00176         {"jpg", "image/jpeg"},
00177         {"png", "image/png"},
00178         {"gif", "image/gif"},
00179         {"ico", "image/x-icon"},
00180     };
00181     int i, j;
00182 
00183     for (i = 0; i < MIMETABLE_NUM; i ++) {
00184         j = strlen(mimetable[i].ext);
00185         if (file[strlen(file) - j - 1] == '.' &&
00186           strnicmp(&file[strlen(file) - j], mimetable[i].ext, j) == NULL) {
00187             return (char*)mimetable[i].type;
00188         }
00189     }
00190     return (char*)mimetable[0].type;
00191 }
00192 
00193 int GSwifi::strnicmp (const char *p1, const char *p2, int n) {
00194     int i, r = -1;
00195     char c1, c2;
00196     
00197     for (i = 0; i < n; i ++) {
00198         c1 = (p1[i] >= 'a' && p1[i] <= 'z') ? p1[i] - ('a' - 'A'): p1[i];
00199         c2 = (p2[i] >= 'a' && p2[i] <= 'z') ? p2[i] - ('a' - 'A'): p2[i];
00200         r = c1 - c2;
00201         if (r) break;
00202     }
00203     return r;
00204 }
00205 #endif