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@12:c926d680f339, 2018-03-04 (annotated)
- Committer:
- aktk
- Date:
- Sun Mar 04 18:40:16 2018 +0000
- Revision:
- 12:c926d680f339
- Parent:
- 10:4a48594c2f44
- Child:
- 13:483b2b1a6471
Changed some name of var, and class.; ; In order to adapt to mbed os 5.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
aktk | 0:cc483bea4fe3 | 1 | #include "HTTP_SERVER.h" |
aktk | 1:3a1fe94c6e42 | 2 | #include "string" |
aktk | 12:c926d680f339 | 3 | #ifndef HTTP_SERVER_DEBUG |
aktk | 10:4a48594c2f44 | 4 | //#define DEBUG |
aktk | 8:b013075de2e4 | 5 | #endif |
aktk | 1:3a1fe94c6e42 | 6 | |
aktk | 10:4a48594c2f44 | 7 | namespace HTTP_SERVER |
aktk | 10:4a48594c2f44 | 8 | { |
aktk | 1:3a1fe94c6e42 | 9 | void DEBUG_PRINT_LINE(const char* arg_line) |
aktk | 1:3a1fe94c6e42 | 10 | { |
aktk | 12:c926d680f339 | 11 | #ifdef HTTP_SERVER_DEBUG |
aktk | 10:4a48594c2f44 | 12 | printf("(HTTP_SERVER) ") |
aktk | 10:4a48594c2f44 | 13 | printf(arg_line); |
aktk | 10:4a48594c2f44 | 14 | printf("\r\n"); |
aktk | 1:3a1fe94c6e42 | 15 | #endif |
aktk | 1:3a1fe94c6e42 | 16 | } |
aktk | 10:4a48594c2f44 | 17 | template<typename T> |
aktk | 10:4a48594c2f44 | 18 | void DEBUG_PRINT_LINE(const char* arg_line, T arg_t) |
aktk | 10:4a48594c2f44 | 19 | { |
aktk | 12:c926d680f339 | 20 | #ifdef HTTP_SERVER_DEBUG |
aktk | 10:4a48594c2f44 | 21 | printf("(HTTP_SERVER) "); |
aktk | 10:4a48594c2f44 | 22 | printf(arg_line, arg_t); |
aktk | 10:4a48594c2f44 | 23 | printf("\r\n"); |
aktk | 10:4a48594c2f44 | 24 | #endif |
aktk | 10:4a48594c2f44 | 25 | } |
aktk | 10:4a48594c2f44 | 26 | template<typename T1, typename T2> |
aktk | 10:4a48594c2f44 | 27 | void DEBUG_PRINT_LINE(const char* arg_line, T1 arg_t1, T2 arg_t2) |
aktk | 10:4a48594c2f44 | 28 | { |
aktk | 12:c926d680f339 | 29 | #ifdef HTTP_SERVER_DEBUG |
aktk | 10:4a48594c2f44 | 30 | printf("(HTTP_SERVER) "); |
aktk | 10:4a48594c2f44 | 31 | printf(arg_line, arg_t1, arg_t2); |
aktk | 10:4a48594c2f44 | 32 | printf("\r\n"); |
aktk | 10:4a48594c2f44 | 33 | #endif |
aktk | 10:4a48594c2f44 | 34 | } |
aktk | 10:4a48594c2f44 | 35 | } |
aktk | 10:4a48594c2f44 | 36 | using namespace HTTP_SERVER; |
aktk | 1:3a1fe94c6e42 | 37 | |
aktk | 0:cc483bea4fe3 | 38 | HttpServer::HttpServer() |
aktk | 0:cc483bea4fe3 | 39 | { |
aktk | 0:cc483bea4fe3 | 40 | keep_alive = (false); |
aktk | 0:cc483bea4fe3 | 41 | listening_flag = (false); |
aktk | 0:cc483bea4fe3 | 42 | req_buf[0] = '\0'; |
aktk | 0:cc483bea4fe3 | 43 | } |
aktk | 0:cc483bea4fe3 | 44 | |
aktk | 0:cc483bea4fe3 | 45 | HttpServer::~HttpServer() |
aktk | 0:cc483bea4fe3 | 46 | { |
aktk | 0:cc483bea4fe3 | 47 | } |
aktk | 0:cc483bea4fe3 | 48 | |
aktk | 0:cc483bea4fe3 | 49 | bool HttpServer::init() |
aktk | 0:cc483bea4fe3 | 50 | { |
aktk | 0:cc483bea4fe3 | 51 | |
aktk | 0:cc483bea4fe3 | 52 | // Ethernet Initialization |
aktk | 12:c926d680f339 | 53 | if(net.init()) { |
aktk | 1:3a1fe94c6e42 | 54 | printf("(HTTP_SERVER) Error!@EthernetInterface::init()\r\n"); |
aktk | 0:cc483bea4fe3 | 55 | return false; |
aktk | 0:cc483bea4fe3 | 56 | } |
aktk | 0:cc483bea4fe3 | 57 | // Ethernet Connecting setup |
aktk | 12:c926d680f339 | 58 | if(net.connect()) { |
aktk | 1:3a1fe94c6e42 | 59 | printf("(HTTP_SERVER) Error!@EthernetInterface::connect()\r\n"); |
aktk | 0:cc483bea4fe3 | 60 | return false; |
aktk | 0:cc483bea4fe3 | 61 | } else { |
aktk | 12:c926d680f339 | 62 | printf("(HTTP_SERVER) IP Address is %s\r\n", net.getIPAddress()); |
aktk | 0:cc483bea4fe3 | 63 | } |
aktk | 0:cc483bea4fe3 | 64 | // TCP Socket setup |
aktk | 0:cc483bea4fe3 | 65 | // To open Server-side PORT |
aktk | 12:c926d680f339 | 66 | if(server.bind(TCP_PORT)< 0) { |
aktk | 1:3a1fe94c6e42 | 67 | printf("(HTTP_SERVER) Error!@TCPSocketServer::bind()\r\n"); |
aktk | 0:cc483bea4fe3 | 68 | return false; |
aktk | 0:cc483bea4fe3 | 69 | } else { |
aktk | 1:3a1fe94c6e42 | 70 | printf("(HTTP_SERVER) TCP Server has bounden!\r\n"); |
aktk | 0:cc483bea4fe3 | 71 | } |
aktk | 0:cc483bea4fe3 | 72 | // Server start listening Request from a web browser. |
aktk | 12:c926d680f339 | 73 | if(server.listen(1) < 0) { |
aktk | 1:3a1fe94c6e42 | 74 | printf("(HTTP_SERVER) tcp server listen failed.\r\n"); |
aktk | 0:cc483bea4fe3 | 75 | return false; |
aktk | 0:cc483bea4fe3 | 76 | } else { |
aktk | 0:cc483bea4fe3 | 77 | listening_flag = true; |
aktk | 1:3a1fe94c6e42 | 78 | printf("(HTTP_SERVER) tcp server is listening...\r\n"); |
aktk | 0:cc483bea4fe3 | 79 | } |
aktk | 0:cc483bea4fe3 | 80 | |
aktk | 0:cc483bea4fe3 | 81 | return true; |
aktk | 0:cc483bea4fe3 | 82 | } |
aktk | 0:cc483bea4fe3 | 83 | |
aktk | 0:cc483bea4fe3 | 84 | bool HttpServer::run() |
aktk | 0:cc483bea4fe3 | 85 | { |
aktk | 0:cc483bea4fe3 | 86 | DigitalOut led1(LED1); |
aktk | 0:cc483bea4fe3 | 87 | DigitalOut led2(LED1); |
aktk | 0:cc483bea4fe3 | 88 | |
aktk | 0:cc483bea4fe3 | 89 | while (listening_flag) { |
aktk | 0:cc483bea4fe3 | 90 | led1 = true; |
aktk | 0:cc483bea4fe3 | 91 | // blocking mode (never timeout) |
aktk | 0:cc483bea4fe3 | 92 | // waiting client connection |
aktk | 1:3a1fe94c6e42 | 93 | printf("(HTTP_SERVER) waiting connection\r\n"); |
aktk | 12:c926d680f339 | 94 | if(server.accept(tcpcon) < 0) { |
aktk | 1:3a1fe94c6e42 | 95 | printf("(HTTP_SERVER) failed to accept connection.\r\n"); |
aktk | 0:cc483bea4fe3 | 96 | return -1; |
aktk | 0:cc483bea4fe3 | 97 | } else { |
aktk | 12:c926d680f339 | 98 | printf("(HTTP_SERVER) connection success!\r\nIP: %s\r\n",client.get_address()); |
aktk | 0:cc483bea4fe3 | 99 | led2 = true; |
aktk | 0:cc483bea4fe3 | 100 | } |
aktk | 1:3a1fe94c6e42 | 101 | // When conected |
aktk | 12:c926d680f339 | 102 | while(client.is_connected()) { |
aktk | 10:4a48594c2f44 | 103 | printf("(HTTP_SERVER) connected\r\n"); |
aktk | 1:3a1fe94c6e42 | 104 | |
aktk | 0:cc483bea4fe3 | 105 | char buffer[1024] = {0}; |
aktk | 0:cc483bea4fe3 | 106 | char* httpmethod = NULL; |
aktk | 0:cc483bea4fe3 | 107 | char* filepath = NULL; |
aktk | 0:cc483bea4fe3 | 108 | char* http_ver = NULL; |
aktk | 0:cc483bea4fe3 | 109 | char* header_field_name = NULL; |
aktk | 0:cc483bea4fe3 | 110 | char* header_field_val = NULL; |
aktk | 1:3a1fe94c6e42 | 111 | |
aktk | 0:cc483bea4fe3 | 112 | // |
aktk | 0:cc483bea4fe3 | 113 | // Request Analysis |
aktk | 0:cc483bea4fe3 | 114 | // |
aktk | 10:4a48594c2f44 | 115 | DEBUG_PRINT_LINE("DEBUG MODE"); |
aktk | 12:c926d680f339 | 116 | switch(client.receive(buffer, 1023)) { |
aktk | 0:cc483bea4fe3 | 117 | case 0: |
aktk | 10:4a48594c2f44 | 118 | DEBUG_PRINT_LINE("recieved buffer is empty."); |
aktk | 0:cc483bea4fe3 | 119 | msger.setStatusLine(400, "No Request"); |
aktk | 10:4a48594c2f44 | 120 | if(msger.setHeaderField("Connection", "Close"))DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger"); |
aktk | 0:cc483bea4fe3 | 121 | httpmethod = NULL; |
aktk | 0:cc483bea4fe3 | 122 | filepath = NULL; |
aktk | 0:cc483bea4fe3 | 123 | http_ver = NULL; |
aktk | 0:cc483bea4fe3 | 124 | break; |
aktk | 0:cc483bea4fe3 | 125 | case -1: |
aktk | 10:4a48594c2f44 | 126 | DEBUG_PRINT_LINE("failed to read data from client."); |
aktk | 0:cc483bea4fe3 | 127 | msger.setStatusLine(500, "Internal Server Error"); |
aktk | 10:4a48594c2f44 | 128 | if(msger.setHeaderField("Connection", "Close"))DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger"); |
aktk | 0:cc483bea4fe3 | 129 | httpmethod = NULL; |
aktk | 0:cc483bea4fe3 | 130 | filepath = NULL; |
aktk | 0:cc483bea4fe3 | 131 | http_ver = NULL; |
aktk | 0:cc483bea4fe3 | 132 | break; |
aktk | 0:cc483bea4fe3 | 133 | default: |
aktk | 10:4a48594c2f44 | 134 | DEBUG_PRINT_LINE("Recieved Data: %d",strlen(buffer)); |
aktk | 10:4a48594c2f44 | 135 | DEBUG_PRINT_LINE("-->\r\n"); |
aktk | 10:4a48594c2f44 | 136 | DEBUG_PRINT_LINE("%.*s[End of Request]",strlen(buffer),buffer); |
aktk | 10:4a48594c2f44 | 137 | // get HTTP method, File path, HTTP version |
aktk | 0:cc483bea4fe3 | 138 | httpmethod = strtok(buffer," "); |
aktk | 0:cc483bea4fe3 | 139 | filepath = strtok(NULL, " "); |
aktk | 0:cc483bea4fe3 | 140 | http_ver = strtok(NULL, "\r\n"); |
aktk | 10:4a48594c2f44 | 141 | DEBUG_PRINT_LINE("httpmethod: %s", httpmethod); |
aktk | 10:4a48594c2f44 | 142 | DEBUG_PRINT_LINE("file path: %s", filepath); |
aktk | 10:4a48594c2f44 | 143 | DEBUG_PRINT_LINE("http ver : %s", http_ver); |
aktk | 0:cc483bea4fe3 | 144 | break; |
aktk | 0:cc483bea4fe3 | 145 | } |
aktk | 1:3a1fe94c6e42 | 146 | |
aktk | 0:cc483bea4fe3 | 147 | // |
aktk | 0:cc483bea4fe3 | 148 | // Response |
aktk | 0:cc483bea4fe3 | 149 | // |
aktk | 0:cc483bea4fe3 | 150 | if (strcmp(httpmethod,"GET") == 0 ) { |
aktk | 10:4a48594c2f44 | 151 | DEBUG_PRINT_LINE("GET request incomming."); |
aktk | 0:cc483bea4fe3 | 152 | |
aktk | 0:cc483bea4fe3 | 153 | // file calibration |
aktk | 10:4a48594c2f44 | 154 | DEBUG_PRINT_LINE("file opening"); |
aktk | 0:cc483bea4fe3 | 155 | fhandl.open(filepath,"rb"); |
aktk | 0:cc483bea4fe3 | 156 | if(fhandl.arrival()) { |
aktk | 0:cc483bea4fe3 | 157 | msger.setStatusLine(200, "OK"); |
aktk | 10:4a48594c2f44 | 158 | if(msger.setHeaderField("Content-Length", fhandl.getFileSize())) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger"); |
aktk | 10:4a48594c2f44 | 159 | if(msger.setHeaderField("Connection", "keep-alive")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger"); |
aktk | 0:cc483bea4fe3 | 160 | } else { |
aktk | 10:4a48594c2f44 | 161 | if(msger.setStatusLine(404, "NOT FOUND")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger"); |
aktk | 10:4a48594c2f44 | 162 | if(msger.setHeaderField("Connection", "Close")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger"); |
aktk | 10:4a48594c2f44 | 163 | DEBUG_PRINT_LINE("NOT FOUND"); |
aktk | 0:cc483bea4fe3 | 164 | } |
aktk | 10:4a48594c2f44 | 165 | if( !strcmp(fhandl.getSuffix(), "htm" ) || |
aktk | 10:4a48594c2f44 | 166 | !strcmp(fhandl.getSuffix(), "HTM" ) || |
aktk | 10:4a48594c2f44 | 167 | !strcmp(fhandl.getSuffix(), "html") || |
aktk | 10:4a48594c2f44 | 168 | !strcmp(fhandl.getSuffix(), "HTML")){ |
aktk | 10:4a48594c2f44 | 169 | if(msger.setHeaderField("Content-Type", "text/html")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger"); |
aktk | 10:4a48594c2f44 | 170 | } else if( !strcmp(fhandl.getSuffix(), "js" )){ |
aktk | 10:4a48594c2f44 | 171 | if(msger.setHeaderField("Content-Type", "text/javascript")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger"); |
aktk | 10:4a48594c2f44 | 172 | } else if ( !strcmp(fhandl.getSuffix(), "ico" )){ |
aktk | 10:4a48594c2f44 | 173 | if(msger.setHeaderField("Content-Type", "image/png")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger"); |
aktk | 10:4a48594c2f44 | 174 | } else if ( !strcmp(fhandl.getSuffix(), "png" ) || |
aktk | 10:4a48594c2f44 | 175 | !strcmp(fhandl.getSuffix(), "PNG" )){ |
aktk | 10:4a48594c2f44 | 176 | if(msger.setHeaderField("Content-Type", "image/png")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger"); |
aktk | 10:4a48594c2f44 | 177 | } else if ( !strcmp(fhandl.getSuffix(), "jpg" ) || |
aktk | 10:4a48594c2f44 | 178 | !strcmp(fhandl.getSuffix(), "JPG" )){ |
aktk | 10:4a48594c2f44 | 179 | if(msger.setHeaderField("Content-Type", "image/jpg")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger"); |
aktk | 0:cc483bea4fe3 | 180 | } else { |
aktk | 0:cc483bea4fe3 | 181 | msger.setStatusLine(406, "not acceptable"); |
aktk | 0:cc483bea4fe3 | 182 | } |
aktk | 0:cc483bea4fe3 | 183 | |
aktk | 0:cc483bea4fe3 | 184 | // Connection timeout field |
aktk | 10:4a48594c2f44 | 185 | if(msger.setHeaderField("Keep-Alive", "timeouit=15")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger"); |
aktk | 1:3a1fe94c6e42 | 186 | |
aktk | 0:cc483bea4fe3 | 187 | // send response |
aktk | 0:cc483bea4fe3 | 188 | msger.sendHTTPResponse(tcpcon, fhandl); |
aktk | 0:cc483bea4fe3 | 189 | |
aktk | 0:cc483bea4fe3 | 190 | //file close |
aktk | 7:184c6f1ace94 | 191 | if( fhandl.close()== 0) |
aktk | 10:4a48594c2f44 | 192 | DEBUG_PRINT_LINE("file has closed"); |
aktk | 0:cc483bea4fe3 | 193 | else if(EOF) |
aktk | 10:4a48594c2f44 | 194 | DEBUG_PRINT_LINE("failed to close the file"); |
aktk | 7:184c6f1ace94 | 195 | |
aktk | 7:184c6f1ace94 | 196 | msger.resetHeader(); |
aktk | 10:4a48594c2f44 | 197 | DEBUG_PRINT_LINE("echo back done."); |
aktk | 7:184c6f1ace94 | 198 | } |
aktk | 7:184c6f1ace94 | 199 | if (httpmethod == NULL) { |
aktk | 7:184c6f1ace94 | 200 | msger.sendHTTPResponse(tcpcon); |
aktk | 0:cc483bea4fe3 | 201 | msger.resetHeader(); |
aktk | 10:4a48594c2f44 | 202 | DEBUG_PRINT_LINE("echo back done."); |
aktk | 0:cc483bea4fe3 | 203 | } |
aktk | 1:3a1fe94c6e42 | 204 | printf("(HTTP_SERVER) Response to Request has done\r\n"); |
aktk | 7:184c6f1ace94 | 205 | // |
aktk | 7:184c6f1ace94 | 206 | // |
aktk | 7:184c6f1ace94 | 207 | // |
aktk | 0:cc483bea4fe3 | 208 | } |
aktk | 1:3a1fe94c6e42 | 209 | printf("(HTTP_SERVER) close connection.\r\ntcp server is listening...\r\n"); |
aktk | 12:c926d680f339 | 210 | client.close(); |
aktk | 0:cc483bea4fe3 | 211 | led2 = false; |
aktk | 0:cc483bea4fe3 | 212 | } |
aktk | 12:c926d680f339 | 213 | server.close(); |
aktk | 7:184c6f1ace94 | 214 | listening_flag = false; |
aktk | 0:cc483bea4fe3 | 215 | led1 = false; |
aktk | 0:cc483bea4fe3 | 216 | return 0; |
aktk | 0:cc483bea4fe3 | 217 | } |