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: mbed_controller_demo
Fork of HTTPD 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 /* 00022 // There was hald fault error of HTTPD with Seeed Arch Max platform 00023 // because of stack overwritten. 00024 // According to the Callgraph report of Keil MDK 4.1, 00025 // the Max Depth is 424 bytes. 00026 HTTPD::daemon(const void*) (Thumb, 110 bytes, Stack size 0 bytes, httpd.o(.text)) 00027 00028 [Stack] 00029 00030 Max Depth = 424 + Unknown Stack Size 00031 Call Chain = HTTPD::daemon(const void*) <-> TCPSocketServer::accept(TCPSocketConnection&) <-> 00032 Socket::wait_readable(TimeInterval&) <-> Socket::select(timeval*, bool, bool) <-> 00033 lwip_select <-> lwip_selscan <-> sys_arch_unprotect <-> error <-> exit (Cycle) 00034 */ 00035 #define DAEMON_STACK_SIZE 512 00036 00037 HTTPD * HTTPD::_inst; 00038 00039 HTTPD::HTTPD () { 00040 _inst = this; 00041 memset(_state, 0, sizeof(_state)); 00042 _handler_count = 0; 00043 } 00044 00045 int HTTPD::start (int port) { 00046 int i; 00047 00048 for (i = 0; i < HTTPD_MAX_CLIENTS; i ++) { 00049 _state[i].buf = new CircBuffer<char>(HTTPD_BUF_SIZE); 00050 _state[i].thread = new Thread(child, (void*)i, osPriorityNormal, HTTPD_STACK_SIZE); 00051 _state[i].client = new TCPSocketConnection; 00052 } 00053 #ifdef HTTPD_ENABLE_CLOSER 00054 _state[HTTPD_MAX_CLIENTS].thread = new Thread(closer, (void*)HTTPD_MAX_CLIENTS, osPriorityNormal, 128); 00055 _state[HTTPD_MAX_CLIENTS].client = new TCPSocketConnection; 00056 #endif 00057 00058 _server.bind(port); 00059 _server.listen(); 00060 _daemon = new Thread(daemon, NULL, osPriorityNormal, DAEMON_STACK_SIZE); 00061 return 0; 00062 } 00063 00064 void HTTPD::daemon (void const *args) { 00065 HTTPD *httpd = HTTPD::getInstance(); 00066 int i, t = 0; 00067 00068 INFO("Wait for new connection...\r\n"); 00069 for (;;) { 00070 if (t >= 0) { 00071 if (httpd->_server.accept(*httpd->_state[t].client) == 0) { 00072 INFO("accept %d\r\n", t); 00073 httpd->_state[t].thread->signal_set(1); 00074 } 00075 } else { 00076 #ifdef HTTPD_ENABLE_CLOSER 00077 if (httpd->_server.accept(*httpd->_state[HTTPD_MAX_CLIENTS].client) == 0) { 00078 INFO("accept x\r\n"); 00079 httpd->_state[HTTPD_MAX_CLIENTS].thread->signal_set(1); 00080 } 00081 #endif 00082 } 00083 00084 t = -1; 00085 for (i = 0; i < HTTPD_MAX_CLIENTS; i ++) { 00086 if (httpd->_state[i].thread->get_state() == Thread::WaitingAnd) { 00087 if (t < 0) t = i; // next empty thread 00088 } 00089 } 00090 } 00091 } 00092 00093 void HTTPD::child (void const *arg) { 00094 HTTPD *httpd = HTTPD::getInstance(); 00095 int id = (int)arg; 00096 int i, n; 00097 char buf[HTTPD_BUF_SIZE]; 00098 00099 for (;;) { 00100 Thread::signal_wait(1); 00101 00102 httpd->_state[id].mode = MODE_REQUEST; 00103 httpd->_state[id].buf->flush(); 00104 httpd->_state[id].keepalive = 0; 00105 INFO("Connection from %s\r\n", httpd->_state[id].client->get_address()); 00106 httpd->_state[id].client->set_blocking(false, HTTPD_TIMEOUT); 00107 for (;;) { 00108 if (! httpd->_state[id].client->is_connected()) break; 00109 00110 n = httpd->_state[id].client->receive(buf, sizeof(buf)-1); 00111 if (n < 0) break; 00112 buf[n] = 0; 00113 // DBG("Recv %d '%s'", n, buf); 00114 00115 for (i = 0; i < n; i ++) { 00116 httpd->recvData(id, buf[i]); 00117 } 00118 } 00119 00120 httpd->_state[id].client->close(); 00121 INFO("Close %s\r\n", httpd->_state[id].client->get_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("Close %s\r\n", httpd->_state[id].client->get_address()); 00134 } 00135 }
Generated on Thu Jul 14 2022 06:03:39 by
1.7.2
