Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of HTTPD by
Revision 1:b724fdb741e7, committed 2017-06-15
- Comitter:
- dgriffin65
- Date:
- Thu Jun 15 20:17:24 2017 +0000
- Parent:
- 0:d18dff347122
- Commit message:
- Updated to mbed-os
Changed in this revision
--- a/HTTPD.cpp Wed Nov 13 01:58:04 2013 +0000 +++ b/HTTPD.cpp Thu Jun 15 20:17:24 2017 +0000 @@ -26,39 +26,46 @@ _handler_count = 0; } -int HTTPD::start (int port) { +int HTTPD::start (NetworkStack *ns, int port) { int i; + m_ns = ns; + for (i = 0; i < HTTPD_MAX_CLIENTS; i ++) { _state[i].buf = new CircBuffer<char>(HTTPD_BUF_SIZE); - _state[i].thread = new Thread(child, (void*)i, osPriorityNormal, HTTPD_STACK_SIZE); - _state[i].client = new TCPSocketConnection; + _state[i].thread = new Thread(osPriorityNormal, HTTPD_STACK_SIZE); + _state[i].client = new TCPSocket(); + _state[i].thread->start(callback(child, (void*)i)); } + #ifdef HTTPD_ENABLE_CLOSER _state[HTTPD_MAX_CLIENTS].thread = new Thread(closer, (void*)HTTPD_MAX_CLIENTS, osPriorityNormal, 128); - _state[HTTPD_MAX_CLIENTS].client = new TCPSocketConnection; + _state[HTTPD_MAX_CLIENTS].client = new TCPSocket(m_ns); #endif + _server.open(m_ns); _server.bind(port); + _server.set_blocking(true); _server.listen(); - _daemon = new Thread(daemon, NULL, osPriorityNormal, 256); + _daemon = new Thread(osPriorityNormal, HTTPD_STACK_SIZE); + _daemon->start(HTTPD::daemon); return 0; } -void HTTPD::daemon (void const *args) { +void HTTPD::daemon () { HTTPD *httpd = HTTPD::getInstance(); int i, t = 0; INFO("Wait for new connection...\r\n"); for (;;) { if (t >= 0) { - if (httpd->_server.accept(*httpd->_state[t].client) == 0) { + if (httpd->_server.accept(httpd->_state[t].client) == 0) { INFO("accept %d\r\n", t); httpd->_state[t].thread->signal_set(1); } } else { #ifdef HTTPD_ENABLE_CLOSER - if (httpd->_server.accept(*httpd->_state[HTTPD_MAX_CLIENTS].client) == 0) { + if (httpd->_server.accept(httpd->_state[HTTPD_MAX_CLIENTS].client) == 0) { INFO("accept x\r\n"); httpd->_state[HTTPD_MAX_CLIENTS].thread->signal_set(1); } @@ -82,19 +89,27 @@ for (;;) { Thread::signal_wait(1); - httpd->_state[id].mode = MODE_REQUEST; httpd->_state[id].buf->flush(); httpd->_state[id].keepalive = 0; - INFO("Connection from %s\r\n", httpd->_state[id].client->get_address()); - httpd->_state[id].client->set_blocking(false, HTTPD_TIMEOUT); + INFO("Connection from client\r\n"); +// INFO("Connection from %s\r\n", httpd->_state[id].client->get_ip_address()); + + httpd->_state[id].client->set_blocking(false); + httpd->_state[id].client->set_timeout(HTTPD_TIMEOUT); + for (;;) { - if (! httpd->_state[id].client->is_connected()) break; + //if (! httpd->_state[id].client->is_connected()) break; - n = httpd->_state[id].client->receive(buf, sizeof(buf)); - if (n < 0) break; + n = httpd->_state[id].client->recv(buf, sizeof(buf)); + + if (n < 0 ) { + printf("HTTPD::child breaking n = %d\r\n", n); + break; + } buf[n] = 0; -// DBG("Recv %d '%s'", n, buf); + //DBG("Recv %d ", n); + DBG("Recv %d '%s'", n, buf); for (i = 0; i < n; i ++) { httpd->recvData(id, buf[i]); @@ -102,7 +117,8 @@ } httpd->_state[id].client->close(); - INFO("Close %s\r\n", httpd->_state[id].client->get_address()); + INFO("Closed client connection\r\n"); + //INFO("Close %s\r\n", httpd->_state[id].client->get_ip_address()); } } @@ -114,7 +130,8 @@ Thread::signal_wait(1); httpd->_state[id].client->close(); - INFO("Close %s\r\n", httpd->_state[id].client->get_address()); + INFO("Closed client connection\r\n"); + //INFO("Close %s\r\n", httpd->_state[id].client->get_ip_address()); } }
--- a/HTTPD.h Wed Nov 13 01:58:04 2013 +0000 +++ b/HTTPD.h Thu Jun 15 20:17:24 2017 +0000 @@ -21,13 +21,14 @@ #include "mbed.h" #include "rtos.h" -#include "EthernetInterface.h" +#include "NetworkStack.h" +#include "EthInterface.h" #include "CBuffer.h" -//#define DEBUG +#define DEBUG #define HTTPD_PORT 80 -#define HTTPD_MAX_CLIENTS 2 +#define HTTPD_MAX_CLIENTS 5 #define HTTPD_KEEPALIVE 10 #define HTTPD_TIMEOUT 15000 #define HTTPD_MAX_HANDLES 10 @@ -75,7 +76,7 @@ struct STATE { Thread *thread; - TCPSocketConnection *client; + TCPSocket *client; volatile Request req; volatile Mode mode; CircBuffer <char>*buf; @@ -97,7 +98,7 @@ HTTPD (); - int start (int port = HTTPD_PORT); + int start (NetworkStack *ns, int port = HTTPD_PORT); // --- HTTPD_req.cpp --- void httpdError (int id, int err); @@ -109,7 +110,14 @@ char *getUri (int id); char *getFilename (int id); char *getQueryString (int id); + + TCPSocket *getClientSocket(int id) { + if (id >= HTTPD_MAX_CLIENTS) return NULL; + return _state[id].client; + } int send (int id, const char *body, int len, const char *header = NULL); + int sendstr (int id, const char *buf); + int hprintf(int id, const char* format, ...); int receive (int id, char *buf, int len); int attach (const char *uri, const char *dir); int attach (const char *uri, void (*funcCgi)(int id)); @@ -124,7 +132,9 @@ private : static HTTPD *_inst; Thread *_daemon; - TCPSocketServer _server; + TCPServer _server; + + NetworkStack *m_ns; #ifdef HTTPD_ENABLE_CLOSER struct STATE _state[HTTPD_MAX_CLIENTS + 1]; @@ -140,7 +150,7 @@ int _handler_count; - static void daemon (void const *arg); + static void daemon (); static void child (void const *arg); static void closer (void const *arg);
--- a/HTTPD_req.cpp Wed Nov 13 01:58:04 2013 +0000 +++ b/HTTPD_req.cpp Thu Jun 15 20:17:24 2017 +0000 @@ -37,7 +37,7 @@ fp = fopen(file, "r"); if (fp) { strcpy(buf, "HTTP/1.1 200 OK\r\n"); - _state[id].client->send_all(buf, strlen(buf)); + _state[id].client->send(buf, strlen(buf)); { // file size i = ftell(fp); @@ -47,22 +47,22 @@ } strcpy(buf, "Server: GSwifi httpd\r\n"); - _state[id].client->send_all(buf, strlen(buf)); + _state[id].client->send(buf, strlen(buf)); if (_state[id].keepalive) { strcpy(buf, "Connection: Keep-Alive\r\n"); } else { strcpy(buf, "Connection: close\r\n"); } - _state[id].client->send_all(buf, strlen(buf)); + _state[id].client->send(buf, strlen(buf)); sprintf(buf, "Content-Type: %s\r\n", mimetype(file)); - _state[id].client->send_all(buf, strlen(buf)); + _state[id].client->send(buf, strlen(buf)); sprintf(buf, "Content-Length: %d\r\n\r\n", len); - _state[id].client->send_all(buf, strlen(buf)); + _state[id].client->send(buf, strlen(buf)); for (;;) { i = fread(buf, sizeof(char), sizeof(buf), fp); if (i <= 0) break; - _state[id].client->send_all(buf, i); + _state[id].client->send(buf, i); #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) if (feof(fp)) break; #endif @@ -70,7 +70,7 @@ fclose(fp); return 0; } - + httpdError(id, 404); return -1; } @@ -96,21 +96,20 @@ DBG("httpd error: %d %d %s\r\n", id, err, msg); sprintf(buf, "HTTP/1.1 %d %s\r\n", err, msg); - _state[id].client->send_all(buf, strlen(buf)); + _state[id].client->send(buf, strlen(buf)); strcpy(buf, "Content-Type: text/html\r\n\r\n"); - _state[id].client->send_all(buf, strlen(buf)); + _state[id].client->send(buf, strlen(buf)); sprintf(buf, "<html><head><title>%d %s</title></head>\r\n", err, msg); - _state[id].client->send_all(buf, strlen(buf)); + _state[id].client->send(buf, strlen(buf)); sprintf(buf, "<body><h1>%s</h1></body></html>\r\n", msg); - _state[id].client->send_all(buf, strlen(buf)); + _state[id].client->send(buf, strlen(buf)); wait_ms(100); _state[id].client->close(); -// 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]); -// WARN("%s %s %d %d -\r\n", _httpd[cid].type == GSPROT_HTTPGET ? "GET" : "POST", _httpd[cid].uri, _httpd[cid].length, err); + //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]); + //WARN("%s %s %d %d -\r\n", _httpd[cid].type == GSPROT_HTTPGET ? "GET" : "POST", _httpd[cid].uri, _httpd[cid].length, err); } - void HTTPD::recvData (int id, char c) { switch (_state[id].mode) { @@ -192,15 +191,15 @@ if (_state[id].mode == MODE_ENTER) { int i = getHandler(_state[id].uri); + printf("handler = %d, uri = %s\r\n", i, _state[id].uri); if (i >= 0) { if (_handler[i].dir) { // file httpdFile(id, _handler[i].dir); - } else - if (_handler[i].funcCgi) { + } else if (_handler[i].funcCgi) { // cgi _handler[i].funcCgi(id); -// _state[id].keepalive = 0; + _state[id].keepalive = 0; } else { httpdError(id, 403); } @@ -210,7 +209,7 @@ if (_state[id].keepalive) { DBG("keepalive %d", _state[id].keepalive); - _state[id].keepalive --; + _state[id].keepalive--; } else { _state[id].client->close(); }
--- a/HTTPD_util.cpp Wed Nov 13 01:58:04 2013 +0000 +++ b/HTTPD_util.cpp Thu Jun 15 20:17:24 2017 +0000 @@ -62,22 +62,46 @@ char buf[HTTPD_CMD_SIZE]; strcpy(buf, "HTTP/1.1 200 OK\r\n"); - _state[id].client->send_all(buf, strlen(buf)); + _state[id].client->send(buf, strlen(buf)); strcpy(buf, "Server: GSwifi httpd\r\n"); - _state[id].client->send_all(buf, strlen(buf)); + _state[id].client->send(buf, strlen(buf)); if (_state[id].keepalive) { strcpy(buf, "Connection: Keep-Alive\r\n"); } else { strcpy(buf, "Connection: close\r\n"); } - _state[id].client->send_all(buf, strlen(buf)); + _state[id].client->send(buf, strlen(buf)); if (header) { - _state[id].client->send_all((char*)header, strlen(header)); + _state[id].client->send((char*)header, strlen(header)); } sprintf(buf, "Content-Length: %d\r\n\r\n", len); - _state[id].client->send_all(buf, strlen(buf)); + _state[id].client->send(buf, strlen(buf)); + + return _state[id].client->send((char*)body, len); +} + +int HTTPD::sendstr (int id, const char *buf) { + return _state[id].client->send((char*)buf, strlen(buf)); +} + - return _state[id].client->send_all((char*)body, len); +int HTTPD::hprintf(int id, const char* format, ...) { + //FIX ME: This could result in memory overruns if the buffer size is exceeded + static Mutex _mtx; + static char _buf[1024]; + + std::va_list arg; + + _mtx.lock(); + + va_start(arg, format); + vsprintf(_buf, format, arg); + va_end(arg); + + int r = _state[id].client->send(_buf, strlen(_buf)); + + _mtx.unlock(); + return r; } int HTTPD::getHandler (const char *uri) {
--- a/HTTPD_ws.cpp Wed Nov 13 01:58:04 2013 +0000 +++ b/HTTPD_ws.cpp Thu Jun 15 20:17:24 2017 +0000 @@ -124,7 +124,7 @@ for (i = 0; i < _state[id].length; i ++) { if (_state[id].buf->dequeue(&pong[i + 2]) == false) break; } - _state[id].client->send_all(pong, _state[id].length + 2); + _state[id].client->send(pong, _state[id].length + 2); } break; case 0x0a: // pong @@ -143,22 +143,22 @@ DBG("websocket accept: %d\r\n", id); strcpy(buf, "HTTP/1.1 101 Switching Protocols\r\n"); - _state[id].client->send_all(buf, strlen(buf)); + _state[id].client->send(buf, strlen(buf)); strcpy(buf, "Upgrade: websocket\r\n"); - _state[id].client->send_all(buf, strlen(buf)); + _state[id].client->send(buf, strlen(buf)); strcpy(buf, "Connection: Upgrade\r\n"); - _state[id].client->send_all(buf, strlen(buf)); + _state[id].client->send(buf, strlen(buf)); strcpy(buf, "Sec-WebSocket-Accept: "); - _state[id].client->send_all(buf, strlen(buf)); + _state[id].client->send(buf, strlen(buf)); strcpy(buf, _state[id].websocket_key); strcat(buf, "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); sha1(buf, strlen(buf), buf2); base64encode(buf2, 20, buf, sizeof(buf)); - _state[id].client->send_all(buf, strlen(buf)); + _state[id].client->send(buf, strlen(buf)); strcpy(buf, "\r\n\r\n"); - _state[id].client->send_all(buf, strlen(buf)); - _state[id].client->set_blocking(true, HTTPD_TIMEOUT * 100); + _state[id].client->send(buf, strlen(buf)); + //_state[id].client->set_blocking(true, HTTPD_TIMEOUT * 100); return 0; } @@ -179,7 +179,7 @@ memcpy(&tmp[i], mask, 4); i += 4; } - r = httpd->_state[id].client->send_all(tmp, i); + r = httpd->_state[id].client->send(tmp, i); if (r >= 0) { if (mask) { @@ -187,9 +187,9 @@ for (i = 0; i < len; i ++) { tmp2[i] = buf[i] ^ mask[i & 0x03]; } - r = httpd->_state[id].client->send_all(tmp2, len); + r = httpd->_state[id].client->send(tmp2, len); } else { - r = httpd->_state[id].client->send_all((char*)buf, len); + r = httpd->_state[id].client->send((char*)buf, len); } } return r;