
HTTP File Server using SD Card for Arch Max
Dependencies: EthernetInterface SDFileSystem mbed-rtos mbed
Fork of HTTP_SDcard_file_server by
main.cpp
00001 #include "mbed.h" 00002 #include "EthernetInterface.h" 00003 #include "SDFileSystem.h" 00004 00005 #define EnDebugMSG false //true-> print debug message to PC USB terminal, false->not print 00006 #include "filelib.h" 00007 00008 #define IP "192.168.100.100" 00009 #define MASK "255.255.255.0" 00010 #define GATEWAY "192.168.100.1" 00011 #define PORT 80 00012 00013 Serial pc (USBTX,USBRX); // tx, rx 00014 SDFileSystem sd(SD_MOSI, SD_MISO, SD_SCK, SD_CS, "wfs"); // the pinout on the mbed 00015 00016 char sMethod[7]; 00017 char sURL[250]; 00018 char sProtocol[8]; 00019 00020 EthernetInterface eth; 00021 00022 TCPSocketServer svr; 00023 bool serverIsListened = false; 00024 00025 TCPSocketConnection client; 00026 bool clientIsConnected = false; 00027 00028 char sentBuffer[1608] = {}; // 2*536=1072, 3*536=1608, 4*536=2144 !1500 00029 char line_response[256]= {0}; 00030 char file_path[256] = {0}; 00031 00032 DigitalOut led1(LED1); //server listning status 00033 DigitalOut led2(LED2); //socket connecting status 00034 00035 Ticker ledTick; 00036 00037 void ledTickfunc() 00038 { 00039 if(serverIsListened) { 00040 led1 = !led1; 00041 } else { 00042 led1 = false; 00043 } 00044 } 00045 00046 void send_HTTP_header(char* protocol, int code, char* title, char* mime_type, long long lengthBody) 00047 { 00048 snprintf(line_response, sizeof(line_response),"%s %d %s\r\n", protocol, code, title ); 00049 snprintf(sentBuffer, sizeof(sentBuffer),"%s",line_response); 00050 00051 if ( mime_type != NULL ) { 00052 snprintf(line_response, sizeof(line_response), "Content-Type: %s\r\n", mime_type ); 00053 snprintf(sentBuffer, sizeof(sentBuffer), "%s%s",sentBuffer,line_response); //append to sentBuffer 00054 } 00055 if ( lengthBody >= 0 ) { 00056 snprintf(line_response, sizeof(line_response), "Content-Length: %lld\r\n", lengthBody ); 00057 snprintf(sentBuffer, sizeof(sentBuffer), "%s%s",sentBuffer,line_response); //append to sentBuffer 00058 } 00059 snprintf(line_response, sizeof(line_response), "Connection: close\r\n" ); 00060 snprintf(sentBuffer, sizeof(sentBuffer),"%s%s\r\n",sentBuffer,line_response); //append to sentBuffer 00061 00062 if (EnDebugMSG) 00063 printf("\n-->sent Header--\n"); 00064 00065 client.send_all(sentBuffer,strlen(sentBuffer)); 00066 if (EnDebugMSG) { 00067 printf(sentBuffer); 00068 printf("\n--end Header-- bytes:%d",strlen(sentBuffer)); 00069 } 00070 Thread::wait(200); //200ms important for browser! 00071 } 00072 00073 void send_HTML_line(char* line, unsigned int length_line) 00074 { 00075 client.send_all(line,length_line); 00076 if (EnDebugMSG) 00077 printf("\n-->send HTML line:\n%s ...Ok!",line); 00078 Thread::wait(10); 00079 } 00080 00081 void send_HTML_error( int status_code, char* title, char* body_text) 00082 { 00083 send_HTTP_header("HTTP/1.1", status_code, title, "text/html", -1); 00084 if (EnDebugMSG) 00085 printf("\n-->send_error...\n"); 00086 sentBuffer[0]=NULL; //clear buffer 00087 sprintf(line_response, "<!DOCTYPE html>\r\n<html>\r\n<head>\r\n<title>%d %s</title>\r\n</head>\r\n", status_code, title); 00088 snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer 00089 sprintf(line_response, "<body><center><h2><center>%d %s</center></h2>\r\n",status_code, title ); 00090 snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer 00091 sprintf(line_response, "%s\r\n", body_text ); 00092 snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer 00093 sprintf(line_response, "<p>mbed HTTP File Server</p>\r\n</center></body></html>\r\n"); 00094 snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer 00095 send_HTML_line(sentBuffer, strlen(sentBuffer)); 00096 } 00097 00098 int send_file(char *path_file) 00099 { 00100 char *mime_type = {0}; 00101 unsigned int bytes_for_send=0; 00102 long long filesize, all_send_bytes = 0; 00103 00104 mime_type = get_mime_type( path_file ); 00105 snprintf(file_path, sizeof(file_path),"/wfs/%s",path_file); 00106 if (EnDebugMSG) { 00107 printf("\n-->from send_file:%s",file_path); 00108 printf("\n-->from send_file mime type:%s",mime_type); 00109 } 00110 00111 if (Mystat(path_file, &myStatBuf)) { //fault with file 00112 send_HTML_error( 403, "Forbidden", "403 - File access forbidden."); 00113 return 403; 00114 } 00115 FILE* fp = NULL; 00116 fp = fopen(file_path,"r"); 00117 if (fp==NULL ) { 00118 send_HTML_error( 403, "Forbidden", "403 - File access forbidden."); 00119 return 403; 00120 } 00121 00122 filesize = myStatBuf.st_size; 00123 send_HTTP_header("HTTP/1.1", 200, "Ok", mime_type, myStatBuf.st_size); 00124 //binary send 00125 all_send_bytes=0; 00126 while(filesize) { //check for EOF !feof(fp) 00127 bytes_for_send = filesize; 00128 if (bytes_for_send > sizeof(sentBuffer)) { 00129 bytes_for_send = sizeof(sentBuffer); 00130 } 00131 fread (sentBuffer,1,bytes_for_send,fp); 00132 filesize -= bytes_for_send; 00133 if (EnDebugMSG) 00134 printf("\n---bytes_for_send...%d",bytes_for_send); 00135 client.send_all(sentBuffer,bytes_for_send); 00136 //Thread::wait(10); 00137 all_send_bytes += bytes_for_send; 00138 } 00139 if (EnDebugMSG) 00140 printf("\n---buffer fill end - all ...%lld", all_send_bytes); 00141 //binary send 00142 00143 sprintf(line_response, "\r\n"); 00144 client.send_all(line_response,strlen(line_response)); 00145 if ( fp != NULL ) 00146 fclose(fp); 00147 //Thread::wait(10); 00148 return 0; 00149 } 00150 00151 int send_directory(char *path) 00152 { 00153 char process_name[64]= {0}; 00154 00155 char posOfLastSlash; 00156 char *pLS; 00157 00158 struct dirent *p; 00159 struct sMystat sb; 00160 struct tm *timeinfo; 00161 char timeBuf[40]; 00162 00163 if (EnDebugMSG) 00164 printf("\n-->from send_directory:%s",path); 00165 snprintf(file_path,sizeof(file_path),"/wfs%s",path); 00166 DIR *d = opendir(file_path); 00167 if (EnDebugMSG && d!=NULL) 00168 printf("\n-->from send_directory:%s ...open OK",file_path); 00169 if (d==NULL) { //error open dir 00170 send_HTML_error( 403, "Forbidden", "403 - Directory access forbidden."); 00171 return -1; 00172 } 00173 send_HTTP_header("HTTP/1.1", 200, "Ok",NULL, -1); 00174 sentBuffer[0]=NULL; 00175 sprintf(line_response,"<!DOCTYPE html>\r\n<html>\n<head><title>Index of %s</title>\n",path); 00176 snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer 00177 00178 sprintf(line_response,"<meta content=\"text/html; charset=iso-8859-1\" http-equiv=\"Content-Type\"></head>\n"); 00179 snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer 00180 00181 00182 sprintf(line_response,"<body><center>\n<h3>Index of %s</h3>\n", path); 00183 snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer 00184 send_HTML_line(sentBuffer, strlen(sentBuffer)); 00185 //begin table 00186 sentBuffer[0]=NULL; //clear buffer 00187 sprintf(line_response,"<table border=\"0\">\n"); 00188 snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer 00189 sprintf(line_response,"<tr><th align=\"left\" width=\"200\">Name</th><th align=\"right\" width=\"100\">Size(bytes)</th><th align=\"right\" width=\"200\">Date/Time</th></tr>\n"); 00190 snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer 00191 //begin table 00192 00193 pLS=strrchr(path,'/'); 00194 posOfLastSlash=pLS-path+1; 00195 if (EnDebugMSG) 00196 printf("\r\n>>posOfLastSlash=%d",posOfLastSlash); 00197 snprintf(process_name,posOfLastSlash+1,"%s",path); 00198 if (EnDebugMSG) 00199 printf("\r\n>>process_name=%s",process_name); 00200 sprintf(line_response,"<tr><td align=\"left\"><a href=\"%s\">../</a></td></tr>\n",process_name); 00201 snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer 00202 while((p = readdir(d)) != NULL) { 00203 if (EnDebugMSG) 00204 printf("\n :%s",p->d_name); 00205 sprintf(file_path,"%s/%s",path,p->d_name); 00206 Mystat( file_path, &sb ); 00207 if (get_dirInfo(file_path)==0 ) { //this is directory path 00208 if (EnDebugMSG) 00209 printf("\nDIR"); 00210 sprintf(line_response, "<tr><td align=\"left\"><a href=\"%s\">%s</a><br></td></tr>\n",file_path,p->d_name); 00211 if (strlen(line_response)>(sizeof(sentBuffer)-strlen(sentBuffer))) { //buffer must be sent 00212 send_HTML_line(sentBuffer, strlen(sentBuffer)); 00213 sentBuffer[0]=NULL; //clear buffer 00214 } 00215 snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer 00216 00217 } else { //this is file 00218 if (EnDebugMSG) 00219 printf("\nFILE"); 00220 timeinfo = localtime (&sb.st_mtime); 00221 //strftime(timeBuf,40, "%I:%M:%S %p (%Y/%m/%d)\r\n", localtime(&sb.st_mtime)); 00222 strftime(timeBuf, 40, "%c", timeinfo); 00223 sprintf(line_response, "<tr><td align=\"left\"><a href=\"%s\">%s</a></td><td align=\"right\">%lld</td><td align=\"right\">%s</td></tr>\n", file_path, p->d_name,(long long) sb.st_size,timeBuf); // asctime(timeinfo) ); 00224 00225 if (strlen(line_response)>(sizeof(sentBuffer)-strlen(sentBuffer))) { //buffer must be sent 00226 send_HTML_line(sentBuffer, strlen(sentBuffer)); 00227 sentBuffer[0]=NULL; //clear buffer 00228 } 00229 snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer 00230 } 00231 } 00232 send_HTML_line(sentBuffer, strlen(sentBuffer)); 00233 closedir(d); 00234 00235 sprintf(line_response, "</table>\n<br><h4>mbed HTTP File Server</h4>\n</center></body></html>\n"); 00236 send_HTML_line(line_response, strlen(line_response)); 00237 00238 return 0; 00239 } 00240 00241 void parseHTTPRequest(char* buffer) 00242 { 00243 char spacePos; 00244 char *tmpBuffer; 00245 spacePos = strcspn(buffer, " ") + 1; //position of first space character 00246 snprintf(sMethod, spacePos,"%s", buffer); 00247 00248 //get Protocol 00249 tmpBuffer=&(buffer[spacePos]); //move pointer to buffer (delete Method) 00250 spacePos = strcspn(tmpBuffer, "\r\n") + 1; 00251 tmpBuffer[spacePos]='\0'; //set end of string ...cut 00252 sprintf(sProtocol, "%s", strrchr(tmpBuffer,' ')); //get string after last (space ) 00253 printf("\r\nsProtocol:%s", tmpBuffer); 00254 buffer = &(sProtocol[1]); //cut first character (space) 00255 sprintf(sProtocol, "%s", buffer); 00256 00257 //get URL 00258 snprintf(sURL,strlen(tmpBuffer)-strlen(sProtocol),"%s\r\n", tmpBuffer); //URL is between Method and Protocol 00259 00260 printf("\nParse Method:%s",sMethod); 00261 printf("\nParse URL:%s",sURL); 00262 printf("\nParse PROTOCOL:%s",sProtocol); 00263 printf("\n\r\n"); 00264 } 00265 00266 int processHTTP(char* sMethod, char* sURL, char* sProtocol) 00267 { 00268 int gdi, gfi; //status of get_dir_info(xxx), and get_file_info(xxx) 00269 00270 if (strcmp(sMethod,"GET")!=0) { 00271 send_HTML_error( 501, "501 Not Implemented", "501 - The server either does not recognize the request method"); 00272 return 501; 00273 } 00274 if (sURL[0]!= '/') { 00275 send_HTML_error( 400, "Bad Request", "400 - The request cannot be fulfilled due to bad syntax."); 00276 return 400; 00277 } 00278 if (sURL[strlen(sURL)-1]=='/') { 00279 sURL[strlen(sURL)-1]=sURL[strlen(sURL)]; //delete last symbol 00280 if (EnDebugMSG) 00281 printf("\n delete last:%s",sURL); 00282 } 00283 gdi= get_dirInfo(sURL); 00284 gfi= get_fileInfo(sURL); 00285 if (gfi!=0) { //!=0 file not found 00286 if (gdi==0) { //0-ok this is directory 00287 return send_directory(sURL); 00288 } 00289 if (EnDebugMSG) 00290 printf("\n404-br File not found or...(Fresult is:%d)",gfi); 00291 send_HTML_error( 404, "Not Found","404 - The requested resource could not be found."); 00292 return 404; 00293 } else { //==0 found 00294 if (gdi==0) //0-ok this is directory 00295 return send_directory(sURL); 00296 else 00297 return send_file(sURL); 00298 } 00299 } 00300 00301 int main() 00302 { 00303 printf("\r\n---- HTTP Server ----\r\n"); 00304 00305 ledTick.attach(&ledTickfunc,0.5); 00306 //ledTick.detach(); 00307 //setup ethernet interface 00308 eth.init(); //Use DHCP 00309 // eth.init(IP,MASK,GATEWAY); //IP,mask,Gateway 00310 eth.connect(); 00311 printf("IP Address is %s\n\r", eth.getIPAddress()); 00312 00313 //setup tcp socket 00314 if(svr.bind(PORT)< 0) { 00315 printf("tcp server bind failed.\n\r"); 00316 return -1; 00317 } else { 00318 printf("tcp server bind successed.\n\r"); 00319 serverIsListened = true; 00320 } 00321 00322 if(svr.listen(1) < 0) { 00323 printf("tcp server listen failed.\n\r"); 00324 return -1; 00325 } else { 00326 printf("tcp server is listening...\n\r"); 00327 } 00328 00329 //listening for http GET request 00330 while (serverIsListened) { 00331 //blocking mode(never timeout) 00332 if(svr.accept(client)<0) { 00333 printf("failed to accept connection.\n\r"); 00334 } else { 00335 //client.set_blocking(false,5000); //5000=5sec 00336 printf("connection success!\n\rIP: %s\n\r",client.get_address()); 00337 clientIsConnected = true; 00338 led2 = true; 00339 while(clientIsConnected) { 00340 char buffer[1024] = {}; 00341 switch(client.receive(buffer, 1023)) { 00342 case 0: 00343 printf("recieved buffer is empty.\n\r"); 00344 clientIsConnected = false; 00345 break; 00346 case -1: 00347 printf("failed to read data from client.\n\r"); 00348 clientIsConnected = false; 00349 break; 00350 default: 00351 printf("Recieved Data: %d\n\r\n\r%.*s\n\r",strlen(buffer),strlen(buffer),buffer); 00352 parseHTTPRequest(buffer); 00353 //if(buffer[0] == 'G' && buffer[1] == 'E' && buffer[2] == 'T' ) { 00354 if (strcmp(sMethod, "GET" ) == 0 ) { 00355 printf("GET request incomming.\n\r"); 00356 processHTTP(sMethod, sURL, sProtocol); 00357 clientIsConnected = false; 00358 }//if get 00359 break; 00360 } //switch 00361 //ledTick.attach(&ledTickfunc,0.5); 00362 }//while 00363 printf("close connection.\n\rHTTP server is listening...\n\r\n"); 00364 client.close(); 00365 Thread::wait(50); 00366 led2 = false; 00367 } 00368 } 00369 00370 }
Generated on Wed Jul 13 2022 06:12:20 by
