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
GSwifi_httpd.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::httpd (int port) { 00024 int i; 00025 00026 if (!isAssociated() || _state.status != STAT_READY) return -1; 00027 00028 memset(&_httpd, 0, sizeof(_httpd)); 00029 for (i = 0; i < CFG_MAX_SOCKETS; i ++) { 00030 _httpd[i].mode = HTTPDMODE_REQUEST; 00031 _httpd[i].buf = _con[i].buf; 00032 } 00033 #ifdef CFG_ENABLE_RTOS 00034 #ifdef CFG_EXTENDED_MEMORY2 00035 int n = CFG_EXTENDED_SIZE2 / CFG_MAX_SOCKETS; 00036 for (i = 0; i < CFG_MAX_SOCKETS; i ++) { 00037 _httpd[i].uri = (char*)(CFG_EXTENDED_MEMORY2 + (n * i)); 00038 #ifdef CFG_ENABLE_RTOS 00039 _httpd[i].websocket_key = (char*)malloc(30); 00040 #endif 00041 } 00042 #else // CFG_EXTENDED_MEMORY 00043 for (i = 0; i < CFG_MAX_SOCKETS; i ++) { 00044 _httpd[i].uri = (char*)malloc(CFG_CMD_SIZE); 00045 #ifdef CFG_ENABLE_RTOS 00046 _httpd[i].websocket_key = (char*)malloc(30); 00047 #endif 00048 } 00049 #endif // CFG_EXTENDED_MEMORY 00050 #endif 00051 _handler_count = 0; 00052 00053 _httpd_cid = listen(PROTO_TCP, port); 00054 if (_httpd_cid < 0) return -1; 00055 00056 _con[_httpd_cid].protocol = PROTO_HTTPD; 00057 return _httpd_cid; 00058 } 00059 00060 void GSwifi::httpdRecvData (int cid, char c) { 00061 00062 switch (_httpd[cid].mode) { 00063 case HTTPDMODE_REQUEST: 00064 #ifndef CFG_ENABLE_RTOS 00065 if (_con[cid].buf == NULL) { 00066 _con[cid].buf = new CircBuffer<char>(CFG_DATA_SIZE); 00067 } 00068 #endif 00069 _httpd[cid].buf = _con[cid].buf; 00070 if (_httpd[cid].buf != NULL) { 00071 _httpd[cid].buf->flush(); 00072 } 00073 _httpd[cid].keepalive = 0; 00074 if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) { 00075 if (_httpd[cid].buf != NULL) { 00076 _httpd[cid].buf->queue(c); 00077 } 00078 _httpd[cid].mode = HTTPDMODE_REQUEST_STR; 00079 } 00080 break; 00081 case HTTPDMODE_REQUEST_STR: 00082 switch (c) { 00083 case 0: 00084 case 0x0d: // CR 00085 break; 00086 case 0x0a: // LF 00087 if (httpdParseRequest(cid)) { 00088 _httpd[cid].mode = HTTPDMODE_REQUEST_STR; 00089 } else { 00090 _httpd[cid].mode = HTTPDMODE_HEADER; 00091 } 00092 _httpd[cid].enter = 0; 00093 break; 00094 default: 00095 if (_httpd[cid].buf != NULL) { 00096 _httpd[cid].buf->queue(c); 00097 } 00098 break; 00099 } 00100 break; 00101 case HTTPDMODE_HEADER: 00102 switch (c) { 00103 case 0: 00104 case 0x0d: // CR 00105 break; 00106 case 0x0a: // LF 00107 // if (_httpd[cid].buf != NULL && _httpd[cid].buf->available() == 0) { 00108 // if ((_httpd[cid].enter == 0x0d && c == 0x0a) || (_httpd[cid].enter == 0x0a && c == 0x0a)) { 00109 if (_httpd[cid].enter == 0x0a && c == 0x0a) { 00110 if (_httpd[cid].buf != NULL) { 00111 _httpd[cid].buf->flush(); 00112 } 00113 #ifdef CFG_ENABLE_WEBSOCKET 00114 if (_httpd[cid].websocket) { 00115 INFO("MODE_WEBSOCKET_BEGIN"); 00116 _httpd[cid].mode = HTTPDMODE_WEBSOCKET_BEGIN; 00117 } else 00118 #endif 00119 if (_httpd[cid].length) { 00120 INFO("MODE_BODY"); 00121 _httpd[cid].mode = HTTPDMODE_BODY; 00122 } else { 00123 INFO("MODE_ENTER"); 00124 _httpd[cid].mode = HTTPDMODE_ENTER; 00125 _con[cid].received = true; 00126 } 00127 } 00128 // break; 00129 // } 00130 00131 _httpd[cid].enter = c; 00132 httpdParseHeader(cid); 00133 break; 00134 default: 00135 if (_httpd[cid].buf != NULL) { 00136 _httpd[cid].buf->queue(c); 00137 } 00138 _httpd[cid].enter = 0; 00139 break; 00140 } 00141 break; 00142 case HTTPDMODE_BODY: 00143 if (_httpd[cid].buf != NULL) { 00144 _httpd[cid].buf->queue(c); 00145 if (_httpd[cid].buf->available() >= _httpd[cid].length) { 00146 _httpd[cid].mode = HTTPDMODE_ENTER; 00147 _con[cid].received = true; 00148 } 00149 } 00150 break; 00151 #ifdef CFG_ENABLE_WEBSOCKET 00152 case HTTPDMODE_WEBSOCKET: 00153 case HTTPDMODE_WEBSOCKET_MASK: 00154 case HTTPDMODE_WEBSOCKET_BODY: 00155 wsRecvData(cid, c); 00156 break; 00157 #endif 00158 } 00159 } 00160 00161 void GSwifi::httpdPoll () { 00162 for (int cid = 0; cid < 16; cid ++) { 00163 if (isConnected(cid) && _con[cid].protocol == PROTO_HTTPD) { 00164 00165 if (_httpd[cid].mode == HTTPDMODE_ENTER) { 00166 int i = httpdGetHandler(_httpd[cid].uri); 00167 if (i >= 0) { 00168 if (_httpd_handler[i].dir) { 00169 // file 00170 httpdFile(cid, _httpd_handler[i].dir); 00171 } else 00172 if (_httpd_handler[i].func && !_httpd_handler[i].ws) { 00173 // cgi 00174 _httpd_handler[i].func(cid); 00175 // _httpd[cid].keepalive = 0; 00176 } else { 00177 httpdError(cid, 403); 00178 } 00179 } else { 00180 httpdError(cid, 404); 00181 } 00182 00183 if (_httpd[cid].keepalive) { 00184 DBG("keepalive %d", _httpd[cid].keepalive); 00185 _httpd[cid].keepalive --; 00186 } else { 00187 close(cid); 00188 } 00189 _httpd[cid].mode = HTTPDMODE_REQUEST; 00190 #ifdef CFG_ENABLE_WEBSOCKET 00191 } else 00192 if (_httpd[cid].mode == HTTPDMODE_WEBSOCKET_BEGIN) { 00193 wsAccept(cid); 00194 _httpd[cid].mode = HTTPDMODE_WEBSOCKET; 00195 } else 00196 if (_httpd[cid].mode == HTTPDMODE_WEBSOCKET_ENTER) { 00197 wsParseRequest(cid); 00198 _httpd[cid].mode = HTTPDMODE_WEBSOCKET; 00199 #endif 00200 } 00201 00202 } // PROTO_HTTPD 00203 } // for 00204 } 00205 00206 int GSwifi::httpdParseRequest (int cid) { 00207 int i, j, len; 00208 char buf[CFG_CMD_SIZE]; 00209 00210 if (_httpd[cid].buf == NULL) return 0; 00211 for (len = 0; len < sizeof(buf); len++) { 00212 if (_httpd[cid].buf->dequeue(&buf[len]) == false) break; 00213 } 00214 buf[len] = 0; 00215 00216 if (strnicmp(buf, "GET ", 4) == 0) { 00217 _httpd[cid].req = REQ_HTTPGET; 00218 j = 4; 00219 } else 00220 if (strnicmp(buf, "POST ", 5) == 0) { 00221 _httpd[cid].req = REQ_HTTPPOST; 00222 j = 5; 00223 } else { 00224 return -1; 00225 } 00226 #ifndef CFG_ENABLE_RTOS 00227 if (_httpd[cid].uri == NULL) 00228 _httpd[cid].uri = (char*)malloc(CFG_CMD_SIZE); 00229 #endif 00230 for (i = 0; i < len - j; i ++) { 00231 _httpd[cid].uri[i] = buf[i + j]; 00232 if (buf[i + j] == ' ' || i >= CFG_CMD_SIZE - 1) { 00233 _httpd[cid].uri[i] = 0; 00234 INFO("URI %d '%s'", _httpd[cid].req, _httpd[cid].uri); 00235 _httpd[cid].mode = HTTPDMODE_HEADER; 00236 if (_httpd[cid].buf != NULL) { 00237 _httpd[cid].buf->flush(); 00238 } 00239 _httpd[cid].length = 0; 00240 _httpd[cid].n = 0; 00241 _httpd[cid].filename = NULL; 00242 _httpd[cid].querystring = NULL; 00243 #ifdef CFG_ENABLE_WEBSOCKET 00244 _httpd[cid].websocket = 0; 00245 #endif 00246 break; 00247 } 00248 } 00249 00250 i = httpdGetHandler(_httpd[cid].uri); 00251 if (i >= 0) { 00252 _httpd[cid].filename = &_httpd[cid].uri[strlen(_httpd_handler[i].uri)]; 00253 for (i = 0; i < strlen(_httpd[cid].filename); i ++) { 00254 if (_httpd[cid].filename[i] == '?') { 00255 _httpd[cid].filename[i] = 0; 00256 _httpd[cid].querystring = _httpd[cid].filename + i + 1; 00257 break; 00258 } 00259 } 00260 INFO("FILE '%s' QUERY '%s'", _httpd[cid].filename, _httpd[cid].querystring); 00261 } 00262 return 0; 00263 } 00264 00265 #define HEADER_TABLE_NUM 5 00266 int GSwifi::httpdParseHeader (int cid) { 00267 int i; 00268 char buf[CFG_CMD_SIZE]; 00269 static const struct HEADER_TABLE { 00270 const char header[24]; 00271 void (GSwifi::*func)(int id, const char*); 00272 } header_table[HEADER_TABLE_NUM] = { 00273 {"Content-Length:", &GSwifi::reqContentLength}, 00274 {"Connection:", &GSwifi::reqConnection}, 00275 {"Upgrade: websocket", &GSwifi::reqUpgrade}, 00276 {"Sec-WebSocket-Version:", &GSwifi::reqWebSocketVersion}, 00277 {"Sec-WebSocket-Key:", &GSwifi::reqWebSocketKey}, 00278 }; 00279 00280 if (_httpd[cid].buf == NULL) return 0; 00281 for (i = 0; i < sizeof(buf); i++) { 00282 if (_httpd[cid].buf->dequeue(&buf[i]) == false) break; 00283 } 00284 buf[i] = 0; 00285 00286 for (i = 0; i < HEADER_TABLE_NUM; i ++) { 00287 if (strnicmp(buf, header_table[i].header, strlen(header_table[i].header)) == 0) { 00288 DBG("parse header %d '%s'\r\n", i, buf); 00289 if (header_table[i].func != NULL) { 00290 (this->*(header_table[i].func))(cid, buf); 00291 } 00292 return 0; 00293 } 00294 } 00295 00296 return -1; 00297 } 00298 00299 void GSwifi::reqContentLength (int cid, const char *buf) { 00300 _httpd[cid].length = atoi(&buf[16]); 00301 } 00302 00303 void GSwifi::reqConnection (int cid, const char *buf) { 00304 if (strnicmp(&buf[12], "Keep-Alive", 10) == 0) { 00305 if (_httpd[cid].keepalive == 0) 00306 _httpd[cid].keepalive = CFG_HTTPD_KEEPALIVE; 00307 } else { 00308 _httpd[cid].keepalive = 0; 00309 } 00310 } 00311 00312 #ifdef CFG_ENABLE_WEBSOCKET 00313 void GSwifi::reqUpgrade (int cid, const char *buf) { 00314 if (! _httpd[cid].websocket) _httpd[cid].websocket = 1; 00315 } 00316 00317 void GSwifi::reqWebSocketVersion (int cid, const char *buf) { 00318 _httpd[cid].websocket = atoi(&buf[23]); 00319 } 00320 00321 void GSwifi::reqWebSocketKey (int cid, const char *buf) { 00322 #ifndef CFG_ENABLE_RTOS 00323 if (_httpd[cid].websocket_key == NULL) { 00324 _httpd[cid].websocket_key = (char*)malloc(30); 00325 } 00326 #endif 00327 strncpy(_httpd[cid].websocket_key, &buf[19], 30); 00328 } 00329 #else 00330 void GSwifi::reqUpgrade (int cid, const char *buf) { 00331 } 00332 void GSwifi::reqWebSocketVersion (int cid, const char *buf) { 00333 } 00334 void GSwifi::reqWebSocketKey (int cid, const char *buf) { 00335 } 00336 #endif 00337 00338 #endif
Generated on Thu Jul 14 2022 07:53:37 by 1.7.2