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.
Dependents: coap-example Borsch coap-example
Fork of NetworkServices by
HTTPD.cpp
00001 /* Copyright (C) 2013 Hiroshi Suga, 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 "HTTPD.h" 00020 00021 HTTPD * HTTPD::_inst; 00022 00023 HTTPD::HTTPD () { 00024 _inst = this; 00025 memset(_state, 0, sizeof(_state)); 00026 _handler_count = 0; 00027 } 00028 00029 int HTTPD::start (NetworkStack *ns, int port) { 00030 int i; 00031 00032 m_ns = ns; 00033 00034 for (i = 0; i < HTTPD_MAX_CLIENTS; i ++) { 00035 _state[i].buf = new CircBuffer<char>(HTTPD_BUF_SIZE); 00036 _state[i].thread = new Thread(osPriorityNormal, HTTPD_STACK_SIZE); 00037 _state[i].client = new TCPSocket(); 00038 _state[i].thread->start(callback(child, (void*)i)); 00039 } 00040 00041 #ifdef HTTPD_ENABLE_CLOSER 00042 _state[HTTPD_MAX_CLIENTS].thread = new Thread(closer, (void*)HTTPD_MAX_CLIENTS, osPriorityNormal, 128); 00043 _state[HTTPD_MAX_CLIENTS].client = new TCPSocket(m_ns); 00044 #endif 00045 00046 _server.open(m_ns); 00047 _server.bind(port); 00048 _server.set_blocking(true); 00049 _server.listen(); 00050 _daemon = new Thread(osPriorityNormal, HTTPD_STACK_SIZE); 00051 _daemon->start(HTTPD::daemon); 00052 return 0; 00053 } 00054 00055 void HTTPD::daemon () { 00056 HTTPD *httpd = HTTPD::getInstance(); 00057 int i, t = 0; 00058 00059 INFO("Wait for new connection...\r\n"); 00060 for (;;) { 00061 if (t >= 0) { 00062 if (httpd->_server.accept(httpd->_state[t].client) == 0) { 00063 INFO("accept %d\r\n", t); 00064 httpd->_state[t].thread->signal_set(1); 00065 } 00066 } else { 00067 #ifdef HTTPD_ENABLE_CLOSER 00068 if (httpd->_server.accept(httpd->_state[HTTPD_MAX_CLIENTS].client) == 0) { 00069 INFO("accept x\r\n"); 00070 httpd->_state[HTTPD_MAX_CLIENTS].thread->signal_set(1); 00071 } 00072 #endif 00073 } 00074 00075 t = -1; 00076 for (i = 0; i < HTTPD_MAX_CLIENTS; i ++) { 00077 if (httpd->_state[i].thread->get_state() == Thread::WaitingAnd) { 00078 if (t < 0) t = i; // next empty thread 00079 } 00080 } 00081 } 00082 } 00083 00084 void HTTPD::child (void const *arg) { 00085 HTTPD *httpd = HTTPD::getInstance(); 00086 int id = (int)arg; 00087 int i, n; 00088 char buf[HTTPD_BUF_SIZE]; 00089 00090 for (;;) { 00091 Thread::signal_wait(1); 00092 httpd->_state[id].mode = MODE_REQUEST; 00093 httpd->_state[id].buf->flush(); 00094 httpd->_state[id].keepalive = 0; 00095 INFO("Connection from client\r\n"); 00096 // INFO("Connection from %s\r\n", httpd->_state[id].client->get_ip_address()); 00097 00098 httpd->_state[id].client->set_blocking(false); 00099 httpd->_state[id].client->set_timeout(HTTPD_TIMEOUT); 00100 00101 for (;;) { 00102 //if (! httpd->_state[id].client->is_connected()) break; 00103 00104 n = httpd->_state[id].client->recv(buf, sizeof(buf)); 00105 00106 if (n < 0 ) { 00107 printf("HTTPD::child breaking n = %d\r\n", n); 00108 break; 00109 } 00110 buf[n] = 0; 00111 //DBG("Recv %d ", n); 00112 DBG("Recv %d '%s'", n, buf); 00113 00114 for (i = 0; i < n; i ++) { 00115 httpd->recvData(id, buf[i]); 00116 } 00117 } 00118 00119 httpd->_state[id].client->close(); 00120 INFO("Closed client connection\r\n"); 00121 //INFO("Close %s\r\n", httpd->_state[id].client->get_ip_address()); 00122 } 00123 } 00124 00125 void HTTPD::closer (void const *arg) { 00126 HTTPD *httpd = HTTPD::getInstance(); 00127 int id = (int)arg; 00128 00129 for (;;) { 00130 Thread::signal_wait(1); 00131 00132 httpd->_state[id].client->close(); 00133 INFO("Closed client connection\r\n"); 00134 //INFO("Close %s\r\n", httpd->_state[id].client->get_ip_address()); 00135 } 00136 } 00137
Generated on Fri Jul 15 2022 01:11:07 by
1.7.2
