The lib with which to make LPC1768 a simple HTTP server. This have not yet implemented. fopen() DOESN'T WORK after EthernetInterface::connect() is called as using mbed-os 5.4~. See also https://os.mbed.com/questions/80658/HardFault-occurs-when-fopen-is-called-af/ or https://github.com/ARMmbed/mbed-os/issues/6578 and https://github.com/ARMmbed/mbed-os/issues/6624
Fork of HTTP_SERVER by
HTTP_SERVER.cpp
00001 #include "HTTP_SERVER.h" 00002 #include "string" 00003 //#ifndef HTTP_SERVER_DEBUG 00004 #define HTTP_SERVER_DEBUG 00005 //#endif 00006 /* 00007 LOG: 00008 "sys_thread_new number error" is occurred when an instance of this class is instantiated in main() in main.cpp 00009 This case wasn't occured with the APIs of mbed os 2. 00010 So, inserting some DEBUG_PRINT_LINE, and finding where is wrong. 00011 00012 The error seems to be occurred in init() in the above case. 00013 00014 TCP_PORT=80 redefine 00015 tcp_port->port 00016 00017 The error seems to be occurred while ethernet->connect() is proceesing. 00018 00019 The error seems to be caused by something wrong with stack. 00020 When modify (char* -> char) req_buf[1024] in the .h file, 00021 the error message became: "CMSIS-RTOS error: Stack underflow (status: 0x1, task ID: 0x10002678, task name: )" 00022 UNDERFLOW means that there is a value which is too fine(or high definition) to express. 00023 (Why was the type char*?) 00024 00025 (char)req_buf[1024] was not uesed anywhere... 00026 so it was deleted. 00027 00028 (bool)keep-alive was also not uesed so deleted it. 00029 00030 After doing those above, the error massage was DERAYED but 00031 it even now occur. 00032 and when some array stack(such like char buffer[1024] -> [256])'s size was decreased, 00033 the message was more derayed. 00034 Therefore it can be thought that the error is causeed by stack overflow. 00035 */ 00036 00037 namespace HTTP_SERVER 00038 { 00039 void DEBUG_PRINT_NAME() 00040 { 00041 #ifdef HTTP_SERVER_DEBUG 00042 printf("(DEBUG LINE: HTTP_SERVER) "); 00043 #endif 00044 } 00045 00046 void DEBUG_PRINT_LINE(const char* arg_line) 00047 { 00048 #ifdef HTTP_SERVER_DEBUG 00049 DEBUG_PRINT_NAME(); 00050 printf(arg_line); 00051 printf("\r\n"); 00052 #endif 00053 } 00054 template<typename T> 00055 void DEBUG_PRINT_LINE(const char* arg_line, T arg_t) 00056 { 00057 #ifdef HTTP_SERVER_DEBUG 00058 DEBUG_PRINT_NAME(); 00059 printf(arg_line, arg_t); 00060 printf("\r\n"); 00061 #endif 00062 } 00063 template<typename T1, typename T2> 00064 void DEBUG_PRINT_LINE(const char* arg_line, T1 arg_t1, T2 arg_t2) 00065 { 00066 #ifdef HTTP_SERVER_DEBUG 00067 DEBUG_PRINT_NAME(); 00068 printf(arg_line, arg_t1, arg_t2); 00069 printf("\r\n"); 00070 #endif 00071 } 00072 } 00073 using namespace HTTP_SERVER; 00074 00075 HttpServer::HttpServer() 00076 { 00077 DEBUG_PRINT_LINE("=DEBUG MODE="); 00078 net = new EthernetInterface(); 00079 port = TCP_PORT; 00080 backlog = 1; 00081 //keep_alive = (false); 00082 listening_flag = (false); 00083 socket_connection = false; 00084 DEBUG_PRINT_LINE("A HTTP_SERVER has been inistantiated."); 00085 } 00086 00087 HttpServer::~HttpServer() 00088 { 00089 } 00090 00091 bool HttpServer::init() 00092 { 00093 DEBUG_PRINT_LINE("The HTTP SERVER is being initiated"); 00094 // Ethernet Initialization 00095 // Ethernet Connecting setup 00096 if(net->connect()) { 00097 printf("(HTTP_SERVER) Error!@EthernetInterface::connect()\r\n"); 00098 return false; 00099 } else { 00100 printf("(HTTP_SERVER) IP Address is %s\r\n", net->get_ip_address()); 00101 } 00102 00103 ftest.func(); 00104 // TCP Socket setup 00105 // To open Server-side PORT 00106 if(server.open(net) < 0) { 00107 printf("(HTTP_SERVER) Error!@TCPSocketServer::open()\r\n"); 00108 return false; 00109 } else { 00110 printf("(HTTP_SERVER) TCP Server has successfully opened\r\n"); 00111 } 00112 if(server.bind(port)< 0) { 00113 printf("(HTTP_SERVER) Error!@TCPSocketServer::bind()\r\n"); 00114 return false; 00115 } else { 00116 printf("(HTTP_SERVER) TCP Server has bounden!\r\n"); 00117 } 00118 // Server start listening Request from a web browser. 00119 if(server.listen(backlog) < 0) { 00120 printf("(HTTP_SERVER) tcp server listen failed.\r\n"); 00121 return false; 00122 } else { 00123 listening_flag = true; 00124 printf("(HTTP_SERVER) tcp server is listening...\r\n"); 00125 } 00126 00127 return true; 00128 } 00129 00130 bool HttpServer::run() 00131 { 00132 00133 DigitalOut led1(LED1); 00134 DigitalOut led2(LED1); 00135 00136 00137 DEBUG_PRINT_LINE("The HTTP SERVER is starting running"); 00138 while (listening_flag) { 00139 led1 = true; 00140 // blocking mode (never timeout) 00141 // waiting client connection 00142 printf("(HTTP_SERVER) waiting connection\r\n"); 00143 if(server.accept(&client_socket, &client_address) < 0) { 00144 printf("(HTTP_SERVER) failed to accept connection.\r\n"); 00145 return -1; 00146 } else { 00147 printf("(HTTP_SERVER) connection success!\r\nIP: %s\r\n",client_address.get_ip_address()); 00148 socket_connection = true; 00149 led2 = true; 00150 } 00151 // When conected 00152 while (socket_connection) { 00153 printf("(HTTP_SERVER) connected\r\n"); 00154 00155 char buffer[1024] = {0}; 00156 char* httpmethod = NULL; 00157 char* filepath = NULL; 00158 char* http_ver = NULL; 00159 //char* header_field_name = NULL; 00160 //char* header_field_val = NULL; 00161 00162 // 00163 // Request Analysis 00164 // 00165 printf("(HTTP_SERVER) Request Analysis\r\n"); 00166 analyzeRequest(buffer, 1023, httpmethod, filepath, http_ver); 00167 DEBUG_PRINT_LINE("httpmethod: %s", httpmethod); 00168 DEBUG_PRINT_LINE("file path: %s", filepath); 00169 DEBUG_PRINT_LINE("http ver : %s", http_ver); 00170 // 00171 // Response 00172 // 00173 sendResponse(httpmethod, filepath, http_ver); 00174 // 00175 // 00176 // 00177 } 00178 printf("(HTTP_SERVER) close connection.\r\ntcp server is listening...\r\n"); 00179 client_socket.close(); 00180 led2 = false; 00181 } 00182 server.close(); 00183 listening_flag = false; 00184 led1 = false; 00185 return 0; 00186 00187 } 00188 00189 bool HttpServer::analyzeRequest(char* buffer, int buffer_size, char* &httpmethod, char* &filepath, char* &http_ver) 00190 { 00191 00192 DEBUG_PRINT_LINE("Request Analysis"); 00193 switch(client_socket.recv(buffer, buffer_size)) { 00194 case 0: 00195 DEBUG_PRINT_LINE("recieved buffer is empty."); 00196 msger.setStatusLine(400, "No Request"); 00197 if(msger.setHeaderField("Connection", "Close"))DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger"); 00198 httpmethod = NULL; 00199 filepath = NULL; 00200 http_ver = NULL; 00201 socket_connection = false; 00202 break; 00203 case -1: 00204 DEBUG_PRINT_LINE("failed to read data from client."); 00205 msger.setStatusLine(500, "Internal Server Error"); 00206 if(msger.setHeaderField("Connection", "Close"))DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger"); 00207 httpmethod = NULL; 00208 filepath = NULL; 00209 http_ver = NULL; 00210 socket_connection = false; 00211 break; 00212 default: 00213 DEBUG_PRINT_LINE("Recieved Data: %d",strlen(buffer)); 00214 DEBUG_PRINT_LINE("-->\r\n"); 00215 DEBUG_PRINT_LINE("%.*s[End of Request]",strlen(buffer),buffer); 00216 // get HTTP method, File path, HTTP version 00217 httpmethod = strtok(buffer," "); 00218 filepath = strtok(NULL, " "); 00219 http_ver = strtok(NULL, "\r\n"); 00220 break; 00221 } 00222 return true; 00223 } 00224 00225 bool HttpServer::sendResponse(char* httpmethod, char* filepath, char* http_ver) 00226 { 00227 if (strcmp(httpmethod,"GET") == 0 ) { 00228 DEBUG_PRINT_LINE("GET request incomming."); 00229 00230 // file calibration 00231 DEBUG_PRINT_LINE("file opening"); 00232 DEBUG_PRINT_LINE("filepath: %s", filepath); 00233 fhndl.open(filepath,"rb"); 00234 if(fhndl.arrival()) { 00235 msger.setStatusLine(200, "OK"); 00236 if(msger.setHeaderField("Content-Length", fhndl.getFileSize())) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger"); 00237 if(msger.setHeaderField("Connection", "keep-alive")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger"); 00238 } else { 00239 if(msger.setStatusLine(404, "NOT FOUND")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger"); 00240 if(msger.setHeaderField("Connection", "Close")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger"); 00241 DEBUG_PRINT_LINE("NOT FOUND"); 00242 } 00243 if( !strcmp(fhndl.getSuffix(), "htm" ) || 00244 !strcmp(fhndl.getSuffix(), "HTM" ) || 00245 !strcmp(fhndl.getSuffix(), "html") || 00246 !strcmp(fhndl.getSuffix(), "HTML")) { 00247 if(msger.setHeaderField("Content-Type", "text/html")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger"); 00248 } else if( !strcmp(fhndl.getSuffix(), "js" )) { 00249 if(msger.setHeaderField("Content-Type", "text/javascript")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger"); 00250 } else if ( !strcmp(fhndl.getSuffix(), "ico" )) { 00251 if(msger.setHeaderField("Content-Type", "image/png")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger"); 00252 } else if ( !strcmp(fhndl.getSuffix(), "png" ) || 00253 !strcmp(fhndl.getSuffix(), "PNG" )) { 00254 if(msger.setHeaderField("Content-Type", "image/png")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger"); 00255 } else if ( !strcmp(fhndl.getSuffix(), "jpg" ) || 00256 !strcmp(fhndl.getSuffix(), "JPG" )) { 00257 if(msger.setHeaderField("Content-Type", "image/jpg")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger"); 00258 } else { 00259 msger.setStatusLine(406, "not acceptable"); 00260 } 00261 00262 // Connection timeout field 00263 if(msger.setHeaderField("Keep-Alive", "timeouit=15")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger"); 00264 00265 // send response 00266 msger.sendHTTPResponse(client_socket, fhndl); 00267 00268 //file close 00269 if( fhndl.close()== 0) 00270 DEBUG_PRINT_LINE("file has closed"); 00271 else if(EOF) 00272 DEBUG_PRINT_LINE("failed to close the file"); 00273 00274 msger.resetHeader(); 00275 DEBUG_PRINT_LINE("echo back done."); 00276 } 00277 if (httpmethod == NULL) { 00278 msger.sendHTTPResponse(client_socket); 00279 msger.resetHeader(); 00280 DEBUG_PRINT_LINE("echo back done."); 00281 socket_connection = false; 00282 } 00283 printf("(HTTP_SERVER) Response to Request has done\r\n"); 00284 00285 return true; 00286 }
Generated on Fri Jul 15 2022 08:17:44 by 1.7.2