httpServer.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include "socket.h"
  5. #include "wizchip_conf.h"
  6. #include "httpServer.h"
  7. #include "httpParser.h"
  8. #include "httpUtil.h"
  9. #ifdef _USE_SDCARD_
  10. #include "ff.h" // header file for FatFs library (FAT file system)
  11. #endif
  12. #ifndef DATA_BUF_SIZE
  13. #define DATA_BUF_SIZE 2048
  14. #endif
  15. /*****************************************************************************
  16. * Private types/enumerations/variables
  17. ****************************************************************************/
  18. static uint8_t HTTPSock_Num[_WIZCHIP_SOCK_NUM_] = {0, };
  19. static st_http_request * http_request; /**< Pointer to received HTTP request */
  20. static st_http_request * parsed_http_request; /**< Pointer to parsed HTTP request */
  21. static uint8_t * http_response; /**< Pointer to HTTP response */
  22. // ## For Debugging
  23. //static uint8_t uri_buf[128];
  24. // Number of registered web content in code flash memory
  25. static uint16_t total_content_cnt = 0;
  26. /*****************************************************************************
  27. * Public types/enumerations/variables
  28. ****************************************************************************/
  29. uint8_t * pHTTP_TX;
  30. uint8_t * pHTTP_RX;
  31. volatile uint32_t httpServer_tick_1s = 0;
  32. st_http_socket HTTPSock_Status[_WIZCHIP_SOCK_NUM_] = { {STATE_HTTP_IDLE, }, };
  33. httpServer_webContent web_content[MAX_CONTENT_CALLBACK];
  34. #ifdef _USE_SDCARD_
  35. FIL fs; // FatFs: File object
  36. FRESULT fr; // FatFs: File function return code
  37. #endif
  38. /*****************************************************************************
  39. * Private functions
  40. ****************************************************************************/
  41. void httpServer_Sockinit(uint8_t cnt, uint8_t * socklist);
  42. static uint8_t getHTTPSocketNum(uint8_t seqnum);
  43. static int8_t getHTTPSequenceNum(uint8_t socket);
  44. static int8_t http_disconnect(uint8_t sn);
  45. static void http_process_handler(uint8_t s, st_http_request * p_http_request);
  46. static void send_http_response_header(uint8_t s, uint8_t content_type, uint32_t body_len, uint16_t http_status);
  47. static void send_http_response_body(uint8_t s, uint8_t * uri_name, uint8_t * buf, uint32_t start_addr, uint32_t file_len);
  48. static void send_http_response_cgi(uint8_t s, uint8_t * buf, uint8_t * http_body, uint16_t file_len);
  49. /*****************************************************************************
  50. * Public functions
  51. ****************************************************************************/
  52. // Callback functions definition: MCU Reset / WDT Reset
  53. void default_mcu_reset(void) {;}
  54. void default_wdt_reset(void) {;}
  55. void (*HTTPServer_ReStart)(void) = default_mcu_reset;
  56. void (*HTTPServer_WDT_Reset)(void) = default_wdt_reset;
  57. void httpServer_Sockinit(uint8_t cnt, uint8_t * socklist)
  58. {
  59. uint8_t i;
  60. for(i = 0; i < cnt; i++)
  61. {
  62. // Mapping the H/W socket numbers to the sequential index numbers
  63. HTTPSock_Num[i] = socklist[i];
  64. }
  65. }
  66. static uint8_t getHTTPSocketNum(uint8_t seqnum)
  67. {
  68. // Return the 'H/W socket number' corresponding to the index number
  69. return HTTPSock_Num[seqnum];
  70. }
  71. static int8_t getHTTPSequenceNum(uint8_t socket)
  72. {
  73. uint8_t i;
  74. for(i = 0; i < _WIZCHIP_SOCK_NUM_; i++)
  75. if(HTTPSock_Num[i] == socket) return i;
  76. return -1;
  77. }
  78. void httpServer_init(uint8_t * tx_buf, uint8_t * rx_buf, uint8_t cnt, uint8_t * socklist)
  79. {
  80. // User's shared buffer
  81. pHTTP_TX = tx_buf;
  82. pHTTP_RX = rx_buf;
  83. // H/W Socket number mapping
  84. httpServer_Sockinit(cnt, socklist);
  85. }
  86. /* Register the call back functions for HTTP Server */
  87. void reg_httpServer_cbfunc(void(*mcu_reset)(void), void(*wdt_reset)(void))
  88. {
  89. // Callback: HW Reset and WDT reset function for each MCU platforms
  90. if(mcu_reset) HTTPServer_ReStart = mcu_reset;
  91. if(wdt_reset) HTTPServer_WDT_Reset = wdt_reset;
  92. }
  93. void httpServer_run(uint8_t seqnum)
  94. {
  95. uint8_t s; // socket number
  96. uint16_t len;
  97. uint32_t gettime = 0;
  98. #ifdef _HTTPSERVER_DEBUG_
  99. uint8_t destip[4] = {0, };
  100. uint16_t destport = 0;
  101. #endif
  102. http_request = (st_http_request *)pHTTP_RX; // Structure of HTTP Request
  103. parsed_http_request = (st_http_request *)pHTTP_TX;
  104. // Get the H/W socket number
  105. s = getHTTPSocketNum(seqnum);
  106. /* HTTP Service Start */
  107. switch(getSn_SR(s))
  108. {
  109. case SOCK_ESTABLISHED:
  110. // Interrupt clear
  111. if(getSn_IR(s) & Sn_IR_CON)
  112. {
  113. setSn_IR(s, Sn_IR_CON);
  114. }
  115. // HTTP Process states
  116. switch(HTTPSock_Status[seqnum].sock_status)
  117. {
  118. case STATE_HTTP_IDLE :
  119. if ((len = getSn_RX_RSR(s)) > 0)
  120. {
  121. if (len > DATA_BUF_SIZE) len = DATA_BUF_SIZE;
  122. len = recv(s, (uint8_t *)http_request, len);
  123. *(((uint8_t *)http_request) + len) = '\0';
  124. parse_http_request(parsed_http_request, (uint8_t *)http_request);
  125. #ifdef _HTTPSERVER_DEBUG_
  126. getSn_DIPR(s, destip);
  127. destport = getSn_DPORT(s);
  128. printf("\r\n");
  129. printf("> HTTPSocket[%d] : HTTP Request received ", s);
  130. printf("from %d.%d.%d.%d : %d\r\n", destip[0], destip[1], destip[2], destip[3], destport);
  131. #endif
  132. #ifdef _HTTPSERVER_DEBUG_
  133. printf("> HTTPSocket[%d] : [State] STATE_HTTP_REQ_DONE\r\n", s);
  134. #endif
  135. // HTTP 'response' handler; includes send_http_response_header / body function
  136. http_process_handler(s, parsed_http_request);
  137. gettime = get_httpServer_timecount();
  138. // Check the TX socket buffer for End of HTTP response sends
  139. while(getSn_TX_FSR(s) != (getSn_TxMAX(s)))
  140. {
  141. if((get_httpServer_timecount() - gettime) > 3)
  142. {
  143. #ifdef _HTTPSERVER_DEBUG_
  144. printf("> HTTPSocket[%d] : [State] STATE_HTTP_REQ_DONE: TX Buffer clear timeout\r\n", s);
  145. #endif
  146. break;
  147. }
  148. }
  149. if(HTTPSock_Status[seqnum].file_len > 0) HTTPSock_Status[seqnum].sock_status = STATE_HTTP_RES_INPROC;
  150. else HTTPSock_Status[seqnum].sock_status = STATE_HTTP_RES_DONE; // Send the 'HTTP response' end
  151. }
  152. break;
  153. case STATE_HTTP_RES_INPROC :
  154. /* Repeat: Send the remain parts of HTTP responses */
  155. #ifdef _HTTPSERVER_DEBUG_
  156. printf("> HTTPSocket[%d] : [State] STATE_HTTP_RES_INPROC\r\n", s);
  157. #endif
  158. // Repeatedly send remaining data to client
  159. send_http_response_body(s, 0, http_response, 0, 0);
  160. if(HTTPSock_Status[seqnum].file_len == 0) HTTPSock_Status[seqnum].sock_status = STATE_HTTP_RES_DONE;
  161. break;
  162. case STATE_HTTP_RES_DONE :
  163. #ifdef _HTTPSERVER_DEBUG_
  164. printf("> HTTPSocket[%d] : [State] STATE_HTTP_RES_DONE\r\n", s);
  165. #endif
  166. // Socket file info structure re-initialize
  167. HTTPSock_Status[seqnum].file_len = 0;
  168. HTTPSock_Status[seqnum].file_offset = 0;
  169. HTTPSock_Status[seqnum].file_start = 0;
  170. HTTPSock_Status[seqnum].sock_status = STATE_HTTP_IDLE;
  171. //#ifdef _USE_SDCARD_
  172. // f_close(&fs);
  173. //#endif
  174. #ifdef _USE_WATCHDOG_
  175. HTTPServer_WDT_Reset();
  176. #endif
  177. http_disconnect(s);
  178. break;
  179. default :
  180. break;
  181. }
  182. break;
  183. case SOCK_CLOSE_WAIT:
  184. #ifdef _HTTPSERVER_DEBUG_
  185. printf("> HTTPSocket[%d] : ClOSE_WAIT\r\n", s); // if a peer requests to close the current connection
  186. #endif
  187. disconnect(s);
  188. break;
  189. case SOCK_CLOSED:
  190. #ifdef _HTTPSERVER_DEBUG_
  191. printf("> HTTPSocket[%d] : CLOSED\r\n", s);
  192. #endif
  193. if(socket(s, Sn_MR_TCP, HTTP_SERVER_PORT, 0x00) == s) /* Reinitialize the socket */
  194. {
  195. #ifdef _HTTPSERVER_DEBUG_
  196. printf("> HTTPSocket[%d] : OPEN\r\n", s);
  197. #endif
  198. }
  199. break;
  200. case SOCK_INIT:
  201. listen(s);
  202. break;
  203. case SOCK_LISTEN:
  204. break;
  205. default :
  206. break;
  207. } // end of switch
  208. #ifdef _USE_WATCHDOG_
  209. HTTPServer_WDT_Reset();
  210. #endif
  211. }
  212. ////////////////////////////////////////////
  213. // Private Functions
  214. ////////////////////////////////////////////
  215. static void send_http_response_header(uint8_t s, uint8_t content_type, uint32_t body_len, uint16_t http_status)
  216. {
  217. switch(http_status)
  218. {
  219. case STATUS_OK: // HTTP/1.1 200 OK
  220. if((content_type != PTYPE_CGI) && (content_type != PTYPE_XML)) // CGI/XML type request does not respond HTTP header
  221. {
  222. #ifdef _HTTPSERVER_DEBUG_
  223. printf("> HTTPSocket[%d] : HTTP Response Header - STATUS_OK\r\n", s);
  224. #endif
  225. make_http_response_head((char*)http_response, content_type, body_len);
  226. }
  227. else
  228. {
  229. #ifdef _HTTPSERVER_DEBUG_
  230. printf("> HTTPSocket[%d] : HTTP Response Header - NONE / CGI or XML\r\n", s);
  231. #endif
  232. // CGI/XML type request does not respond HTTP header to client
  233. http_status = 0;
  234. }
  235. break;
  236. case STATUS_BAD_REQ: // HTTP/1.1 400 OK
  237. #ifdef _HTTPSERVER_DEBUG_
  238. printf("> HTTPSocket[%d] : HTTP Response Header - STATUS_BAD_REQ\r\n", s);
  239. #endif
  240. memcpy(http_response, ERROR_REQUEST_PAGE, sizeof(ERROR_REQUEST_PAGE));
  241. break;
  242. case STATUS_NOT_FOUND: // HTTP/1.1 404 Not Found
  243. #ifdef _HTTPSERVER_DEBUG_
  244. printf("> HTTPSocket[%d] : HTTP Response Header - STATUS_NOT_FOUND\r\n", s);
  245. #endif
  246. memcpy(http_response, ERROR_HTML_PAGE, sizeof(ERROR_HTML_PAGE));
  247. break;
  248. default:
  249. break;
  250. }
  251. // Send the HTTP Response 'header'
  252. if(http_status)
  253. {
  254. #ifdef _HTTPSERVER_DEBUG_
  255. printf("> HTTPSocket[%d] : [Send] HTTP Response Header [ %d ]byte\r\n", s, (uint16_t)strlen((char *)http_response));
  256. #endif
  257. send(s, http_response, strlen((char *)http_response));
  258. }
  259. }
  260. static void send_http_response_body(uint8_t s, uint8_t * uri_name, uint8_t * buf, uint32_t start_addr, uint32_t file_len)
  261. {
  262. int8_t get_seqnum;
  263. uint32_t send_len;
  264. uint8_t flag_datasend_end = 0;
  265. #ifdef _USE_SDCARD_
  266. uint16_t blocklen;
  267. #endif
  268. #ifdef _USE_FLASH_
  269. uint32_t addr = 0;
  270. #endif
  271. if((get_seqnum = getHTTPSequenceNum(s)) == -1) return; // exception handling; invalid number
  272. // Send the HTTP Response 'body'; requested file
  273. if(!HTTPSock_Status[get_seqnum].file_len) // ### Send HTTP response body: First part ###
  274. {
  275. if (file_len > DATA_BUF_SIZE - 1)
  276. {
  277. HTTPSock_Status[get_seqnum].file_start = start_addr;
  278. HTTPSock_Status[get_seqnum].file_len = file_len;
  279. send_len = DATA_BUF_SIZE - 1;
  280. /////////////////////////////////////////////////////////////////////////////////////////////////
  281. // ## 20141219 Eric added, for 'File object structure' (fs) allocation reduced (8 -> 1)
  282. memset(HTTPSock_Status[get_seqnum].file_name, 0x00, MAX_CONTENT_NAME_LEN);
  283. strcpy((char *)HTTPSock_Status[get_seqnum].file_name, (char *)uri_name);
  284. #ifdef _HTTPSERVER_DEBUG_
  285. printf("> HTTPSocket[%d] : HTTP Response body - file name [ %s ]\r\n", s, HTTPSock_Status[get_seqnum].file_name);
  286. #endif
  287. /////////////////////////////////////////////////////////////////////////////////////////////////
  288. #ifdef _HTTPSERVER_DEBUG_
  289. printf("> HTTPSocket[%d] : HTTP Response body - file len [ %ld ]byte\r\n", s, file_len);
  290. #endif
  291. }
  292. else
  293. {
  294. // Send process end
  295. send_len = file_len;
  296. #ifdef _HTTPSERVER_DEBUG_
  297. printf("> HTTPSocket[%d] : HTTP Response end - file len [ %ld ]byte\r\n", s, send_len);
  298. #endif
  299. }
  300. #ifdef _USE_FLASH_
  301. if(HTTPSock_Status[get_seqnum]->storage_type == DATAFLASH) addr = start_addr;
  302. #endif
  303. }
  304. else // remained parts
  305. {
  306. #ifdef _USE_FLASH_
  307. if(HTTPSock_Status[get_seqnum]->storage_type == DATAFLASH)
  308. {
  309. addr = HTTPSock_Status[get_seqnum].file_start + HTTPSock_Status[get_seqnum].file_offset;
  310. }
  311. #endif
  312. send_len = HTTPSock_Status[get_seqnum].file_len - HTTPSock_Status[get_seqnum].file_offset;
  313. if(send_len > DATA_BUF_SIZE - 1)
  314. {
  315. send_len = DATA_BUF_SIZE - 1;
  316. //HTTPSock_Status[get_seqnum]->file_offset += send_len;
  317. }
  318. else
  319. {
  320. #ifdef _HTTPSERVER_DEBUG_
  321. printf("> HTTPSocket[%d] : HTTP Response end - file len [ %ld ]byte\r\n", s, HTTPSock_Status[get_seqnum].file_len);
  322. #endif
  323. // Send process end
  324. flag_datasend_end = 1;
  325. }
  326. #ifdef _HTTPSERVER_DEBUG_
  327. printf("> HTTPSocket[%d] : HTTP Response body - send len [ %ld ]byte\r\n", s, send_len);
  328. #endif
  329. }
  330. /*****************************************************/
  331. //HTTPSock_Status[get_seqnum]->storage_type == NONE
  332. //HTTPSock_Status[get_seqnum]->storage_type == CODEFLASH
  333. //HTTPSock_Status[get_seqnum]->storage_type == SDCARD
  334. //HTTPSock_Status[get_seqnum]->storage_type == DATAFLASH
  335. /*****************************************************/
  336. if(HTTPSock_Status[get_seqnum].storage_type == CODEFLASH)
  337. {
  338. if(HTTPSock_Status[get_seqnum].file_len) start_addr = HTTPSock_Status[get_seqnum].file_start;
  339. read_userReg_webContent(start_addr, &buf[0], HTTPSock_Status[get_seqnum].file_offset, send_len);
  340. }
  341. #ifdef _USE_SDCARD_
  342. else if(HTTPSock_Status[get_seqnum].storage_type == SDCARD)
  343. {
  344. // Data read from SD Card
  345. fr = f_read(&fs, &buf[0], send_len, (void *)&blocklen);
  346. if(fr != FR_OK)
  347. {
  348. send_len = 0;
  349. #ifdef _HTTPSERVER_DEBUG_
  350. printf("> HTTPSocket[%d] : [FatFs] Error code return: %d (File Read) / HTTP Send Failed - %s\r\n", s, fr, HTTPSock_Status[get_seqnum].file_name);
  351. #endif
  352. }
  353. else
  354. {
  355. *(buf+send_len+1) = 0; // Insert '/0' for indicates the 'End of String' (null terminated)
  356. }
  357. }
  358. #endif
  359. #ifdef _USE_FLASH_
  360. else if(HTTPSock_Status[get_seqnum]->storage_type == DATAFLASH)
  361. {
  362. // Data read from external data flash memory
  363. read_from_flashbuf(addr, &buf[0], send_len);
  364. *(buf+send_len+1) = 0; // Insert '/0' for indicates the 'End of String' (null terminated)
  365. }
  366. #endif
  367. else
  368. {
  369. send_len = 0;
  370. }
  371. // Requested content send to HTTP client
  372. #ifdef _HTTPSERVER_DEBUG_
  373. printf("> HTTPSocket[%d] : [Send] HTTP Response body [ %ld ]byte\r\n", s, send_len);
  374. #endif
  375. if(send_len) send(s, buf, send_len);
  376. else flag_datasend_end = 1;
  377. if(flag_datasend_end)
  378. {
  379. HTTPSock_Status[get_seqnum].file_start = 0;
  380. HTTPSock_Status[get_seqnum].file_len = 0;
  381. HTTPSock_Status[get_seqnum].file_offset = 0;
  382. flag_datasend_end = 0;
  383. }
  384. else
  385. {
  386. HTTPSock_Status[get_seqnum].file_offset += send_len;
  387. #ifdef _HTTPSERVER_DEBUG_
  388. printf("> HTTPSocket[%d] : HTTP Response body - offset [ %ld ]\r\n", s, HTTPSock_Status[get_seqnum].file_offset);
  389. #endif
  390. }
  391. // ## 20141219 Eric added, for 'File object structure' (fs) allocation reduced (8 -> 1)
  392. #ifdef _USE_SDCARD_
  393. f_close(&fs);
  394. #endif
  395. // ## 20141219 added end
  396. }
  397. static void send_http_response_cgi(uint8_t s, uint8_t * buf, uint8_t * http_body, uint16_t file_len)
  398. {
  399. uint16_t send_len = 0;
  400. #ifdef _HTTPSERVER_DEBUG_
  401. printf("> HTTPSocket[%d] : HTTP Response Header + Body - CGI\r\n", s);
  402. #endif
  403. send_len = sprintf((char *)buf, "%s%d\r\n\r\n%s", RES_CGIHEAD_OK, file_len, http_body);
  404. #ifdef _HTTPSERVER_DEBUG_
  405. printf("> HTTPSocket[%d] : HTTP Response Header + Body - send len [ %d ]byte\r\n", s, send_len);
  406. #endif
  407. send(s, buf, send_len);
  408. }
  409. static int8_t http_disconnect(uint8_t sn)
  410. {
  411. setSn_CR(sn,Sn_CR_DISCON);
  412. /* wait to process the command... */
  413. while(getSn_CR(sn));
  414. return SOCK_OK;
  415. }
  416. static void http_process_handler(uint8_t s, st_http_request * p_http_request)
  417. {
  418. uint8_t * uri_name;
  419. uint32_t content_addr = 0;
  420. uint16_t content_num = 0;
  421. uint32_t file_len = 0;
  422. uint8_t uri_buf[MAX_URI_SIZE]={0x00, };
  423. uint16_t http_status;
  424. int8_t get_seqnum;
  425. uint8_t content_found;
  426. if((get_seqnum = getHTTPSequenceNum(s)) == -1) return; // exception handling; invalid number
  427. http_status = 0;
  428. http_response = pHTTP_RX;
  429. file_len = 0;
  430. //method Analyze
  431. switch (p_http_request->METHOD)
  432. {
  433. case METHOD_ERR :
  434. http_status = STATUS_BAD_REQ;
  435. send_http_response_header(s, 0, 0, http_status);
  436. break;
  437. case METHOD_HEAD :
  438. case METHOD_GET :
  439. get_http_uri_name(p_http_request->URI, uri_buf);
  440. uri_name = uri_buf;
  441. if (!strcmp((char *)uri_name, "/")) strcpy((char *)uri_name, INITIAL_WEBPAGE); // If URI is "/", respond by index.html
  442. if (!strcmp((char *)uri_name, "m")) strcpy((char *)uri_name, M_INITIAL_WEBPAGE);
  443. if (!strcmp((char *)uri_name, "mobile")) strcpy((char *)uri_name, MOBILE_INITIAL_WEBPAGE);
  444. find_http_uri_type(&p_http_request->TYPE, uri_name); // Checking requested file types (HTML, TEXT, GIF, JPEG and Etc. are included)
  445. #ifdef _HTTPSERVER_DEBUG_
  446. printf("\r\n> HTTPSocket[%d] : HTTP Method GET\r\n", s);
  447. printf("> HTTPSocket[%d] : Request Type = %d\r\n", s, p_http_request->TYPE);
  448. printf("> HTTPSocket[%d] : Request URI = %s\r\n", s, uri_name);
  449. #endif
  450. if(p_http_request->TYPE == PTYPE_CGI)
  451. {
  452. content_found = http_get_cgi_handler(uri_name, pHTTP_TX, &file_len);
  453. if(content_found && (file_len <= (DATA_BUF_SIZE-(strlen(RES_CGIHEAD_OK)+8))))
  454. {
  455. send_http_response_cgi(s, http_response, pHTTP_TX, (uint16_t)file_len);
  456. }
  457. else
  458. {
  459. send_http_response_header(s, PTYPE_CGI, 0, STATUS_NOT_FOUND);
  460. }
  461. }
  462. else
  463. {
  464. // Find the User registered index for web content
  465. if(find_userReg_webContent(uri_buf, &content_num, &file_len))
  466. {
  467. content_found = 1; // Web content found in code flash memory
  468. content_addr = (uint32_t)content_num;
  469. HTTPSock_Status[get_seqnum].storage_type = CODEFLASH;
  470. }
  471. // Not CGI request, Web content in 'SD card' or 'Data flash' requested
  472. #ifdef _USE_SDCARD_
  473. #ifdef _HTTPSERVER_DEBUG_
  474. printf("\r\n> HTTPSocket[%d] : Searching the requested content\r\n", s);
  475. #endif
  476. if((fr = f_open(&fs, (const char *)uri_name, FA_READ)) == 0)
  477. {
  478. content_found = 1; // file open succeed
  479. file_len = fs.fsize;
  480. content_addr = fs.sclust;
  481. HTTPSock_Status[get_seqnum].storage_type = SDCARD;
  482. }
  483. #elif _USE_FLASH_
  484. else if(/* Read content from Dataflash */)
  485. {
  486. content_found = 1;
  487. HTTPSock_Status[get_seqnum]->storage_type = DATAFLASH;
  488. ; // To do
  489. }
  490. #endif
  491. else
  492. {
  493. content_found = 0; // fail to find content
  494. }
  495. if(!content_found)
  496. {
  497. #ifdef _HTTPSERVER_DEBUG_
  498. printf("> HTTPSocket[%d] : Unknown Page Request\r\n", s);
  499. #endif
  500. http_status = STATUS_NOT_FOUND;
  501. }
  502. else
  503. {
  504. #ifdef _HTTPSERVER_DEBUG_
  505. printf("> HTTPSocket[%d] : Find Content [%s] ok - Start [%ld] len [ %ld ]byte\r\n", s, uri_name, content_addr, file_len);
  506. #endif
  507. http_status = STATUS_OK;
  508. }
  509. // Send HTTP header
  510. if(http_status)
  511. {
  512. #ifdef _HTTPSERVER_DEBUG_
  513. printf("> HTTPSocket[%d] : Requested content len = [ %ld ]byte\r\n", s, file_len);
  514. #endif
  515. send_http_response_header(s, p_http_request->TYPE, file_len, http_status);
  516. }
  517. // Send HTTP body (content)
  518. if(http_status == STATUS_OK)
  519. {
  520. send_http_response_body(s, uri_name, http_response, content_addr, file_len);
  521. }
  522. }
  523. break;
  524. case METHOD_POST :
  525. mid((char *)p_http_request->URI, "/", " HTTP", (char *)uri_buf);
  526. uri_name = uri_buf;
  527. find_http_uri_type(&p_http_request->TYPE, uri_name); // Check file type (HTML, TEXT, GIF, JPEG are included)
  528. #ifdef _HTTPSERVER_DEBUG_
  529. printf("\r\n> HTTPSocket[%d] : HTTP Method POST\r\n", s);
  530. printf("> HTTPSocket[%d] : Request URI = %s ", s, uri_name);
  531. printf("Type = %d\r\n", p_http_request->TYPE);
  532. #endif
  533. if(p_http_request->TYPE == PTYPE_CGI) // HTTP POST Method; CGI Process
  534. {
  535. content_found = http_post_cgi_handler(uri_name, p_http_request, http_response, &file_len);
  536. #ifdef _HTTPSERVER_DEBUG_
  537. printf("> HTTPSocket[%d] : [CGI: %s] / Response len [ %ld ]byte\r\n", s, content_found?"Content found":"Content not found", file_len);
  538. #endif
  539. if(content_found && (file_len <= (DATA_BUF_SIZE-(strlen(RES_CGIHEAD_OK)+8))))
  540. {
  541. send_http_response_cgi(s, pHTTP_TX, http_response, (uint16_t)file_len);
  542. // Reset the H/W for apply to the change configuration information
  543. if(content_found == HTTP_RESET) HTTPServer_ReStart();
  544. }
  545. else
  546. {
  547. send_http_response_header(s, PTYPE_CGI, 0, STATUS_NOT_FOUND);
  548. }
  549. }
  550. else // HTTP POST Method; Content not found
  551. {
  552. send_http_response_header(s, 0, 0, STATUS_NOT_FOUND);
  553. }
  554. break;
  555. default :
  556. http_status = STATUS_BAD_REQ;
  557. send_http_response_header(s, 0, 0, http_status);
  558. break;
  559. }
  560. }
  561. void httpServer_time_handler(void)
  562. {
  563. httpServer_tick_1s++;
  564. }
  565. uint32_t get_httpServer_timecount(void)
  566. {
  567. return httpServer_tick_1s;
  568. }
  569. void reg_httpServer_webContent(uint8_t * content_name, uint8_t * content)
  570. {
  571. uint16_t name_len;
  572. uint32_t content_len;
  573. if(content_name == NULL || content == NULL)
  574. {
  575. return;
  576. }
  577. else if(total_content_cnt >= MAX_CONTENT_CALLBACK)
  578. {
  579. return;
  580. }
  581. name_len = strlen((char *)content_name);
  582. content_len = strlen((char *)content);
  583. web_content[total_content_cnt].content_name = malloc(name_len+1);
  584. strcpy((char *)web_content[total_content_cnt].content_name, (const char *)content_name);
  585. web_content[total_content_cnt].content_len = content_len;
  586. web_content[total_content_cnt].content = content;
  587. total_content_cnt++;
  588. }
  589. uint8_t display_reg_webContent_list(void)
  590. {
  591. uint16_t i;
  592. uint8_t ret;
  593. if(total_content_cnt == 0)
  594. {
  595. printf(">> Web content file not found\r\n");
  596. ret = 0;
  597. }
  598. else
  599. {
  600. printf("\r\n=== List of Web content in code flash ===\r\n");
  601. for(i = 0; i < total_content_cnt; i++)
  602. {
  603. printf(" [%d] ", i+1);
  604. printf("%s, ", web_content[i].content_name);
  605. printf("%ld byte, ", web_content[i].content_len);
  606. if(web_content[i].content_len < 30) printf("[%s]\r\n", web_content[i].content);
  607. else printf("[ ... ]\r\n");
  608. }
  609. printf("=========================================\r\n\r\n");
  610. ret = 1;
  611. }
  612. return ret;
  613. }
  614. uint8_t find_userReg_webContent(uint8_t * content_name, uint16_t * content_num, uint32_t * file_len)
  615. {
  616. uint16_t i;
  617. uint8_t ret = 0; // '0' means 'File Not Found'
  618. for(i = 0; i < total_content_cnt; i++)
  619. {
  620. if(!strcmp((char *)content_name, (char *)web_content[i].content_name))
  621. {
  622. *file_len = web_content[i].content_len;
  623. *content_num = i;
  624. ret = 1; // If the requested content found, ret set to '1' (Found)
  625. break;
  626. }
  627. }
  628. return ret;
  629. }
  630. uint16_t read_userReg_webContent(uint16_t content_num, uint8_t * buf, uint32_t offset, uint16_t size)
  631. {
  632. uint16_t ret = 0;
  633. uint8_t * ptr;
  634. if(content_num > total_content_cnt) return 0;
  635. ptr = web_content[content_num].content;
  636. if(offset) ptr += offset;
  637. strncpy((char *)buf, (char *)ptr, size);
  638. *(buf+size) = 0; // Insert '/0' for indicates the 'End of String' (null terminated)
  639. ret = strlen((void *)buf);
  640. return ret;
  641. }