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