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:
Sun Mar 04 19:08:36 2018 +0000
Revision:
13:483b2b1a6471
Parent:
12:c926d680f339
Child:
14:a16cdcd098d7
add (int) backlog; add (uint16_t) tcp_port; rm enum{TCP_PORT}

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 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 13:483b2b1a6471 43 tcp_port = 80;
aktk 13:483b2b1a6471 44 backlog = 1;
aktk 0:cc483bea4fe3 45 }
aktk 0:cc483bea4fe3 46
aktk 0:cc483bea4fe3 47 HttpServer::~HttpServer()
aktk 0:cc483bea4fe3 48 {
aktk 0:cc483bea4fe3 49 }
aktk 0:cc483bea4fe3 50
aktk 0:cc483bea4fe3 51 bool HttpServer::init()
aktk 0:cc483bea4fe3 52 {
aktk 0:cc483bea4fe3 53
aktk 0:cc483bea4fe3 54 // Ethernet Initialization
aktk 0:cc483bea4fe3 55 // Ethernet Connecting setup
aktk 12:c926d680f339 56 if(net.connect()) {
aktk 1:3a1fe94c6e42 57 printf("(HTTP_SERVER) Error!@EthernetInterface::connect()\r\n");
aktk 0:cc483bea4fe3 58 return false;
aktk 0:cc483bea4fe3 59 } else {
aktk 12:c926d680f339 60 printf("(HTTP_SERVER) IP Address is %s\r\n", net.getIPAddress());
aktk 0:cc483bea4fe3 61 }
aktk 0:cc483bea4fe3 62 // TCP Socket setup
aktk 0:cc483bea4fe3 63 // To open Server-side PORT
aktk 13:483b2b1a6471 64 if(server.bind(tcp_port)< 0) {
aktk 1:3a1fe94c6e42 65 printf("(HTTP_SERVER) Error!@TCPSocketServer::bind()\r\n");
aktk 0:cc483bea4fe3 66 return false;
aktk 0:cc483bea4fe3 67 } else {
aktk 1:3a1fe94c6e42 68 printf("(HTTP_SERVER) TCP Server has bounden!\r\n");
aktk 0:cc483bea4fe3 69 }
aktk 0:cc483bea4fe3 70 // Server start listening Request from a web browser.
aktk 13:483b2b1a6471 71 if(server.listen(backlog) < 0) {
aktk 1:3a1fe94c6e42 72 printf("(HTTP_SERVER) tcp server listen failed.\r\n");
aktk 0:cc483bea4fe3 73 return false;
aktk 0:cc483bea4fe3 74 } else {
aktk 0:cc483bea4fe3 75 listening_flag = true;
aktk 1:3a1fe94c6e42 76 printf("(HTTP_SERVER) tcp server is listening...\r\n");
aktk 0:cc483bea4fe3 77 }
aktk 0:cc483bea4fe3 78
aktk 0:cc483bea4fe3 79 return true;
aktk 0:cc483bea4fe3 80 }
aktk 0:cc483bea4fe3 81
aktk 0:cc483bea4fe3 82 bool HttpServer::run()
aktk 0:cc483bea4fe3 83 {
aktk 0:cc483bea4fe3 84 DigitalOut led1(LED1);
aktk 0:cc483bea4fe3 85 DigitalOut led2(LED1);
aktk 0:cc483bea4fe3 86
aktk 0:cc483bea4fe3 87 while (listening_flag) {
aktk 0:cc483bea4fe3 88 led1 = true;
aktk 0:cc483bea4fe3 89 // blocking mode (never timeout)
aktk 0:cc483bea4fe3 90 // waiting client connection
aktk 1:3a1fe94c6e42 91 printf("(HTTP_SERVER) waiting connection\r\n");
aktk 12:c926d680f339 92 if(server.accept(tcpcon) < 0) {
aktk 1:3a1fe94c6e42 93 printf("(HTTP_SERVER) failed to accept connection.\r\n");
aktk 0:cc483bea4fe3 94 return -1;
aktk 0:cc483bea4fe3 95 } else {
aktk 12:c926d680f339 96 printf("(HTTP_SERVER) connection success!\r\nIP: %s\r\n",client.get_address());
aktk 0:cc483bea4fe3 97 led2 = true;
aktk 0:cc483bea4fe3 98 }
aktk 1:3a1fe94c6e42 99 // When conected
aktk 12:c926d680f339 100 while(client.is_connected()) {
aktk 10:4a48594c2f44 101 printf("(HTTP_SERVER) connected\r\n");
aktk 1:3a1fe94c6e42 102
aktk 0:cc483bea4fe3 103 char buffer[1024] = {0};
aktk 0:cc483bea4fe3 104 char* httpmethod = NULL;
aktk 0:cc483bea4fe3 105 char* filepath = NULL;
aktk 0:cc483bea4fe3 106 char* http_ver = NULL;
aktk 0:cc483bea4fe3 107 char* header_field_name = NULL;
aktk 0:cc483bea4fe3 108 char* header_field_val = NULL;
aktk 1:3a1fe94c6e42 109
aktk 0:cc483bea4fe3 110 //
aktk 0:cc483bea4fe3 111 // Request Analysis
aktk 0:cc483bea4fe3 112 //
aktk 10:4a48594c2f44 113 DEBUG_PRINT_LINE("DEBUG MODE");
aktk 12:c926d680f339 114 switch(client.receive(buffer, 1023)) {
aktk 0:cc483bea4fe3 115 case 0:
aktk 10:4a48594c2f44 116 DEBUG_PRINT_LINE("recieved buffer is empty.");
aktk 0:cc483bea4fe3 117 msger.setStatusLine(400, "No Request");
aktk 10:4a48594c2f44 118 if(msger.setHeaderField("Connection", "Close"))DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
aktk 0:cc483bea4fe3 119 httpmethod = NULL;
aktk 0:cc483bea4fe3 120 filepath = NULL;
aktk 0:cc483bea4fe3 121 http_ver = NULL;
aktk 0:cc483bea4fe3 122 break;
aktk 0:cc483bea4fe3 123 case -1:
aktk 10:4a48594c2f44 124 DEBUG_PRINT_LINE("failed to read data from client.");
aktk 0:cc483bea4fe3 125 msger.setStatusLine(500, "Internal Server Error");
aktk 10:4a48594c2f44 126 if(msger.setHeaderField("Connection", "Close"))DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
aktk 0:cc483bea4fe3 127 httpmethod = NULL;
aktk 0:cc483bea4fe3 128 filepath = NULL;
aktk 0:cc483bea4fe3 129 http_ver = NULL;
aktk 0:cc483bea4fe3 130 break;
aktk 0:cc483bea4fe3 131 default:
aktk 10:4a48594c2f44 132 DEBUG_PRINT_LINE("Recieved Data: %d",strlen(buffer));
aktk 10:4a48594c2f44 133 DEBUG_PRINT_LINE("-->\r\n");
aktk 10:4a48594c2f44 134 DEBUG_PRINT_LINE("%.*s[End of Request]",strlen(buffer),buffer);
aktk 10:4a48594c2f44 135 // get HTTP method, File path, HTTP version
aktk 0:cc483bea4fe3 136 httpmethod = strtok(buffer," ");
aktk 0:cc483bea4fe3 137 filepath = strtok(NULL, " ");
aktk 0:cc483bea4fe3 138 http_ver = strtok(NULL, "\r\n");
aktk 10:4a48594c2f44 139 DEBUG_PRINT_LINE("httpmethod: %s", httpmethod);
aktk 10:4a48594c2f44 140 DEBUG_PRINT_LINE("file path: %s", filepath);
aktk 10:4a48594c2f44 141 DEBUG_PRINT_LINE("http ver : %s", http_ver);
aktk 0:cc483bea4fe3 142 break;
aktk 0:cc483bea4fe3 143 }
aktk 1:3a1fe94c6e42 144
aktk 0:cc483bea4fe3 145 //
aktk 0:cc483bea4fe3 146 // Response
aktk 0:cc483bea4fe3 147 //
aktk 0:cc483bea4fe3 148 if (strcmp(httpmethod,"GET") == 0 ) {
aktk 10:4a48594c2f44 149 DEBUG_PRINT_LINE("GET request incomming.");
aktk 0:cc483bea4fe3 150
aktk 0:cc483bea4fe3 151 // file calibration
aktk 10:4a48594c2f44 152 DEBUG_PRINT_LINE("file opening");
aktk 0:cc483bea4fe3 153 fhandl.open(filepath,"rb");
aktk 0:cc483bea4fe3 154 if(fhandl.arrival()) {
aktk 0:cc483bea4fe3 155 msger.setStatusLine(200, "OK");
aktk 10:4a48594c2f44 156 if(msger.setHeaderField("Content-Length", fhandl.getFileSize())) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
aktk 10:4a48594c2f44 157 if(msger.setHeaderField("Connection", "keep-alive")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
aktk 0:cc483bea4fe3 158 } else {
aktk 10:4a48594c2f44 159 if(msger.setStatusLine(404, "NOT FOUND")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
aktk 10:4a48594c2f44 160 if(msger.setHeaderField("Connection", "Close")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
aktk 10:4a48594c2f44 161 DEBUG_PRINT_LINE("NOT FOUND");
aktk 0:cc483bea4fe3 162 }
aktk 10:4a48594c2f44 163 if( !strcmp(fhandl.getSuffix(), "htm" ) ||
aktk 10:4a48594c2f44 164 !strcmp(fhandl.getSuffix(), "HTM" ) ||
aktk 10:4a48594c2f44 165 !strcmp(fhandl.getSuffix(), "html") ||
aktk 10:4a48594c2f44 166 !strcmp(fhandl.getSuffix(), "HTML")){
aktk 10:4a48594c2f44 167 if(msger.setHeaderField("Content-Type", "text/html")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
aktk 10:4a48594c2f44 168 } else if( !strcmp(fhandl.getSuffix(), "js" )){
aktk 10:4a48594c2f44 169 if(msger.setHeaderField("Content-Type", "text/javascript")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
aktk 10:4a48594c2f44 170 } else if ( !strcmp(fhandl.getSuffix(), "ico" )){
aktk 10:4a48594c2f44 171 if(msger.setHeaderField("Content-Type", "image/png")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
aktk 10:4a48594c2f44 172 } else if ( !strcmp(fhandl.getSuffix(), "png" ) ||
aktk 10:4a48594c2f44 173 !strcmp(fhandl.getSuffix(), "PNG" )){
aktk 10:4a48594c2f44 174 if(msger.setHeaderField("Content-Type", "image/png")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
aktk 10:4a48594c2f44 175 } else if ( !strcmp(fhandl.getSuffix(), "jpg" ) ||
aktk 10:4a48594c2f44 176 !strcmp(fhandl.getSuffix(), "JPG" )){
aktk 10:4a48594c2f44 177 if(msger.setHeaderField("Content-Type", "image/jpg")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
aktk 0:cc483bea4fe3 178 } else {
aktk 0:cc483bea4fe3 179 msger.setStatusLine(406, "not acceptable");
aktk 0:cc483bea4fe3 180 }
aktk 0:cc483bea4fe3 181
aktk 0:cc483bea4fe3 182 // Connection timeout field
aktk 10:4a48594c2f44 183 if(msger.setHeaderField("Keep-Alive", "timeouit=15")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
aktk 1:3a1fe94c6e42 184
aktk 0:cc483bea4fe3 185 // send response
aktk 0:cc483bea4fe3 186 msger.sendHTTPResponse(tcpcon, fhandl);
aktk 0:cc483bea4fe3 187
aktk 0:cc483bea4fe3 188 //file close
aktk 7:184c6f1ace94 189 if( fhandl.close()== 0)
aktk 10:4a48594c2f44 190 DEBUG_PRINT_LINE("file has closed");
aktk 0:cc483bea4fe3 191 else if(EOF)
aktk 10:4a48594c2f44 192 DEBUG_PRINT_LINE("failed to close the file");
aktk 7:184c6f1ace94 193
aktk 7:184c6f1ace94 194 msger.resetHeader();
aktk 10:4a48594c2f44 195 DEBUG_PRINT_LINE("echo back done.");
aktk 7:184c6f1ace94 196 }
aktk 7:184c6f1ace94 197 if (httpmethod == NULL) {
aktk 7:184c6f1ace94 198 msger.sendHTTPResponse(tcpcon);
aktk 0:cc483bea4fe3 199 msger.resetHeader();
aktk 10:4a48594c2f44 200 DEBUG_PRINT_LINE("echo back done.");
aktk 0:cc483bea4fe3 201 }
aktk 1:3a1fe94c6e42 202 printf("(HTTP_SERVER) Response to Request has done\r\n");
aktk 7:184c6f1ace94 203 //
aktk 7:184c6f1ace94 204 //
aktk 7:184c6f1ace94 205 //
aktk 0:cc483bea4fe3 206 }
aktk 1:3a1fe94c6e42 207 printf("(HTTP_SERVER) close connection.\r\ntcp server is listening...\r\n");
aktk 12:c926d680f339 208 client.close();
aktk 0:cc483bea4fe3 209 led2 = false;
aktk 0:cc483bea4fe3 210 }
aktk 12:c926d680f339 211 server.close();
aktk 7:184c6f1ace94 212 listening_flag = false;
aktk 0:cc483bea4fe3 213 led1 = false;
aktk 0:cc483bea4fe3 214 return 0;
aktk 0:cc483bea4fe3 215 }