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