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 Akifumi Takahashi

Committer:
aktk
Date:
Sat Nov 26 18:54:10 2016 +0000
Revision:
5:dedbaa9c633b
Parent:
4:b551799053c6
Child:
6:4eb469f51570
bug fix: the bug communication was conducted when it shouldn't have been was fixed.

Who changed what in which revision?

UserRevisionLine numberNew 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 5:dedbaa9c633b 94 if(msger.setHeaderField("Connection", "close"))printf("(HTTP_SERVER)buffer over flow @ ResponseMessenger");
aktk 0:cc483bea4fe3 95 httpmethod = NULL;
aktk 0:cc483bea4fe3 96 filepath = NULL;
aktk 0:cc483bea4fe3 97 http_ver = NULL;
aktk 0:cc483bea4fe3 98 break;
aktk 0:cc483bea4fe3 99 case -1:
aktk 1:3a1fe94c6e42 100 printf("(HTTP_SERVER) failed to read data from client.\r\n");
aktk 0:cc483bea4fe3 101 msger.setStatusLine(500, "Internal Server Error");
aktk 5:dedbaa9c633b 102 if(msger.setHeaderField("Connection", "close"))printf("(HTTP_SERVER)buffer over flow @ ResponseMessenger");
aktk 0:cc483bea4fe3 103 httpmethod = NULL;
aktk 0:cc483bea4fe3 104 filepath = NULL;
aktk 0:cc483bea4fe3 105 http_ver = NULL;
aktk 0:cc483bea4fe3 106 break;
aktk 0:cc483bea4fe3 107 default:
aktk 1:3a1fe94c6e42 108 printf("(HTTP_SERVER) Recieved Data: %d\r\n-->\r\n%.*s[End of Request]\r\n",strlen(buffer),strlen(buffer),buffer);
aktk 0:cc483bea4fe3 109 // get HTTP method
aktk 0:cc483bea4fe3 110 httpmethod = strtok(buffer," ");
aktk 0:cc483bea4fe3 111 // get File path
aktk 0:cc483bea4fe3 112 filepath = strtok(NULL, " ");
aktk 0:cc483bea4fe3 113 // get HTTP version
aktk 0:cc483bea4fe3 114 http_ver = strtok(NULL, "\r\n");
aktk 0:cc483bea4fe3 115 #ifdef DEBUG
aktk 1:3a1fe94c6e42 116 printf("(HTTP_SERVER) httpmethod: %s\r\n", httpmethod);
aktk 1:3a1fe94c6e42 117 printf("(HTTP_SERVER) file path: %s\r\n", filepath);
aktk 1:3a1fe94c6e42 118 printf("(HTTP_SERVER) http ver : %s\r\n", http_ver);
aktk 0:cc483bea4fe3 119 #endif
aktk 0:cc483bea4fe3 120 break;
aktk 0:cc483bea4fe3 121 }
aktk 1:3a1fe94c6e42 122 DEBUG_PRINT_LINE("\r\n"
aktk 1:3a1fe94c6e42 123 "(HTTP_SERVER) debug before response\r\n");
aktk 1:3a1fe94c6e42 124
aktk 0:cc483bea4fe3 125 //
aktk 0:cc483bea4fe3 126 // Response
aktk 0:cc483bea4fe3 127 //
aktk 0:cc483bea4fe3 128 if (strcmp(httpmethod,"GET") == 0 ) {
aktk 1:3a1fe94c6e42 129 printf("(HTTP_SERVER) GET request incomming.\r\n");
aktk 0:cc483bea4fe3 130
aktk 0:cc483bea4fe3 131 // file calibration
aktk 1:3a1fe94c6e42 132 DEBUG_PRINT_LINE("(HTTP_SERVER) file opening\r\n");
aktk 0:cc483bea4fe3 133 fhandl.open(filepath,"rb");
aktk 0:cc483bea4fe3 134 if(fhandl.arrival()) {
aktk 0:cc483bea4fe3 135 msger.setStatusLine(200, "OK");
aktk 5:dedbaa9c633b 136 if(msger.setHeaderField("Content-Length", fhandl.getFileSize()))printf("(HTTP_SERVER)buffer over flow @ ResponseMessenger");
aktk 5:dedbaa9c633b 137 if(msger.setHeaderField("Connection", "keep-alive"))printf("(HTTP_SERVER)buffer over flow @ ResponseMessenger");
aktk 0:cc483bea4fe3 138 } else {
aktk 5:dedbaa9c633b 139 if(msger.setStatusLine(404, "NOT FOUND"))printf("(HTTP_SERVER)buffer over flow @ ResponseMessenger");
aktk 5:dedbaa9c633b 140 if(msger.setHeaderField("Connection", "close"))printf("(HTTP_SERVER)buffer over flow @ ResponseMessenger");
aktk 1:3a1fe94c6e42 141 DEBUG_PRINT_LINE("(HTTP_SERVER) NOT FOUND\r\n");
aktk 0:cc483bea4fe3 142 }
aktk 1:3a1fe94c6e42 143 if( strcmp(fhandl.getSuffix(), "htm" ) ||
aktk 1:3a1fe94c6e42 144 strcmp(fhandl.getSuffix(), "HTM" ) ||
aktk 1:3a1fe94c6e42 145 strcmp(fhandl.getSuffix(), "html") ||
aktk 1:3a1fe94c6e42 146 strcmp(fhandl.getSuffix(), "HTML")) {
aktk 5:dedbaa9c633b 147 if(msger.setHeaderField("Content-Type", "text/html"))printf("(HTTP_SERVER)buffer over flow @ ResponseMessenger");
aktk 1:3a1fe94c6e42 148 } else if (strcmp(fhandl.getSuffix(), "ico" ) ) {
aktk 5:dedbaa9c633b 149 if(msger.setHeaderField("Content-Type", "image/png"))printf("(HTTP_SERVER)buffer over flow @ ResponseMessenger");
aktk 0:cc483bea4fe3 150 } else {
aktk 0:cc483bea4fe3 151 msger.setStatusLine(406, "not acceptable");
aktk 0:cc483bea4fe3 152 }
aktk 0:cc483bea4fe3 153
aktk 0:cc483bea4fe3 154 // Connection timeout field
aktk 5:dedbaa9c633b 155 if(msger.setHeaderField("Keep-Alive", "timeouit=15"))printf("(HTTP_SERVER)buffer over flow @ ResponseMessenger");
aktk 1:3a1fe94c6e42 156
aktk 1:3a1fe94c6e42 157 // Define behaviour of server according to Request Header lines
aktk 2:33714d7c0f45 158 // Apply request header field to response header field
aktk 3:59884bc0a238 159 char* field_Connection = NULL;
aktk 3:59884bc0a238 160 char* field_Upgrade = NULL;
aktk 3:59884bc0a238 161 char* field_Sec_WebSocket_Key = NULL;
aktk 3:59884bc0a238 162 char* field_Sec_WebSocket_Version = NULL;
aktk 3:59884bc0a238 163 char* field_Origin = NULL;
aktk 0:cc483bea4fe3 164 do {
aktk 2:33714d7c0f45 165 //Analyze the header feilds
aktk 0:cc483bea4fe3 166 header_field_name = strtok(NULL, ":");
aktk 0:cc483bea4fe3 167 header_field_name++;
aktk 0:cc483bea4fe3 168 header_field_val = strtok(NULL, "\r\n");
aktk 0:cc483bea4fe3 169 header_field_val++;
aktk 2:33714d7c0f45 170
aktk 4:b551799053c6 171 if(header_field_name - 1 != NULL) {
aktk 3:59884bc0a238 172 if(!strcmp(header_field_name, "Connection")) {
aktk 3:59884bc0a238 173 field_Connection = header_field_val;
aktk 3:59884bc0a238 174 } else if(!strcmp(header_field_name, "Upgrade")) {
aktk 3:59884bc0a238 175 field_Upgrade = header_field_val;
aktk 3:59884bc0a238 176 } else if(!strcmp(header_field_name, "Sec-WebSocket-Key") ) {
aktk 3:59884bc0a238 177 field_Sec_WebSocket_Key = header_field_val;
aktk 3:59884bc0a238 178 } else if(!strcmp(header_field_name, "Sec-WebSocket-Version") ) {
aktk 3:59884bc0a238 179 field_Sec_WebSocket_Version = header_field_val;
aktk 3:59884bc0a238 180 } else if(!strcmp(header_field_name, "Origin") ) {
aktk 3:59884bc0a238 181 field_Origin = header_field_val;
aktk 2:33714d7c0f45 182 }
aktk 4:b551799053c6 183 } else {
aktk 4:b551799053c6 184 break;
aktk 4:b551799053c6 185 }
aktk 0:cc483bea4fe3 186 #ifdef DEBUG
aktk 1:3a1fe94c6e42 187 printf("(HTTP_SERVER) *header_field_name adr: %d %s\r\n", header_field_name - 1, header_field_name);
aktk 1:3a1fe94c6e42 188 printf("(HTTP_SERVER) header_field_val adr: %d %s\r\n", header_field_val - 1, header_field_val);
aktk 0:cc483bea4fe3 189 #endif
aktk 2:33714d7c0f45 190 } while(1);
aktk 2:33714d7c0f45 191
aktk 2:33714d7c0f45 192 // if the request is to switching to the WebSocket Server
aktk 5:dedbaa9c633b 193 if(!strcmp(field_Connection, "Upgrade")) {
aktk 5:dedbaa9c633b 194 if( !strcmp(field_Upgrade, "websocket") &&
aktk 5:dedbaa9c633b 195 field_Sec_WebSocket_Key != NULL &&
aktk 5:dedbaa9c633b 196 !strcmp(field_Sec_WebSocket_Version, "13") &&
aktk 5:dedbaa9c633b 197 field_Origin != NULL) {
aktk 5:dedbaa9c633b 198 DEBUG_PRINT_LINE("(HTTP_SERVER) Communication Protocol will be Upgraded to Websocket! \r\n");
aktk 5:dedbaa9c633b 199 /*
aktk 5:dedbaa9c633b 200 if(ws.isValid()){
aktk 5:dedbaa9c633b 201 ...//calcurate the key
aktk 5:dedbaa9c633b 202 msger.resetHeader();
aktk 5:dedbaa9c633b 203 msger.setStatusLine(101, "Switching Protocols");
aktk 5:dedbaa9c633b 204 if(msger.msger.setHeaderField("Connection", "Upgrade")) printf("(HTTP_SERVER)buffer over flow@ResposeMessenger");
aktk 5:dedbaa9c633b 205 if(msger.msger.setHeaderField("Upgrade", "websocket")) printf("(HTTP_SERVER)buffer over flow@ResposeMessenger");
aktk 5:dedbaa9c633b 206 if(msger.msger.setHeaderField("Sec-WebSocket-Accept", ...)) printf("(HTTP_SERVER)buffer over flow@ResposeMessenger");
aktk 5:dedbaa9c633b 207 if(msger.msger.setHeaderField("Access-Control-Allow-Origin", "*")) printf("(HTTP_SERVER)buffer over flow@ResposeMessenger");
aktk 5:dedbaa9c633b 208 }
aktk 5:dedbaa9c633b 209 else goto AAA;
aktk 5:dedbaa9c633b 210 */
aktk 5:dedbaa9c633b 211 } else {
aktk 5:dedbaa9c633b 212 //AAA:
aktk 5:dedbaa9c633b 213 DEBUG_PRINT_LINE("(HTTP_SERVER) Communication Protocol won't be Upgraded.\r\n");
aktk 5:dedbaa9c633b 214 msger.setStatusLine(426, "Upgrade Required");
aktk 5:dedbaa9c633b 215 if(msger.setHeaderField("Connection", "Close"))printf("(HTTP_SERVER)buffer over flow @ ResponseMessenger");
aktk 0:cc483bea4fe3 216 }
aktk 2:33714d7c0f45 217 }
aktk 2:33714d7c0f45 218
aktk 1:3a1fe94c6e42 219
aktk 0:cc483bea4fe3 220 #ifdef DEBUG
aktk 0:cc483bea4fe3 221 //printf("status code : %d\r\n", status_code);
aktk 0:cc483bea4fe3 222 //printf("content type: %s\r\n", content_type);
aktk 0:cc483bea4fe3 223 #endif
aktk 0:cc483bea4fe3 224
aktk 0:cc483bea4fe3 225 // send response
aktk 0:cc483bea4fe3 226 msger.sendHTTPResponse(tcpcon, fhandl);
aktk 0:cc483bea4fe3 227
aktk 0:cc483bea4fe3 228 //file close
aktk 0:cc483bea4fe3 229 #ifdef DEBUG
aktk 0:cc483bea4fe3 230 if(
aktk 0:cc483bea4fe3 231 #endif
aktk 0:cc483bea4fe3 232 fhandl.close()
aktk 0:cc483bea4fe3 233 #ifndef DEBUG
aktk 0:cc483bea4fe3 234 ;
aktk 0:cc483bea4fe3 235 #endif
aktk 0:cc483bea4fe3 236 #ifdef DEBUG
aktk 0:cc483bea4fe3 237 == 0)
aktk 1:3a1fe94c6e42 238 printf("(HTTP_SERVER) file has closed\r\n");
aktk 0:cc483bea4fe3 239 else if(EOF)
aktk 1:3a1fe94c6e42 240 printf("(HTTP_SERVER) failed to close the file\r\n");
aktk 0:cc483bea4fe3 241 #endif
aktk 0:cc483bea4fe3 242 msger.resetHeader();
aktk 1:3a1fe94c6e42 243 printf("(HTTP_SERVER) echo back done.\r\n");
aktk 0:cc483bea4fe3 244 }
aktk 1:3a1fe94c6e42 245 printf("(HTTP_SERVER) Response to Request has done\r\n");
aktk 0:cc483bea4fe3 246 }
aktk 1:3a1fe94c6e42 247 printf("(HTTP_SERVER) close connection.\r\ntcp server is listening...\r\n");
aktk 0:cc483bea4fe3 248 tcpcon.close();
aktk 1:3a1fe94c6e42 249 //tcpsvr.close();
aktk 0:cc483bea4fe3 250 led2 = false;
aktk 0:cc483bea4fe3 251 }
aktk 0:cc483bea4fe3 252 led1 = false;
aktk 0:cc483bea4fe3 253 return 0;
aktk 0:cc483bea4fe3 254 }