httpParser.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. /**
  2. @file httpd.c
  3. @brief functions associated http processing
  4. */
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include "socket.h"
  8. #include "httpParser.h"
  9. /*****************************************************************************
  10. * Public types/enumerations/variables
  11. ****************************************************************************/
  12. //uint8_t BUFPUB[2048];
  13. uint8_t BUFPUB[256];
  14. /*****************************************************************************
  15. * Private functions
  16. ****************************************************************************/
  17. static void replacetochar(uint8_t * str, uint8_t oldchar, uint8_t newchar); /* Replace old character with new character in the string */
  18. static uint8_t C2D(uint8_t c); /* Convert a character to HEX */
  19. /**
  20. @brief convert escape characters(%XX) to ASCII character
  21. */
  22. void unescape_http_url(
  23. char * url /**< pointer to be converted ( escape characters )*/
  24. )
  25. {
  26. int x, y;
  27. for (x = 0, y = 0; url[y]; ++x, ++y) {
  28. if ((url[x] = url[y]) == '%') {
  29. url[x] = C2D(url[y+1])*0x10+C2D(url[y+2]);
  30. y+=2;
  31. }
  32. }
  33. url[x] = '\0';
  34. }
  35. /**
  36. @brief make response header such as html, gif, jpeg,etc.
  37. */
  38. void make_http_response_head(
  39. char * buf, /**< pointer to response header to be made */
  40. char type, /**< response type */
  41. uint32_t len /**< size of response header */
  42. )
  43. {
  44. char * head;
  45. char tmp[10];
  46. /* file type*/
  47. if (type == PTYPE_HTML) head = RES_HTMLHEAD_OK;
  48. else if (type == PTYPE_GIF) head = RES_GIFHEAD_OK;
  49. else if (type == PTYPE_TEXT) head = RES_TEXTHEAD_OK;
  50. else if (type == PTYPE_JPEG) head = RES_JPEGHEAD_OK;
  51. else if (type == PTYPE_FLASH) head = RES_FLASHHEAD_OK;
  52. else if (type == PTYPE_XML) head = RES_XMLHEAD_OK;
  53. else if (type == PTYPE_CSS) head = RES_CSSHEAD_OK;
  54. else if (type == PTYPE_JSON) head = RES_JSONHEAD_OK;
  55. else if (type == PTYPE_JS) head = RES_JSHEAD_OK;
  56. else if (type == PTYPE_CGI) head = RES_CGIHEAD_OK;
  57. else if (type == PTYPE_PNG) head = RES_PNGHEAD_OK;
  58. else if (type == PTYPE_ICO) head = RES_ICOHEAD_OK;
  59. else if (type == PTYPE_TTF) head = RES_TTFHEAD_OK;
  60. else if (type == PTYPE_OTF) head = RES_OTFHEAD_OK;
  61. else if (type == PTYPE_WOFF) head = RES_WOFFHEAD_OK;
  62. else if (type == PTYPE_EOT) head = RES_EOTHEAD_OK;
  63. else if (type == PTYPE_SVG) head = RES_SVGHEAD_OK;
  64. #ifdef _HTTPPARSER_DEBUG_
  65. else
  66. {
  67. head = NULL;
  68. printf("\r\n\r\n-MAKE HEAD UNKNOWN-\r\n");
  69. }
  70. #else
  71. else head = NULL;
  72. #endif
  73. sprintf(tmp, "%ld", len);
  74. strcpy(buf, head);
  75. strcat(buf, tmp);
  76. strcat(buf, "\r\n\r\n");
  77. }
  78. /**
  79. @brief find MIME type of a file
  80. */
  81. void find_http_uri_type(
  82. uint8_t * type, /**< type to be returned */
  83. uint8_t * buff /**< file name */
  84. )
  85. {
  86. /* Decide type according to extension*/
  87. char * buf;
  88. buf = (char *)buff;
  89. if (strstr(buf, ".htm") || strstr(buf, ".html")) *type = PTYPE_HTML;
  90. else if (strstr(buf, ".gif")) *type = PTYPE_GIF;
  91. else if (strstr(buf, ".text") || strstr(buf,".txt")) *type = PTYPE_TEXT;
  92. else if (strstr(buf, ".jpeg") || strstr(buf,".jpg")) *type = PTYPE_JPEG;
  93. else if (strstr(buf, ".swf")) *type = PTYPE_FLASH;
  94. else if (strstr(buf, ".cgi") || strstr(buf,".CGI")) *type = PTYPE_CGI;
  95. else if (strstr(buf, ".json") || strstr(buf,".JSON")) *type = PTYPE_JSON;
  96. else if (strstr(buf, ".js") || strstr(buf,".JS")) *type = PTYPE_JS;
  97. else if (strstr(buf, ".CGI") || strstr(buf,".cgi")) *type = PTYPE_CGI;
  98. else if (strstr(buf, ".xml") || strstr(buf,".XML")) *type = PTYPE_XML;
  99. else if (strstr(buf, ".css") || strstr(buf,".CSS")) *type = PTYPE_CSS;
  100. else if (strstr(buf, ".png") || strstr(buf,".PNG")) *type = PTYPE_PNG;
  101. else if (strstr(buf, ".ico") || strstr(buf,".ICO")) *type = PTYPE_ICO;
  102. else if (strstr(buf, ".ttf") || strstr(buf,".TTF")) *type = PTYPE_TTF;
  103. else if (strstr(buf, ".otf") || strstr(buf,".OTF")) *type = PTYPE_OTF;
  104. else if (strstr(buf, ".woff") || strstr(buf,".WOFF")) *type = PTYPE_WOFF;
  105. else if (strstr(buf, ".eot") || strstr(buf,".EOT")) *type = PTYPE_EOT;
  106. else if (strstr(buf, ".svg") || strstr(buf,".SVG")) *type = PTYPE_SVG;
  107. else *type = PTYPE_ERR;
  108. }
  109. /**
  110. @brief parse http request from a peer
  111. */
  112. void parse_http_request(
  113. st_http_request * request, /**< request to be returned */
  114. uint8_t * buf /**< pointer to be parsed */
  115. )
  116. {
  117. char * nexttok;
  118. nexttok = strtok((char*)buf," ");
  119. if(!nexttok)
  120. {
  121. request->METHOD = METHOD_ERR;
  122. return;
  123. }
  124. if(!strcmp(nexttok, "GET") || !strcmp(nexttok,"get"))
  125. {
  126. request->METHOD = METHOD_GET;
  127. nexttok = strtok(NULL," ");
  128. }
  129. else if (!strcmp(nexttok, "HEAD") || !strcmp(nexttok,"head"))
  130. {
  131. request->METHOD = METHOD_HEAD;
  132. nexttok = strtok(NULL," ");
  133. }
  134. else if (!strcmp(nexttok, "POST") || !strcmp(nexttok,"post"))
  135. {
  136. nexttok = strtok(NULL,"\0");
  137. request->METHOD = METHOD_POST;
  138. }
  139. else
  140. {
  141. request->METHOD = METHOD_ERR;
  142. }
  143. if(!nexttok)
  144. {
  145. request->METHOD = METHOD_ERR;
  146. return;
  147. }
  148. strcpy((char *)request->URI, nexttok);
  149. }
  150. #ifdef _OLD_
  151. /**
  152. @brief get next parameter value in the request
  153. */
  154. uint8_t * get_http_param_value(
  155. char* uri,
  156. char* param_name
  157. )
  158. {
  159. char tempURI[MAX_URI_SIZE];
  160. uint8_t * name = 0;
  161. if(!uri || !param_name) return 0;
  162. strcpy((char*)tempURI,uri);
  163. if((name = (uint8_t*)strstr(tempURI, param_name)))
  164. {
  165. name += strlen(param_name) + 1; // strlen(para_name) + strlen("=")
  166. if((name = (uint8_t*)strtok((char *)name,"& \r\n\t\0")))
  167. {
  168. unescape_http_url((char *)name);
  169. replacetochar(name, '+', ' ');
  170. }
  171. }
  172. #ifdef _HTTPPARSER_DEBUG_
  173. printf(" %s=%s",param_name,name);
  174. #endif
  175. return name;
  176. }
  177. #else
  178. /**
  179. @brief get next parameter value in the request
  180. */
  181. uint8_t * get_http_param_value(char* uri, char* param_name)
  182. {
  183. uint8_t * name = 0;
  184. uint8_t * ret = BUFPUB;
  185. uint8_t * pos2;
  186. uint16_t len = 0, content_len = 0;
  187. uint8_t tmp_buf[10]={0x00, };
  188. if(!uri || !param_name) return 0;
  189. /***************/
  190. mid(uri, "Content-Length: ", "\r\n", (char *)tmp_buf);
  191. content_len = ATOI(tmp_buf, 10);
  192. uri = strstr(uri, "\r\n\r\n");
  193. uri += 4;
  194. uri[content_len] = 0;
  195. /***************/
  196. if((name = (uint8_t *)strstr(uri, param_name)))
  197. {
  198. name += strlen(param_name) + 1;
  199. pos2 = (uint8_t*)strstr((char*)name, "&");
  200. if(!pos2)
  201. {
  202. pos2 = name + strlen((char*)name);
  203. }
  204. len = pos2 - name;
  205. if(len)
  206. {
  207. ret[len] = 0;
  208. strncpy((char*)ret,(char*)name, len);
  209. unescape_http_url((char *)ret);
  210. replacetochar(ret, '+' ,' ');
  211. //ret[len] = 0;
  212. //ret[strlen((int8*)ret)] = 0;
  213. //printf("len=%d\r\n",len);
  214. }
  215. else
  216. {
  217. ret[0] = 0;
  218. }
  219. }
  220. else
  221. {
  222. return 0;
  223. }
  224. #ifdef _HTTPPARSER_DEBUG_
  225. printf(" %s=%s\r\n", param_name, ret);
  226. #endif
  227. return ret;
  228. }
  229. #endif
  230. #ifdef _OLD_
  231. uint8_t * get_http_uri_name(uint8_t * uri)
  232. {
  233. char tempURI[MAX_URI_SIZE];
  234. uint8_t * uri_name;
  235. if(!uri) return 0;
  236. strcpy(tempURI, (char *)uri);
  237. uri_name = (uint8_t *)strtok(tempURI, " ?");
  238. if(strcmp((char *)uri_name,"/")) uri_name++;
  239. #ifdef _HTTPPARSER_DEBUG_
  240. printf(" uri_name = %s\r\n", uri_name);
  241. #endif
  242. return uri_name;
  243. }
  244. #else
  245. uint8_t get_http_uri_name(uint8_t * uri, uint8_t * uri_buf)
  246. {
  247. uint8_t * uri_ptr;
  248. if(!uri) return 0;
  249. strcpy((char *)uri_buf, (char *)uri);
  250. uri_ptr = (uint8_t *)strtok((char *)uri_buf, " ?");
  251. if(strcmp((char *)uri_ptr,"/")) uri_ptr++;
  252. strcpy((char *)uri_buf, (char *)uri_ptr);
  253. #ifdef _HTTPPARSER_DEBUG_
  254. printf(" uri_name = %s\r\n", uri_buf);
  255. #endif
  256. return 1;
  257. }
  258. #endif
  259. void inet_addr_(uint8_t * addr, uint8_t *ip)
  260. {
  261. uint8_t i;
  262. uint8_t taddr[30];
  263. uint8_t * nexttok;
  264. uint8_t num;
  265. strcpy((char *)taddr, (char *)addr);
  266. nexttok = taddr;
  267. for(i = 0; i < 4 ; i++)
  268. {
  269. nexttok = (uint8_t *)strtok((char *)nexttok, ".");
  270. if(nexttok[0] == '0' && nexttok[1] == 'x') num = ATOI(nexttok+2,0x10);
  271. else num = ATOI(nexttok,10);
  272. ip[i] = num;
  273. nexttok = NULL;
  274. }
  275. }
  276. /**
  277. @brief CONVERT STRING INTO INTEGER
  278. @return a integer number
  279. */
  280. uint16_t ATOI(
  281. uint8_t * str, /**< is a pointer to convert */
  282. uint8_t base /**< is a base value (must be in the range 2 - 16) */
  283. )
  284. {
  285. unsigned int num = 0;
  286. // debug_2013_11_25
  287. // while (*str !=0)
  288. while ((*str !=0) && (*str != 0x20)) // not include the space(0x020)
  289. num = num * base + C2D(*str++);
  290. return num;
  291. }
  292. /**
  293. * @brief Check strings and then execute callback function by each string.
  294. * @param src The information of URI
  295. * @param s1 The start string to be researched
  296. * @param s2 The end string to be researched
  297. * @param sub The string between s1 and s2
  298. * @return The length value atfer working
  299. */
  300. void mid(char* src, char* s1, char* s2, char* sub)
  301. {
  302. char* sub1;
  303. char* sub2;
  304. uint16_t n;
  305. sub1=strstr((char*)src,(char*)s1);
  306. sub1+=strlen((char*)s1);
  307. sub2=strstr((char*)sub1,(char*)s2);
  308. n=sub2-sub1;
  309. strncpy((char*)sub,(char*)sub1,n);
  310. sub[n]='\0';
  311. }
  312. ////////////////////////////////////////////////////////////////////
  313. // Static functions
  314. ////////////////////////////////////////////////////////////////////
  315. /**
  316. @brief replace the specified character in a string with new character
  317. */
  318. static void replacetochar(
  319. uint8_t * str, /**< pointer to be replaced */
  320. uint8_t oldchar, /**< old character */
  321. uint8_t newchar /**< new character */
  322. )
  323. {
  324. int x;
  325. for (x = 0; str[x]; x++)
  326. if (str[x] == oldchar) str[x] = newchar;
  327. }
  328. /**
  329. @brief CONVERT CHAR INTO HEX
  330. @return HEX
  331. This function converts HEX(0-F) to a character
  332. */
  333. static uint8_t C2D(
  334. uint8_t c /**< is a character('0'-'F') to convert to HEX */
  335. )
  336. {
  337. if (c >= '0' && c <= '9')
  338. return c - '0';
  339. if (c >= 'a' && c <= 'f')
  340. return 10 + c -'a';
  341. if (c >= 'A' && c <= 'F')
  342. return 10 + c -'A';
  343. return (char)c;
  344. }