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@3:59884bc0a238, 2016-11-26 (annotated)
- Committer:
- aktk
- Date:
- Sat Nov 26 18:22:42 2016 +0000
- Revision:
- 3:59884bc0a238
- Parent:
- 2:33714d7c0f45
- Child:
- 4:b551799053c6
fix the library to be compilable
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 | 0:cc483bea4fe3 | 3 | #define DEBUG |
aktk | 1:3a1fe94c6e42 | 4 | |
aktk | 1:3a1fe94c6e42 | 5 | void DEBUG_PRINT_LINE(const char* arg_line) |
aktk | 1:3a1fe94c6e42 | 6 | { |
aktk | 1:3a1fe94c6e42 | 7 | #ifdef DEBUG |
aktk | 1:3a1fe94c6e42 | 8 | printf("%s",arg_line); |
aktk | 1:3a1fe94c6e42 | 9 | #endif |
aktk | 1:3a1fe94c6e42 | 10 | } |
aktk | 1:3a1fe94c6e42 | 11 | |
aktk | 0:cc483bea4fe3 | 12 | HttpServer::HttpServer() |
aktk | 0:cc483bea4fe3 | 13 | { |
aktk | 0:cc483bea4fe3 | 14 | keep_alive = (false); |
aktk | 0:cc483bea4fe3 | 15 | listening_flag = (false); |
aktk | 0:cc483bea4fe3 | 16 | req_buf[0] = '\0'; |
aktk | 0:cc483bea4fe3 | 17 | } |
aktk | 0:cc483bea4fe3 | 18 | |
aktk | 0:cc483bea4fe3 | 19 | HttpServer::~HttpServer() |
aktk | 0:cc483bea4fe3 | 20 | { |
aktk | 0:cc483bea4fe3 | 21 | } |
aktk | 0:cc483bea4fe3 | 22 | |
aktk | 0:cc483bea4fe3 | 23 | bool HttpServer::init() |
aktk | 0:cc483bea4fe3 | 24 | { |
aktk | 0:cc483bea4fe3 | 25 | |
aktk | 0:cc483bea4fe3 | 26 | // Ethernet Initialization |
aktk | 0:cc483bea4fe3 | 27 | if(eth.init()) { |
aktk | 1:3a1fe94c6e42 | 28 | printf("(HTTP_SERVER) Error!@EthernetInterface::init()\r\n"); |
aktk | 0:cc483bea4fe3 | 29 | return false; |
aktk | 0:cc483bea4fe3 | 30 | } |
aktk | 0:cc483bea4fe3 | 31 | // Ethernet Connecting setup |
aktk | 0:cc483bea4fe3 | 32 | if(eth.connect()) { |
aktk | 1:3a1fe94c6e42 | 33 | printf("(HTTP_SERVER) Error!@EthernetInterface::connect()\r\n"); |
aktk | 0:cc483bea4fe3 | 34 | return false; |
aktk | 0:cc483bea4fe3 | 35 | } else { |
aktk | 1:3a1fe94c6e42 | 36 | printf("(HTTP_SERVER) IP Address is %s\r\n", eth.getIPAddress()); |
aktk | 0:cc483bea4fe3 | 37 | } |
aktk | 0:cc483bea4fe3 | 38 | // TCP Socket setup |
aktk | 0:cc483bea4fe3 | 39 | // To open Server-side PORT |
aktk | 0:cc483bea4fe3 | 40 | if(tcpsvr.bind(TCP_PORT)< 0) { |
aktk | 1:3a1fe94c6e42 | 41 | printf("(HTTP_SERVER) Error!@TCPSocketServer::bind()\r\n"); |
aktk | 0:cc483bea4fe3 | 42 | return false; |
aktk | 0:cc483bea4fe3 | 43 | } else { |
aktk | 1:3a1fe94c6e42 | 44 | printf("(HTTP_SERVER) TCP Server has bounden!\r\n"); |
aktk | 0:cc483bea4fe3 | 45 | } |
aktk | 0:cc483bea4fe3 | 46 | // Server start listening Request from a web browser. |
aktk | 0:cc483bea4fe3 | 47 | if(tcpsvr.listen(1) < 0) { |
aktk | 1:3a1fe94c6e42 | 48 | printf("(HTTP_SERVER) tcp server listen failed.\r\n"); |
aktk | 0:cc483bea4fe3 | 49 | return false; |
aktk | 0:cc483bea4fe3 | 50 | } else { |
aktk | 0:cc483bea4fe3 | 51 | listening_flag = true; |
aktk | 1:3a1fe94c6e42 | 52 | printf("(HTTP_SERVER) tcp server is listening...\r\n"); |
aktk | 0:cc483bea4fe3 | 53 | } |
aktk | 0:cc483bea4fe3 | 54 | |
aktk | 0:cc483bea4fe3 | 55 | return true; |
aktk | 0:cc483bea4fe3 | 56 | } |
aktk | 0:cc483bea4fe3 | 57 | |
aktk | 0:cc483bea4fe3 | 58 | bool HttpServer::run() |
aktk | 0:cc483bea4fe3 | 59 | { |
aktk | 0:cc483bea4fe3 | 60 | DigitalOut led1(LED1); |
aktk | 0:cc483bea4fe3 | 61 | DigitalOut led2(LED1); |
aktk | 0:cc483bea4fe3 | 62 | |
aktk | 0:cc483bea4fe3 | 63 | while (listening_flag) { |
aktk | 0:cc483bea4fe3 | 64 | led1 = true; |
aktk | 0:cc483bea4fe3 | 65 | // blocking mode (never timeout) |
aktk | 0:cc483bea4fe3 | 66 | // waiting client connection |
aktk | 1:3a1fe94c6e42 | 67 | printf("(HTTP_SERVER) waiting connection\r\n"); |
aktk | 0:cc483bea4fe3 | 68 | if(tcpsvr.accept(tcpcon) < 0) { |
aktk | 1:3a1fe94c6e42 | 69 | printf("(HTTP_SERVER) failed to accept connection.\r\n"); |
aktk | 0:cc483bea4fe3 | 70 | return -1; |
aktk | 0:cc483bea4fe3 | 71 | } else { |
aktk | 1:3a1fe94c6e42 | 72 | printf("(HTTP_SERVER) connection success!\r\nIP: %s\r\n",tcpcon.get_address()); |
aktk | 0:cc483bea4fe3 | 73 | led2 = true; |
aktk | 0:cc483bea4fe3 | 74 | } |
aktk | 1:3a1fe94c6e42 | 75 | // When conected |
aktk | 0:cc483bea4fe3 | 76 | while(tcpcon.is_connected()) { |
aktk | 1:3a1fe94c6e42 | 77 | DEBUG_PRINT_LINE("(HTTP_SERVER) connected\r\n"); |
aktk | 1:3a1fe94c6e42 | 78 | |
aktk | 0:cc483bea4fe3 | 79 | char buffer[1024] = {0}; |
aktk | 0:cc483bea4fe3 | 80 | char* httpmethod = NULL; |
aktk | 0:cc483bea4fe3 | 81 | char* filepath = NULL; |
aktk | 0:cc483bea4fe3 | 82 | char* http_ver = NULL; |
aktk | 0:cc483bea4fe3 | 83 | char* header_field_name = NULL; |
aktk | 0:cc483bea4fe3 | 84 | char* header_field_val = NULL; |
aktk | 1:3a1fe94c6e42 | 85 | |
aktk | 0:cc483bea4fe3 | 86 | // |
aktk | 0:cc483bea4fe3 | 87 | // Request Analysis |
aktk | 0:cc483bea4fe3 | 88 | // |
aktk | 1:3a1fe94c6e42 | 89 | DEBUG_PRINT_LINE("(HTTP_SERVER) DEBUG MODE\r\n"); |
aktk | 0:cc483bea4fe3 | 90 | switch(tcpcon.receive(buffer, 1023)) { |
aktk | 0:cc483bea4fe3 | 91 | case 0: |
aktk | 1:3a1fe94c6e42 | 92 | printf("(HTTP_SERVER) recieved buffer is empty.\r\n"); |
aktk | 0:cc483bea4fe3 | 93 | msger.setStatusLine(400, "No Request"); |
aktk | 0:cc483bea4fe3 | 94 | httpmethod = NULL; |
aktk | 0:cc483bea4fe3 | 95 | filepath = NULL; |
aktk | 0:cc483bea4fe3 | 96 | http_ver = NULL; |
aktk | 0:cc483bea4fe3 | 97 | break; |
aktk | 0:cc483bea4fe3 | 98 | case -1: |
aktk | 1:3a1fe94c6e42 | 99 | printf("(HTTP_SERVER) failed to read data from client.\r\n"); |
aktk | 0:cc483bea4fe3 | 100 | msger.setStatusLine(500, "Internal Server Error"); |
aktk | 0:cc483bea4fe3 | 101 | httpmethod = NULL; |
aktk | 0:cc483bea4fe3 | 102 | filepath = NULL; |
aktk | 0:cc483bea4fe3 | 103 | http_ver = NULL; |
aktk | 0:cc483bea4fe3 | 104 | break; |
aktk | 0:cc483bea4fe3 | 105 | default: |
aktk | 1:3a1fe94c6e42 | 106 | printf("(HTTP_SERVER) Recieved Data: %d\r\n-->\r\n%.*s[End of Request]\r\n",strlen(buffer),strlen(buffer),buffer); |
aktk | 0:cc483bea4fe3 | 107 | // get HTTP method |
aktk | 0:cc483bea4fe3 | 108 | httpmethod = strtok(buffer," "); |
aktk | 0:cc483bea4fe3 | 109 | // get File path |
aktk | 0:cc483bea4fe3 | 110 | filepath = strtok(NULL, " "); |
aktk | 0:cc483bea4fe3 | 111 | // get HTTP version |
aktk | 0:cc483bea4fe3 | 112 | http_ver = strtok(NULL, "\r\n"); |
aktk | 0:cc483bea4fe3 | 113 | #ifdef DEBUG |
aktk | 1:3a1fe94c6e42 | 114 | printf("(HTTP_SERVER) httpmethod: %s\r\n", httpmethod); |
aktk | 1:3a1fe94c6e42 | 115 | printf("(HTTP_SERVER) file path: %s\r\n", filepath); |
aktk | 1:3a1fe94c6e42 | 116 | printf("(HTTP_SERVER) http ver : %s\r\n", http_ver); |
aktk | 0:cc483bea4fe3 | 117 | #endif |
aktk | 0:cc483bea4fe3 | 118 | break; |
aktk | 0:cc483bea4fe3 | 119 | } |
aktk | 1:3a1fe94c6e42 | 120 | DEBUG_PRINT_LINE("\r\n" |
aktk | 1:3a1fe94c6e42 | 121 | "(HTTP_SERVER) debug before response\r\n"); |
aktk | 1:3a1fe94c6e42 | 122 | |
aktk | 0:cc483bea4fe3 | 123 | // |
aktk | 0:cc483bea4fe3 | 124 | // Response |
aktk | 0:cc483bea4fe3 | 125 | // |
aktk | 0:cc483bea4fe3 | 126 | if (strcmp(httpmethod,"GET") == 0 ) { |
aktk | 1:3a1fe94c6e42 | 127 | printf("(HTTP_SERVER) GET request incomming.\r\n"); |
aktk | 0:cc483bea4fe3 | 128 | |
aktk | 0:cc483bea4fe3 | 129 | // file calibration |
aktk | 1:3a1fe94c6e42 | 130 | DEBUG_PRINT_LINE("(HTTP_SERVER) file opening\r\n"); |
aktk | 0:cc483bea4fe3 | 131 | fhandl.open(filepath,"rb"); |
aktk | 0:cc483bea4fe3 | 132 | if(fhandl.arrival()) { |
aktk | 0:cc483bea4fe3 | 133 | msger.setStatusLine(200, "OK"); |
aktk | 0:cc483bea4fe3 | 134 | if(msger.setHeaderField("Content-Length", fhandl.getFileSize()))printf("buffer over flow"); |
aktk | 0:cc483bea4fe3 | 135 | if(msger.setHeaderField("Connection", "keep-alive"))printf("buffer over flow"); |
aktk | 0:cc483bea4fe3 | 136 | } else { |
aktk | 0:cc483bea4fe3 | 137 | if(msger.setStatusLine(404, "NOT FOUND"))printf("buffer over flow"); |
aktk | 0:cc483bea4fe3 | 138 | if(msger.setHeaderField("Connection", "close"))printf("buffer over flow"); |
aktk | 1:3a1fe94c6e42 | 139 | DEBUG_PRINT_LINE("(HTTP_SERVER) NOT FOUND\r\n"); |
aktk | 0:cc483bea4fe3 | 140 | } |
aktk | 1:3a1fe94c6e42 | 141 | if( strcmp(fhandl.getSuffix(), "htm" ) || |
aktk | 1:3a1fe94c6e42 | 142 | strcmp(fhandl.getSuffix(), "HTM" ) || |
aktk | 1:3a1fe94c6e42 | 143 | strcmp(fhandl.getSuffix(), "html") || |
aktk | 1:3a1fe94c6e42 | 144 | strcmp(fhandl.getSuffix(), "HTML")) { |
aktk | 0:cc483bea4fe3 | 145 | if(msger.setHeaderField("Content-Type", "text/html"))printf("buffer over flow"); |
aktk | 1:3a1fe94c6e42 | 146 | } else if (strcmp(fhandl.getSuffix(), "ico" ) ) { |
aktk | 0:cc483bea4fe3 | 147 | if(msger.setHeaderField("Content-Type", "image/png"))printf("buffer over flow"); |
aktk | 0:cc483bea4fe3 | 148 | } else { |
aktk | 0:cc483bea4fe3 | 149 | msger.setStatusLine(406, "not acceptable"); |
aktk | 0:cc483bea4fe3 | 150 | } |
aktk | 0:cc483bea4fe3 | 151 | |
aktk | 0:cc483bea4fe3 | 152 | // Connection timeout field |
aktk | 0:cc483bea4fe3 | 153 | if(msger.setHeaderField("Keep-Alive", "timeouit=15"))printf("buffer over flow"); |
aktk | 1:3a1fe94c6e42 | 154 | |
aktk | 1:3a1fe94c6e42 | 155 | // Define behaviour of server according to Request Header lines |
aktk | 2:33714d7c0f45 | 156 | // Apply request header field to response header field |
aktk | 3:59884bc0a238 | 157 | char* field_Connection = NULL; |
aktk | 3:59884bc0a238 | 158 | char* field_Upgrade = NULL; |
aktk | 3:59884bc0a238 | 159 | char* field_Sec_WebSocket_Key = NULL; |
aktk | 3:59884bc0a238 | 160 | char* field_Sec_WebSocket_Version = NULL; |
aktk | 3:59884bc0a238 | 161 | char* field_Origin = NULL; |
aktk | 0:cc483bea4fe3 | 162 | do { |
aktk | 2:33714d7c0f45 | 163 | //Analyze the header feilds |
aktk | 0:cc483bea4fe3 | 164 | header_field_name = strtok(NULL, ":"); |
aktk | 0:cc483bea4fe3 | 165 | header_field_name++; |
aktk | 0:cc483bea4fe3 | 166 | header_field_val = strtok(NULL, "\r\n"); |
aktk | 0:cc483bea4fe3 | 167 | header_field_val++; |
aktk | 2:33714d7c0f45 | 168 | |
aktk | 2:33714d7c0f45 | 169 | if(header_field_name != NULL) { |
aktk | 3:59884bc0a238 | 170 | if(!strcmp(header_field_name, "Connection")) { |
aktk | 3:59884bc0a238 | 171 | field_Connection = header_field_val; |
aktk | 3:59884bc0a238 | 172 | } else if(!strcmp(header_field_name, "Upgrade")) { |
aktk | 3:59884bc0a238 | 173 | field_Upgrade = header_field_val; |
aktk | 3:59884bc0a238 | 174 | } else if(!strcmp(header_field_name, "Sec-WebSocket-Key") ) { |
aktk | 3:59884bc0a238 | 175 | field_Sec_WebSocket_Key = header_field_val; |
aktk | 3:59884bc0a238 | 176 | } else if(!strcmp(header_field_name, "Sec-WebSocket-Version") ) { |
aktk | 3:59884bc0a238 | 177 | field_Sec_WebSocket_Version = header_field_val; |
aktk | 3:59884bc0a238 | 178 | } else if(!strcmp(header_field_name, "Origin") ) { |
aktk | 3:59884bc0a238 | 179 | field_Origin = header_field_val; |
aktk | 2:33714d7c0f45 | 180 | } |
aktk | 3:59884bc0a238 | 181 | } else break; |
aktk | 0:cc483bea4fe3 | 182 | #ifdef DEBUG |
aktk | 1:3a1fe94c6e42 | 183 | printf("(HTTP_SERVER) *header_field_name adr: %d %s\r\n", header_field_name - 1, header_field_name); |
aktk | 1:3a1fe94c6e42 | 184 | printf("(HTTP_SERVER) header_field_val adr: %d %s\r\n", header_field_val - 1, header_field_val); |
aktk | 0:cc483bea4fe3 | 185 | #endif |
aktk | 2:33714d7c0f45 | 186 | } while(1); |
aktk | 2:33714d7c0f45 | 187 | |
aktk | 2:33714d7c0f45 | 188 | // if the request is to switching to the WebSocket Server |
aktk | 3:59884bc0a238 | 189 | if( !strcmp(field_Connection, "Upgrade") && |
aktk | 2:33714d7c0f45 | 190 | !strcmp(field_Upgrade, "websocket") && |
aktk | 2:33714d7c0f45 | 191 | field_Sec_WebSocket_Key != NULL && |
aktk | 2:33714d7c0f45 | 192 | !strcmp(field_Sec_WebSocket_Version, "13") && |
aktk | 2:33714d7c0f45 | 193 | field_Origin != NULL) { |
aktk | 2:33714d7c0f45 | 194 | DEBUG_PRINT_LINE("(HTTP_SERVER) Communication Protocol will be Upgraded to Websocket! \r\n"); |
aktk | 2:33714d7c0f45 | 195 | /* |
aktk | 2:33714d7c0f45 | 196 | if(ws.isValid()){ |
aktk | 3:59884bc0a238 | 197 | ...//calcurate the key |
aktk | 2:33714d7c0f45 | 198 | msger.resetHeader(); |
aktk | 2:33714d7c0f45 | 199 | msger.setStatusLine(101, "Switching Protocols"); |
aktk | 2:33714d7c0f45 | 200 | if(msger.msger.setHeaderField("Connection", "Upgrade")) printf("(HTTP_SERVER)buffer over flow@ResposeMessenger"); |
aktk | 2:33714d7c0f45 | 201 | if(msger.msger.setHeaderField("Upgrade", "websocket")) printf("(HTTP_SERVER)buffer over flow@ResposeMessenger"); |
aktk | 2:33714d7c0f45 | 202 | if(msger.msger.setHeaderField("Sec-WebSocket-Accept", ...)) printf("(HTTP_SERVER)buffer over flow@ResposeMessenger"); |
aktk | 2:33714d7c0f45 | 203 | if(msger.msger.setHeaderField("Access-Control-Allow-Origin", "*")) printf("(HTTP_SERVER)buffer over flow@ResposeMessenger"); |
aktk | 0:cc483bea4fe3 | 204 | } |
aktk | 3:59884bc0a238 | 205 | else goto AAA; |
aktk | 2:33714d7c0f45 | 206 | */ |
aktk | 2:33714d7c0f45 | 207 | } else { |
aktk | 3:59884bc0a238 | 208 | //AAA: |
aktk | 2:33714d7c0f45 | 209 | DEBUG_PRINT_LINE("(HTTP_SERVER) Communication Protocol won't be Upgraded.\r\n"); |
aktk | 2:33714d7c0f45 | 210 | msger.setStatusLine(426, "Upgrade Required"); |
aktk | 2:33714d7c0f45 | 211 | if(msger.setHeaderField("Connection", "Close"))printf("buffer over flow"); |
aktk | 2:33714d7c0f45 | 212 | } |
aktk | 2:33714d7c0f45 | 213 | |
aktk | 1:3a1fe94c6e42 | 214 | |
aktk | 0:cc483bea4fe3 | 215 | #ifdef DEBUG |
aktk | 0:cc483bea4fe3 | 216 | //printf("status code : %d\r\n", status_code); |
aktk | 0:cc483bea4fe3 | 217 | //printf("content type: %s\r\n", content_type); |
aktk | 0:cc483bea4fe3 | 218 | #endif |
aktk | 0:cc483bea4fe3 | 219 | |
aktk | 0:cc483bea4fe3 | 220 | // send response |
aktk | 0:cc483bea4fe3 | 221 | msger.sendHTTPResponse(tcpcon, fhandl); |
aktk | 0:cc483bea4fe3 | 222 | |
aktk | 0:cc483bea4fe3 | 223 | //file close |
aktk | 0:cc483bea4fe3 | 224 | #ifdef DEBUG |
aktk | 0:cc483bea4fe3 | 225 | if( |
aktk | 0:cc483bea4fe3 | 226 | #endif |
aktk | 0:cc483bea4fe3 | 227 | fhandl.close() |
aktk | 0:cc483bea4fe3 | 228 | #ifndef DEBUG |
aktk | 0:cc483bea4fe3 | 229 | ; |
aktk | 0:cc483bea4fe3 | 230 | #endif |
aktk | 0:cc483bea4fe3 | 231 | #ifdef DEBUG |
aktk | 0:cc483bea4fe3 | 232 | == 0) |
aktk | 1:3a1fe94c6e42 | 233 | printf("(HTTP_SERVER) file has closed\r\n"); |
aktk | 0:cc483bea4fe3 | 234 | else if(EOF) |
aktk | 1:3a1fe94c6e42 | 235 | printf("(HTTP_SERVER) failed to close the file\r\n"); |
aktk | 0:cc483bea4fe3 | 236 | #endif |
aktk | 0:cc483bea4fe3 | 237 | msger.resetHeader(); |
aktk | 1:3a1fe94c6e42 | 238 | printf("(HTTP_SERVER) echo back done.\r\n"); |
aktk | 0:cc483bea4fe3 | 239 | } |
aktk | 1:3a1fe94c6e42 | 240 | printf("(HTTP_SERVER) Response to Request has done\r\n"); |
aktk | 0:cc483bea4fe3 | 241 | } |
aktk | 1:3a1fe94c6e42 | 242 | printf("(HTTP_SERVER) close connection.\r\ntcp server is listening...\r\n"); |
aktk | 0:cc483bea4fe3 | 243 | tcpcon.close(); |
aktk | 1:3a1fe94c6e42 | 244 | //tcpsvr.close(); |
aktk | 0:cc483bea4fe3 | 245 | led2 = false; |
aktk | 0:cc483bea4fe3 | 246 | } |
aktk | 0:cc483bea4fe3 | 247 | led1 = false; |
aktk | 0:cc483bea4fe3 | 248 | return 0; |
aktk | 0:cc483bea4fe3 | 249 | } |