wn_module_upload.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778
  1. /*
  2. * File : wn_module_upload.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
  5. *
  6. * This software is dual-licensed: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation. For the terms of this
  9. * license, see <http://www.gnu.org/licenses/>.
  10. *
  11. * You are free to use this software under the terms of the GNU General
  12. * Public License, but WITHOUT ANY WARRANTY; without even the implied
  13. * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  14. * See the GNU General Public License for more details.
  15. *
  16. * Alternatively for commercial application, you can contact us
  17. * by email <business@rt-thread.com> for commercial license.
  18. *
  19. * Change Logs:
  20. * Date Author Notes
  21. * 2012-06-25 Bernard the first version
  22. */
  23. #include <webnet.h>
  24. #include <wn_module.h>
  25. #include <wn_utils.h>
  26. #ifdef RT_USING_DFS
  27. #include <dfs_posix.h>
  28. #endif
  29. #if defined(WEBNET_USING_UPLOAD)
  30. #define MULTIPART_FORM_DATA_STRING "multipart/form-data"
  31. #define BOUNDARY_STRING "boundary="
  32. #define CONTENT_DISPOSITION_STRING "Content-Disposition:"
  33. #define CONTENT_TYPE_STRING "Content-Type:"
  34. #define CONTENT_RANGE_STRING "Content-Range:"
  35. #define FORM_DATA_STRING "form-data"
  36. #define FILENAME_STRING "filename=\""
  37. #define FIELDNAME_STRING "name=\""
  38. #define FIRST_BOUNDARY 2, upload_session->boundary, "\r\n"
  39. #define NORMAL_BOUNDARY 3, "\r\n", upload_session->boundary, "\r\n"
  40. #define COMMON_BOUNDARY 2, "\r\n", upload_session->boundary
  41. #define LAST_BOUNDARY 3, "\r\n", upload_session->boundary, "--\r\n"
  42. #define FIRST_BOUNDARY_SIZE (strlen(upload_session->boundary) + 2)
  43. #define NORMAL_BOUNDARY_SIZE (strlen(upload_session->boundary) + 4)
  44. #define COMMON_BOUNDARY_SIZE (strlen(upload_session->boundary) + 2)
  45. #define LAST_BOUNDARY_SIZE (strlen(upload_session->boundary) + 6)
  46. struct webnet_upload_name_entry
  47. {
  48. char *name;
  49. char *value;
  50. };
  51. static const struct webnet_module_upload_entry **_upload_entries = RT_NULL;
  52. static rt_uint16_t _upload_entries_count = 0;
  53. struct webnet_module_upload_session
  54. {
  55. char* boundary;
  56. char* filename;
  57. char* content_type;
  58. struct webnet_upload_name_entry* name_entries;
  59. rt_uint16_t name_entries_count;
  60. rt_uint16_t file_opened;
  61. /* upload entry */
  62. const struct webnet_module_upload_entry* entry;
  63. /* user data */
  64. rt_uint32_t user_data;
  65. };
  66. static int str_begin_with_strs(const char* str, int num, ...)
  67. {
  68. char *match;
  69. va_list args;
  70. int index, result;
  71. result = 1;
  72. va_start(args,num);
  73. for (index = 0; index < num; index ++)
  74. {
  75. match = va_arg(args, char*);
  76. if (strncasecmp(str, match, strlen(match)) != 0)
  77. {
  78. result = 0;
  79. break;
  80. }
  81. str += strlen(match);
  82. }
  83. va_end(args);
  84. return result;
  85. }
  86. /* Search string on binary data */
  87. static char *memstr(const char *haystack, size_t length, const char *needle)
  88. {
  89. size_t nl=strlen(needle);
  90. size_t hl=length;
  91. size_t i;
  92. if (!nl) goto __found;
  93. if (nl > length) return 0;
  94. for (i=hl-nl+1; i; --i)
  95. {
  96. if (*haystack==*needle && !memcmp(haystack,needle,nl))
  97. __found:
  98. return (char*)haystack;
  99. ++haystack;
  100. }
  101. return 0;
  102. }
  103. /* Search string array on binary data */
  104. static char* memstrs(const char* str, size_t length, int num, ...)
  105. {
  106. char *substr;
  107. char *index_str, *ptr;
  108. va_list args;
  109. int index;
  110. int total_size;
  111. /* get the match total string length */
  112. va_start(args, num);
  113. total_size = 0;
  114. for (index = 0; index < num; index ++)
  115. {
  116. index_str = va_arg(args, char*);
  117. total_size += strlen(index_str);
  118. }
  119. va_end(args);
  120. substr = wn_malloc(total_size + 1);
  121. ptr = substr;
  122. va_start(args, num);
  123. for (index = 0; index < num; index++)
  124. {
  125. index_str = va_arg(args, char*);
  126. memcpy(ptr, index_str, strlen(index_str));
  127. ptr += strlen(index_str);
  128. }
  129. substr[total_size] = '\0';
  130. va_end(args);
  131. /* find in binary data */
  132. ptr = memstr(str, length, substr);
  133. wn_free(substr);
  134. return ptr;
  135. }
  136. #ifndef __GNUC__
  137. static void* memrchr(const void *s, int c, size_t n)
  138. {
  139. register const char* t=s;
  140. register const char* last=0;
  141. int i;
  142. t = t + n;
  143. for (i=n; i; --i)
  144. {
  145. if (*t==c)
  146. {
  147. last=t;
  148. break;
  149. }
  150. t--;
  151. }
  152. return (void*)last; /* man, what an utterly b0rken prototype */
  153. }
  154. #endif
  155. static char* _webnet_module_upload_parse_header(struct webnet_session* session, char* buffer, rt_size_t length)
  156. {
  157. char *ptr, *ch, *end_ptr;
  158. struct webnet_module_upload_session *upload_session;
  159. char *name = RT_NULL, *filename = RT_NULL, *content_type = RT_NULL;
  160. /* get upload session */
  161. upload_session = (struct webnet_module_upload_session *)session->user_data;
  162. ptr = buffer;
  163. end_ptr = buffer + length;
  164. /* begin with last boundary */
  165. if (str_begin_with_strs(ptr, LAST_BOUNDARY))
  166. {
  167. ptr += LAST_BOUNDARY_SIZE;
  168. return ptr;
  169. }
  170. /* begin with normal boundary */
  171. if (str_begin_with_strs(ptr, NORMAL_BOUNDARY))
  172. ptr += NORMAL_BOUNDARY_SIZE;
  173. else if (str_begin_with_strs(ptr, FIRST_BOUNDARY))
  174. ptr += FIRST_BOUNDARY_SIZE;
  175. if (ptr == buffer) return RT_NULL; /* not begin with boundary */
  176. if (upload_session->filename != RT_NULL &&
  177. upload_session->content_type != RT_NULL)
  178. {
  179. /* end of file name section */
  180. wn_free(upload_session->filename);
  181. wn_free(upload_session->content_type);
  182. upload_session->filename = RT_NULL;
  183. upload_session->content_type = RT_NULL;
  184. }
  185. while ((rt_uint32_t)ptr - (rt_uint32_t)buffer < length)
  186. {
  187. /* handle Content-Disposition: */
  188. if (str_begin_with(ptr, CONTENT_DISPOSITION_STRING))
  189. {
  190. ptr += sizeof(CONTENT_DISPOSITION_STRING) - 1;
  191. while (*ptr == ' ') ptr ++;
  192. /* form-data */
  193. if (str_begin_with(ptr, FORM_DATA_STRING))
  194. {
  195. ptr += sizeof(FORM_DATA_STRING) - 1;
  196. while (*ptr == ' ' || *ptr == ';') ptr ++;
  197. /* get name="str" */
  198. if (str_begin_with(ptr, FIELDNAME_STRING))
  199. {
  200. ptr += sizeof(FIELDNAME_STRING) - 1;
  201. name = ptr;
  202. ch = memchr(ptr, '"', buffer - ptr);
  203. if (ch != RT_NULL)
  204. {
  205. *ch = '\0';
  206. ch ++;
  207. while (*ch == ' ' || *ch ==';') ch ++;
  208. ptr = ch;
  209. }
  210. }
  211. /* get filename="str" */
  212. if (str_begin_with(ptr, FILENAME_STRING))
  213. {
  214. ptr += sizeof(FILENAME_STRING) - 1;
  215. filename = ptr;
  216. ch = memchr(ptr, '"', buffer - ptr);
  217. if (ch != RT_NULL)
  218. {
  219. *ch = '\0';
  220. ch ++;
  221. ptr = ch;
  222. }
  223. }
  224. }
  225. }
  226. /* handle Content-Type */
  227. else if (str_begin_with(ptr, CONTENT_TYPE_STRING))
  228. {
  229. ptr += sizeof(CONTENT_TYPE_STRING) - 1;
  230. while (*ptr == ' ') ptr ++;
  231. content_type = ptr;
  232. }
  233. /* handle Content-Range: */
  234. else if (str_begin_with(ptr, CONTENT_RANGE_STRING))
  235. {
  236. ptr += sizeof(CONTENT_RANGE_STRING) - 1;
  237. while (*ptr == ' ') ptr ++;
  238. }
  239. /* whether end of header */
  240. else if (str_begin_with(ptr, "\r\n"))
  241. {
  242. ptr += 2;
  243. if (upload_session->filename != RT_NULL)
  244. {
  245. wn_free(upload_session->filename);
  246. upload_session->filename = RT_NULL;
  247. }
  248. if (upload_session->content_type != RT_NULL)
  249. {
  250. wn_free(upload_session->content_type);
  251. upload_session->content_type = RT_NULL;
  252. }
  253. if (filename != RT_NULL)
  254. {
  255. upload_session->filename = wn_strdup(filename);
  256. }
  257. if (content_type != RT_NULL)
  258. {
  259. upload_session->content_type = wn_strdup(content_type);
  260. }
  261. if (name != RT_NULL)
  262. {
  263. /* add a name entry in the upload session */
  264. if (upload_session->name_entries == RT_NULL)
  265. {
  266. upload_session->name_entries_count = 1;
  267. upload_session->name_entries = (struct webnet_upload_name_entry*)
  268. wn_malloc(sizeof(struct webnet_upload_name_entry));
  269. }
  270. else
  271. {
  272. upload_session->name_entries_count += 1;
  273. upload_session->name_entries = (struct webnet_upload_name_entry*)
  274. wn_realloc(upload_session->name_entries,
  275. sizeof(struct webnet_upload_name_entry) * upload_session->name_entries_count);
  276. }
  277. upload_session->name_entries[upload_session->name_entries_count - 1].name = wn_strdup(name);
  278. upload_session->name_entries[upload_session->name_entries_count - 1].value = RT_NULL;
  279. }
  280. return ptr;
  281. }
  282. /* skip this request header line */
  283. ch = memstr(ptr, end_ptr - ptr, "\r\n");
  284. *ch = '\0';
  285. ch ++;
  286. *ch = '\0';
  287. ch ++;
  288. ptr = ch;
  289. }
  290. return ptr;
  291. }
  292. static char* _next_possible_boundary(struct webnet_session* session, char* buffer, rt_size_t length)
  293. {
  294. char *ptr;
  295. struct webnet_module_upload_session *upload_session;
  296. /* get upload session */
  297. upload_session = (struct webnet_module_upload_session *)session->user_data;
  298. /* try the beginning */
  299. if (str_begin_with_strs(buffer, COMMON_BOUNDARY)) return buffer;
  300. /* search in all the string */
  301. ptr = memstrs(buffer, length, COMMON_BOUNDARY);
  302. if (ptr != RT_NULL) return ptr;
  303. /* search from the end of string */
  304. ptr = memrchr(buffer, '\r', length);
  305. if (ptr == RT_NULL ) return RT_NULL;
  306. if (ptr - buffer == length - 1) return ptr; /* only \r */
  307. if (*(ptr + 1) == '\n' && ptr - buffer == length - 2) return RT_NULL; /* only \r\n */
  308. if (memcmp(ptr + 2, upload_session->boundary, length - (ptr - buffer + 2)) == 0) return ptr;
  309. return RT_NULL;
  310. }
  311. static void _handle_section(struct webnet_session* session, char* buffer, rt_size_t length)
  312. {
  313. char *ptr;
  314. struct webnet_module_upload_session *upload_session;
  315. #define name_entry \
  316. (upload_session->name_entries[upload_session->name_entries_count - 1])
  317. /* get upload session */
  318. upload_session = (struct webnet_module_upload_session *)session->user_data;
  319. if (upload_session->filename != RT_NULL &&
  320. upload_session->content_type != RT_NULL&&
  321. length != 0)
  322. {
  323. upload_session->entry->upload_write(session, buffer, length);
  324. }
  325. else
  326. {
  327. /* get name value */
  328. ptr = memstr(buffer, length, "\r\n");
  329. if (ptr != RT_NULL)
  330. {
  331. int value_size = ptr - buffer + 1;
  332. name_entry.value = wn_malloc(value_size);
  333. memcpy(name_entry.value, buffer, value_size - 1);
  334. name_entry.value[value_size - 1] = '\0';
  335. }
  336. }
  337. }
  338. static void _webnet_module_upload_handle(struct webnet_session* session, int event)
  339. {
  340. int length;
  341. char *ptr, *end_ptr;
  342. char *upload_buffer;
  343. rt_uint32_t chunk_size;
  344. struct webnet_module_upload_session *upload_session;
  345. if (event != WEBNET_EVENT_READ) return;
  346. /* get upload session */
  347. upload_session = (struct webnet_module_upload_session *)session->user_data;
  348. upload_buffer = (char*)session->buffer;
  349. /* read stream */
  350. if (memstrs((const char *)session->buffer, session->buffer_offset, LAST_BOUNDARY))
  351. {
  352. length = session->buffer_offset;
  353. }
  354. else
  355. {
  356. if (session->buffer_offset != 0)
  357. {
  358. length = webnet_session_read(session,
  359. (char*)&session->buffer[session->buffer_offset],
  360. sizeof(session->buffer) - session->buffer_offset - 1);
  361. if (length > 0)
  362. {
  363. length += session->buffer_offset;
  364. }
  365. else
  366. {
  367. length = session->buffer_offset;
  368. }
  369. }
  370. else
  371. {
  372. length = webnet_session_read(session, (char *)session->buffer, sizeof(session->buffer) - 1);
  373. }
  374. }
  375. /* connection break out */
  376. if (length <= 0)
  377. {
  378. /* read stream failed (connection break out), close this session */
  379. session->session_phase = WEB_PHASE_CLOSE;
  380. return;
  381. }
  382. end_ptr = (char*)(session->buffer + length);
  383. session->buffer[length] = '\0';
  384. while (upload_buffer < end_ptr)
  385. {
  386. if (str_begin_with_strs(upload_buffer, LAST_BOUNDARY))
  387. {
  388. /* upload done */
  389. upload_session->entry->upload_done(session);
  390. session->session_phase = WEB_PHASE_CLOSE;
  391. return;
  392. }
  393. /* read more data */
  394. if (end_ptr - upload_buffer < sizeof(session->buffer)/3 &&
  395. memstrs(upload_buffer, end_ptr - upload_buffer, LAST_BOUNDARY) == RT_NULL)
  396. {
  397. /* read more data */
  398. rt_memmove(session->buffer, upload_buffer, end_ptr - upload_buffer);
  399. session->buffer_offset = end_ptr - upload_buffer;
  400. return ;
  401. }
  402. ptr = _webnet_module_upload_parse_header(session, upload_buffer,
  403. (rt_uint32_t)end_ptr - (rt_uint32_t)upload_buffer);
  404. if (ptr == RT_NULL)
  405. {
  406. /* not begin with a boundary */
  407. ptr = _next_possible_boundary(session, upload_buffer,
  408. (rt_uint32_t)end_ptr - (rt_uint32_t)upload_buffer);
  409. if (ptr == RT_NULL)
  410. {
  411. /* all are the data section */
  412. _handle_section(session, upload_buffer, (rt_uint32_t)end_ptr - (rt_uint32_t)upload_buffer);
  413. upload_buffer = end_ptr;
  414. }
  415. else
  416. {
  417. chunk_size = (rt_uint32_t)ptr - (rt_uint32_t)upload_buffer;
  418. _handle_section(session, upload_buffer, chunk_size);
  419. upload_buffer += chunk_size;
  420. }
  421. }
  422. else
  423. {
  424. if (upload_session->filename != RT_NULL &&
  425. upload_session->content_type != RT_NULL)
  426. {
  427. if (upload_session->file_opened == 0)
  428. {
  429. /* open file */
  430. upload_session->user_data = upload_session->entry->upload_open(session);
  431. upload_session->file_opened = 1;
  432. }
  433. }
  434. else
  435. {
  436. if (upload_session->file_opened == 1)
  437. {
  438. /* close file */
  439. upload_session->entry->upload_close(session);
  440. upload_session->user_data = 0;
  441. upload_session->file_opened = 0;
  442. }
  443. }
  444. upload_buffer = ptr;
  445. ptr = _next_possible_boundary(session, upload_buffer,
  446. (rt_uint32_t)end_ptr - (rt_uint32_t)upload_buffer);
  447. if (ptr == RT_NULL)
  448. {
  449. /* all are the data section */
  450. _handle_section(session, upload_buffer, (rt_uint32_t)end_ptr - (rt_uint32_t)upload_buffer);
  451. upload_buffer = end_ptr;
  452. }
  453. else
  454. {
  455. chunk_size = (rt_uint32_t)ptr - (rt_uint32_t)upload_buffer;
  456. _handle_section(session, upload_buffer, chunk_size);
  457. upload_buffer += chunk_size;
  458. }
  459. }
  460. }
  461. session->buffer_offset = 0;
  462. }
  463. static void _webnet_module_upload_close(struct webnet_session* session)
  464. {
  465. struct webnet_module_upload_session *upload_session;
  466. /* get upload session */
  467. upload_session = (struct webnet_module_upload_session *)session->user_data;
  468. if (upload_session == RT_NULL) return;
  469. /* close file */
  470. if (upload_session->file_opened == 1)
  471. {
  472. upload_session->entry->upload_close(session);
  473. upload_session->file_opened = 0;
  474. }
  475. /* free session */
  476. if (upload_session->filename != RT_NULL)
  477. wn_free(upload_session->filename);
  478. if (upload_session->content_type != RT_NULL)
  479. wn_free(upload_session->content_type);
  480. if (upload_session->boundary != RT_NULL)
  481. wn_free(upload_session->boundary);
  482. if (upload_session->entry != RT_NULL)
  483. {
  484. rt_uint32_t index;
  485. for (index = 0; index < upload_session->name_entries_count; index ++)
  486. {
  487. if (upload_session->name_entries[index].value != RT_NULL)
  488. wn_free(upload_session->name_entries[index].value);
  489. if (upload_session->name_entries[index].name != RT_NULL)
  490. wn_free(upload_session->name_entries[index].name);
  491. }
  492. wn_free(upload_session->name_entries);
  493. upload_session->name_entries = RT_NULL;
  494. }
  495. wn_free(upload_session);
  496. /* remove private data */
  497. session->user_data = 0;
  498. session->session_ops = RT_NULL;
  499. session->session_phase = WEB_PHASE_CLOSE;
  500. }
  501. static const struct webnet_session_ops _upload_ops =
  502. {
  503. _webnet_module_upload_handle,
  504. _webnet_module_upload_close
  505. };
  506. int webnet_module_upload_open(struct webnet_session* session)
  507. {
  508. char* boundary;
  509. rt_uint32_t index, length;
  510. const struct webnet_module_upload_entry *entry = RT_NULL;
  511. struct webnet_module_upload_session *upload_session;
  512. if (session->request->method != WEBNET_POST)
  513. return WEBNET_MODULE_CONTINUE;
  514. /* get upload entry */
  515. for (index = 0; index < _upload_entries_count; index ++)
  516. {
  517. if (str_begin_with(session->request->path, _upload_entries[index]->url))
  518. {
  519. length = rt_strlen(_upload_entries[index]->url);
  520. if (session->request->path[length] == '\0' ||
  521. session->request->path[length] == '?')
  522. {
  523. /* found entry */
  524. entry = _upload_entries[index];
  525. break;
  526. }
  527. }
  528. }
  529. if (entry == RT_NULL) /* no this entry */
  530. return WEBNET_MODULE_CONTINUE;
  531. /* create a uploading session */
  532. upload_session = (struct webnet_module_upload_session*) wn_malloc (
  533. sizeof (struct webnet_module_upload_session));
  534. if (upload_session == RT_NULL) return 0; /* no memory */
  535. /* get boundary */
  536. boundary = strstr(session->request->content_type, BOUNDARY_STRING);
  537. if (boundary != RT_NULL)
  538. {
  539. int boundary_size;
  540. /* make boundary */
  541. boundary_size = strlen(boundary + sizeof(BOUNDARY_STRING) - 1) + 3;
  542. upload_session->boundary = wn_malloc(boundary_size);
  543. rt_sprintf(upload_session->boundary, "--%s", boundary + sizeof(BOUNDARY_STRING) - 1);
  544. }
  545. upload_session->filename = RT_NULL;
  546. upload_session->content_type = RT_NULL;
  547. upload_session->name_entries = RT_NULL;
  548. upload_session->name_entries_count = 0;
  549. upload_session->file_opened = 0;
  550. upload_session->entry = entry;
  551. upload_session->user_data = 0;
  552. /* add this upload session into webnet session */
  553. session->user_data = (rt_uint32_t) upload_session;
  554. /* set webnet session operations */
  555. session->session_ops = &_upload_ops;
  556. session->session_ops->session_handle(session, WEBNET_EVENT_READ);
  557. return WEBNET_MODULE_FINISHED;
  558. }
  559. int webnet_module_upload(struct webnet_session* session, int event)
  560. {
  561. if (event == WEBNET_EVENT_URI_PHYSICAL)
  562. {
  563. return webnet_module_upload_open(session);
  564. }
  565. return WEBNET_MODULE_CONTINUE;
  566. }
  567. /* webnet upload module APIs */
  568. void webnet_upload_add(const struct webnet_module_upload_entry* entry)
  569. {
  570. if (_upload_entries == RT_NULL)
  571. {
  572. _upload_entries_count = 1;
  573. /* first entries, malloc upload entry */
  574. _upload_entries = (const struct webnet_module_upload_entry**)
  575. wn_malloc (sizeof(struct webnet_module_upload_entry));
  576. }
  577. else
  578. {
  579. _upload_entries_count += 1;
  580. _upload_entries = (const struct webnet_module_upload_entry**) wn_realloc (_upload_entries,
  581. sizeof(void*) * _upload_entries_count);
  582. }
  583. RT_ASSERT(_upload_entries != RT_NULL);
  584. _upload_entries[_upload_entries_count - 1] = entry;
  585. }
  586. RTM_EXPORT(webnet_upload_add);
  587. const char* webnet_upload_get_filename(struct webnet_session* session)
  588. {
  589. struct webnet_module_upload_session *upload_session;
  590. /* get upload session */
  591. upload_session = (struct webnet_module_upload_session *)session->user_data;
  592. if (upload_session == RT_NULL) return RT_NULL;
  593. return upload_session->filename;
  594. }
  595. RTM_EXPORT(webnet_upload_get_filename);
  596. const char* webnet_upload_get_content_type(struct webnet_session* session)
  597. {
  598. struct webnet_module_upload_session *upload_session;
  599. /* get upload session */
  600. upload_session = (struct webnet_module_upload_session *)session->user_data;
  601. if (upload_session == RT_NULL) return RT_NULL;
  602. return upload_session->content_type;
  603. }
  604. RTM_EXPORT(webnet_upload_get_content_type);
  605. const char* webnet_upload_get_nameentry(struct webnet_session* session, const char* name)
  606. {
  607. rt_uint32_t index;
  608. struct webnet_module_upload_session *upload_session;
  609. /* get upload session */
  610. upload_session = (struct webnet_module_upload_session *)session->user_data;
  611. if (upload_session == RT_NULL) return RT_NULL;
  612. for (index = 0; index < upload_session->name_entries_count; index ++)
  613. {
  614. if (strcasecmp(upload_session->name_entries[index].name, name) == 0)
  615. {
  616. return upload_session->name_entries[index].value;
  617. }
  618. }
  619. return RT_NULL;
  620. }
  621. RTM_EXPORT(webnet_upload_get_nameentry);
  622. const void* webnet_upload_get_userdata(struct webnet_session* session)
  623. {
  624. struct webnet_module_upload_session *upload_session;
  625. /* get upload session */
  626. upload_session = (struct webnet_module_upload_session *)session->user_data;
  627. if (upload_session == RT_NULL) return RT_NULL;
  628. return (const void*) upload_session->user_data;
  629. }
  630. RTM_EXPORT(webnet_upload_get_userdata);
  631. /* ---- upload file interface ---- */
  632. int webnet_upload_file_open(struct webnet_session* session)
  633. {
  634. struct webnet_module_upload_session* upload_session;
  635. /* get upload session */
  636. upload_session = (struct webnet_module_upload_session *)session->user_data;
  637. if (upload_session->filename != RT_NULL)
  638. {
  639. /* open file */
  640. upload_session->user_data = open(upload_session->filename, O_WRONLY, 0);
  641. return upload_session->user_data;
  642. }
  643. return -1;
  644. }
  645. int webnet_upload_file_close(struct webnet_session* session)
  646. {
  647. int fd;
  648. struct webnet_module_upload_session* upload_session;
  649. /* get upload session */
  650. upload_session = (struct webnet_module_upload_session *)session->user_data;
  651. fd = upload_session->user_data;
  652. if (fd >= 0)
  653. {
  654. return close(fd);
  655. }
  656. return -1;
  657. }
  658. int webnet_upload_file_write(struct webnet_session* session, const void* data, rt_size_t length)
  659. {
  660. int fd;
  661. struct webnet_module_upload_session* upload_session;
  662. /* get upload session */
  663. upload_session = (struct webnet_module_upload_session *)session->user_data;
  664. fd = upload_session->user_data;
  665. if (fd >= 0)
  666. {
  667. return write(fd, data, length);
  668. }
  669. return 0;
  670. }
  671. #endif /* WEBNET_USING_UPLOAD */