luat_http_client.c 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334
  1. #include "luat_base.h"
  2. #include "luat_network_adapter.h"
  3. #include "luat_rtos.h"
  4. // #include "luat_msgbus.h"
  5. #include "luat_mem.h"
  6. #include "http_parser.h"
  7. #ifdef __LUATOS__
  8. #include "luat_fs.h"
  9. #include "luat_fota.h"
  10. #include "luat_spi.h"
  11. #include "luat_timer.h"
  12. #include "luat_str.h"
  13. #endif
  14. #include "luat_http.h"
  15. #define LUAT_LOG_TAG "http"
  16. #include "luat_log.h"
  17. #ifndef LUAT_HTTP_DEBUG
  18. #define LUAT_HTTP_DEBUG 0
  19. #endif
  20. #if LUAT_HTTP_DEBUG == 0
  21. #undef LLOGD
  22. #define LLOGD(...)
  23. #endif
  24. static void http_send_message(luat_http_ctrl_t *http_ctrl);
  25. static int32_t luat_lib_http_callback(void *data, void *param);
  26. #ifdef __LUATOS__
  27. int strncasecmp(const char *string1, const char *string2, size_t count);
  28. void luat_http_client_onevent(luat_http_ctrl_t *http_ctrl, int arg1, int arg2);
  29. int http_close(luat_http_ctrl_t *http_ctrl){
  30. LLOGD("http close %p", http_ctrl);
  31. if (http_ctrl->netc){
  32. network_close(http_ctrl->netc, 0);
  33. network_force_close_socket(http_ctrl->netc);
  34. network_release_ctrl(http_ctrl->netc);
  35. http_ctrl->netc = NULL;
  36. }
  37. if (http_ctrl->timeout_timer){
  38. luat_stop_rtos_timer(http_ctrl->timeout_timer);
  39. luat_release_rtos_timer(http_ctrl->timeout_timer);
  40. http_ctrl->timeout_timer = NULL;
  41. }
  42. if (http_ctrl->host){
  43. luat_heap_free(http_ctrl->host);
  44. http_ctrl->host = NULL;
  45. }
  46. if (http_ctrl->request_line){
  47. luat_heap_free(http_ctrl->request_line);
  48. http_ctrl->request_line = NULL;
  49. }
  50. if (http_ctrl->req_header){
  51. luat_heap_free(http_ctrl->req_header);
  52. http_ctrl->req_header = NULL;
  53. }
  54. if (http_ctrl->req_body){
  55. luat_heap_free(http_ctrl->req_body);
  56. http_ctrl->req_body = NULL;
  57. }
  58. if (http_ctrl->dst){
  59. luat_heap_free(http_ctrl->dst);
  60. http_ctrl->dst = NULL;
  61. }
  62. if (http_ctrl->headers){
  63. luat_heap_free(http_ctrl->headers);
  64. http_ctrl->headers = NULL;
  65. }
  66. if (http_ctrl->body){
  67. luat_heap_free(http_ctrl->body);
  68. http_ctrl->body = NULL;
  69. }
  70. if (http_ctrl->req_auth) {
  71. luat_heap_free(http_ctrl->req_auth);
  72. http_ctrl->req_auth = NULL;
  73. }
  74. luat_heap_free(http_ctrl);
  75. return 0;
  76. }
  77. static void http_resp_error(luat_http_ctrl_t *http_ctrl, int error_code) {
  78. LLOGD("http_resp_error error_code:%d close_state:%d",error_code,http_ctrl->close_state);
  79. #ifdef LUAT_USE_FOTA
  80. if (http_ctrl->isfota!=0 && error_code == HTTP_ERROR_FOTA){
  81. luat_fota_end(0);
  82. // if (http_ctrl->parser.status_code){
  83. // error_code = 0;
  84. // }
  85. luat_http_client_onevent(http_ctrl, error_code, 0);
  86. return;
  87. }
  88. #endif
  89. LLOGD("http_resp_error headers_complete:%d re_request_count:%d",http_ctrl->headers_complete,http_ctrl->re_request_count);
  90. if (http_ctrl->close_state == 0 && http_ctrl->headers_complete==1 && http_ctrl->re_request_count < HTTP_RE_REQUEST_MAX){
  91. http_ctrl->re_request_count++;
  92. network_close(http_ctrl->netc, 0);
  93. network_force_close_socket(http_ctrl->netc);
  94. if(network_connect(http_ctrl->netc, http_ctrl->host, strlen(http_ctrl->host), NULL, http_ctrl->remote_port, 0) < 0){
  95. LLOGE("http_resp_error network_connect error");
  96. goto error;
  97. }
  98. }else if (http_ctrl->close_state==0){
  99. error:
  100. http_ctrl->close_state=1;
  101. // network_close(http_ctrl->netc, 0);
  102. luat_http_client_onevent(http_ctrl, error_code, 0);
  103. }
  104. }
  105. static void luat_http_callback(luat_http_ctrl_t *http_ctrl){
  106. if (http_ctrl->http_cb){
  107. luat_http_client_onevent(http_ctrl, HTTP_CALLBACK, http_ctrl->body_len);
  108. // LLOGD("luat_http_callback content_length:%ld body_len:%ld",http_ctrl->resp_content_len, http_ctrl->body_len);
  109. }
  110. }
  111. #else
  112. static void http_network_error(luat_http_ctrl_t *http_ctrl);
  113. static void luat_http_dummy_cb(int status, void *data, uint32_t data_len, void *user_param) {;}
  114. static void http_network_close(luat_http_ctrl_t *http_ctrl)
  115. {
  116. http_ctrl->state = HTTP_STATE_WAIT_CLOSE;
  117. luat_rtos_timer_stop(http_ctrl->timeout_timer);
  118. if (!network_close(http_ctrl->netc, 0))
  119. {
  120. http_network_error(http_ctrl);
  121. }
  122. }
  123. static void http_network_error(luat_http_ctrl_t *http_ctrl)
  124. {
  125. if (++(http_ctrl->retry_cnt))
  126. {
  127. if (http_ctrl->retry_cnt >= http_ctrl->retry_cnt_max)
  128. {
  129. if (http_ctrl->error_code > 0)
  130. {
  131. http_ctrl->error_code = HTTP_ERROR_STATE;
  132. }
  133. http_ctrl->http_cb(http_ctrl->error_code, NULL, 0, http_ctrl->http_cb_userdata);
  134. return;
  135. }
  136. }
  137. if (http_ctrl->debug_onoff)
  138. {
  139. LLOGD("retry %d", http_ctrl->retry_cnt);
  140. }
  141. http_ctrl->state = HTTP_STATE_CONNECT;
  142. if (http_ctrl->timeout)
  143. {
  144. luat_start_rtos_timer(http_ctrl->timeout_timer, http_ctrl->timeout, 1);
  145. }
  146. else
  147. {
  148. luat_stop_rtos_timer(http_ctrl->timeout_timer);
  149. }
  150. if (network_connect(http_ctrl->netc, http_ctrl->host, strlen(http_ctrl->host), NULL, http_ctrl->remote_port, 0) < 0)
  151. {
  152. LLOGD("http can not connect!");
  153. http_ctrl->state = HTTP_STATE_IDLE;
  154. http_ctrl->error_code = HTTP_ERROR_CONNECT;
  155. network_close(http_ctrl->netc, 0);
  156. http_ctrl->http_cb(http_ctrl->error_code, NULL, 0, http_ctrl->http_cb_userdata);
  157. }
  158. }
  159. #endif
  160. static int on_header_field(http_parser* parser, const char *at, size_t length){
  161. LLOGD("on_header_field:%.*s",length,at);
  162. luat_http_ctrl_t *http_ctrl =(luat_http_ctrl_t *)parser->data;
  163. #ifdef __LUATOS__
  164. if (http_ctrl->headers_complete){
  165. return 0;
  166. }
  167. if(!strncasecmp(at, "Content-Length: ", 16) && http_ctrl->resp_content_len == 0){
  168. http_ctrl->resp_content_len = -1;
  169. }
  170. if (!http_ctrl->headers){
  171. http_ctrl->headers = luat_heap_malloc(length+2);
  172. }else{
  173. http_ctrl->headers = luat_heap_realloc(http_ctrl->headers,http_ctrl->headers_len+length+2);
  174. }
  175. memcpy(http_ctrl->headers+http_ctrl->headers_len,at,length);
  176. memcpy(http_ctrl->headers+http_ctrl->headers_len+length, ":", 1);
  177. http_ctrl->headers_len += length+1;
  178. #else
  179. char temp[16] = {':'};
  180. if (http_ctrl->state != HTTP_STATE_GET_HEAD)
  181. {
  182. LLOGD("!");
  183. return 0;
  184. }
  185. http_ctrl->response_head_buffer.Pos = 0;
  186. OS_BufferWrite(&http_ctrl->response_head_buffer, (void*)at, length);
  187. OS_BufferWrite(&http_ctrl->response_head_buffer, temp, 1);
  188. #endif
  189. return 0;
  190. }
  191. static int on_header_value(http_parser* parser, const char *at, size_t length){
  192. LLOGD("on_header_value:%.*s",length,at);
  193. char tmp[16] = {0};
  194. luat_http_ctrl_t *http_ctrl =(luat_http_ctrl_t *)parser->data;
  195. #ifdef __LUATOS__
  196. if (http_ctrl->headers_complete){
  197. return 0;
  198. }
  199. if(http_ctrl->resp_content_len == -1){
  200. memcpy(tmp, at, length);
  201. http_ctrl->resp_content_len = atoi(tmp);
  202. LLOGD("http_ctrl->resp_content_len:%d",http_ctrl->resp_content_len);
  203. }
  204. http_ctrl->headers = luat_heap_realloc(http_ctrl->headers,http_ctrl->headers_len+length+3);
  205. memcpy(http_ctrl->headers+http_ctrl->headers_len,at,length);
  206. memcpy(http_ctrl->headers+http_ctrl->headers_len+length, "\r\n", 2);
  207. http_ctrl->headers_len += length+2;
  208. #else
  209. if (http_ctrl->state != HTTP_STATE_GET_HEAD){
  210. LLOGD("http state error %d", http_ctrl->state);
  211. return 0;
  212. }
  213. OS_BufferWrite(&http_ctrl->response_head_buffer, (void *)at, length);
  214. OS_BufferWrite(&http_ctrl->response_head_buffer, tmp, 1);
  215. http_ctrl->http_cb(HTTP_STATE_GET_HEAD, http_ctrl->response_head_buffer.Data, http_ctrl->response_head_buffer.Pos, http_ctrl->http_cb_userdata);
  216. #endif
  217. return 0;
  218. }
  219. static int on_headers_complete(http_parser* parser){
  220. LLOGD("on_headers_complete");
  221. luat_http_ctrl_t *http_ctrl =(luat_http_ctrl_t *)parser->data;
  222. #ifdef __LUATOS__
  223. if (http_ctrl->headers_complete){
  224. return 0;
  225. }
  226. http_ctrl->headers[http_ctrl->headers_len] = 0x00;
  227. if (http_ctrl->is_download){
  228. luat_fs_remove(http_ctrl->dst);
  229. http_ctrl->fd = luat_fs_fopen(http_ctrl->dst, "w+");
  230. if (http_ctrl->fd == NULL) {
  231. LLOGE("open download file fail %s", http_ctrl->dst);
  232. }
  233. }
  234. #ifdef LUAT_USE_FOTA
  235. else if(http_ctrl->isfota){
  236. luat_fota_init(http_ctrl->address, http_ctrl->length, http_ctrl->spi_device, NULL, 0);
  237. }
  238. #endif
  239. http_ctrl->headers_complete = 1;
  240. luat_http_callback(http_ctrl);
  241. #else
  242. if (http_ctrl->state != HTTP_STATE_GET_HEAD){
  243. LLOGD("http state error %d", http_ctrl->state);
  244. return 0;
  245. }
  246. if (!http_ctrl->total_len)
  247. {
  248. if (http_ctrl->parser.content_length != -1)
  249. {
  250. http_ctrl->total_len = http_ctrl->parser.content_length;
  251. }
  252. else
  253. {
  254. LLOGD("no content lenght, maybe error!");
  255. }
  256. }
  257. if (http_ctrl->debug_onoff)
  258. {
  259. LLOGD("total %u done %u", http_ctrl->total_len, http_ctrl->done_len);
  260. }
  261. http_ctrl->http_cb(HTTP_STATE_GET_HEAD, NULL, 0, http_ctrl->http_cb_userdata);
  262. http_ctrl->state = HTTP_STATE_GET_BODY;
  263. #endif
  264. return 0;
  265. }
  266. static int on_body(http_parser* parser, const char *at, size_t length){
  267. // LLOGD("on_body:%.*s",length,at);
  268. luat_http_ctrl_t *http_ctrl =(luat_http_ctrl_t *)parser->data;
  269. #ifdef __LUATOS__
  270. LLOGD("on_body length:%d http_ctrl->body_len:%d status_code:%d",length,http_ctrl->body_len+length,parser->status_code);
  271. if (http_ctrl->is_download){
  272. if (http_ctrl->fd == NULL){
  273. luat_fs_remove(http_ctrl->dst);
  274. http_ctrl->fd = luat_fs_fopen(http_ctrl->dst, "w+");
  275. if (http_ctrl->fd == NULL) {
  276. LLOGE("open download file fail %s", http_ctrl->dst);
  277. http_resp_error(http_ctrl, HTTP_ERROR_DOWNLOAD);
  278. return -1;
  279. }
  280. }
  281. if (length != luat_fs_fwrite(at, length, 1, http_ctrl->fd)) {
  282. LLOGE("err when fwrite %s", http_ctrl->dst);
  283. http_resp_error(http_ctrl, HTTP_ERROR_DOWNLOAD);
  284. return -1;
  285. }
  286. }
  287. #ifdef LUAT_USE_FOTA
  288. else if(http_ctrl->isfota && (parser->status_code == 200 || parser->status_code == 206)){
  289. if (luat_fota_write((uint8_t*)at, length) < 0){
  290. luat_fota_end(0);
  291. http_resp_error(http_ctrl, HTTP_ERROR_FOTA);
  292. return -1;
  293. }
  294. }
  295. #endif
  296. else if(http_ctrl->is_post==0 && http_ctrl->zbuff_body!=NULL){
  297. if (http_ctrl->zbuff_body->len < http_ctrl->zbuff_body->used+length+1 ){
  298. void* tmpptr = luat_heap_realloc(http_ctrl->zbuff_body->addr,http_ctrl->zbuff_body->used+length+1);
  299. if (tmpptr == NULL) {
  300. LLOGE("out of memory when recv http body");
  301. http_resp_error(http_ctrl, HTTP_ERROR_DOWNLOAD);
  302. return -1;
  303. }
  304. http_ctrl->zbuff_body->addr = tmpptr;
  305. }
  306. memcpy(http_ctrl->zbuff_body->addr + http_ctrl->zbuff_body->used ,at,length);
  307. http_ctrl->zbuff_body->used += length;
  308. }
  309. else{
  310. if (!http_ctrl->body){
  311. http_ctrl->body = luat_heap_malloc(length+1);
  312. if (http_ctrl->body == NULL) {
  313. LLOGE("out of memory when recv http body");
  314. http_resp_error(http_ctrl, HTTP_ERROR_DOWNLOAD);
  315. return -1;
  316. }
  317. }else{
  318. void* tmpptr = luat_heap_realloc(http_ctrl->body,http_ctrl->body_len+length+1);
  319. if (tmpptr == NULL) {
  320. LLOGE("out of memory when recv http body");
  321. http_resp_error(http_ctrl, HTTP_ERROR_DOWNLOAD);
  322. return -1;
  323. }
  324. http_ctrl->body = tmpptr;
  325. }
  326. memcpy(http_ctrl->body+http_ctrl->body_len,at,length);
  327. }
  328. http_ctrl->body_len += length;
  329. luat_http_callback(http_ctrl);
  330. #else
  331. if (http_ctrl->state != HTTP_STATE_GET_BODY){
  332. LLOGD("http state error %d", http_ctrl->state);
  333. return 0;
  334. }
  335. http_ctrl->done_len += length;
  336. http_ctrl->http_cb(HTTP_STATE_GET_BODY, (void *)at, length, http_ctrl->http_cb_userdata);
  337. #endif
  338. return 0;
  339. }
  340. #ifdef __LUATOS__
  341. static int on_complete(http_parser* parser, luat_http_ctrl_t *http_ctrl){
  342. LLOGD("on_complete");
  343. // http_ctrl->body[http_ctrl->body_len] = 0x00;
  344. LLOGD("status_code:%d",parser->status_code);
  345. // LLOGD("content_length:%lld",parser->content_length);
  346. (void)parser;
  347. if (http_ctrl->fd != NULL) {
  348. luat_fs_fclose(http_ctrl->fd);
  349. http_ctrl->fd = NULL;
  350. if (parser->status_code > 299 && http_ctrl->dst) {
  351. LLOGW("download fail, remove file %s", http_ctrl->dst);
  352. luat_fs_remove(http_ctrl->dst);
  353. }
  354. }
  355. #ifdef LUAT_USE_FOTA
  356. else if(http_ctrl->isfota){
  357. if (parser->status_code == 200 || parser->status_code == 206){
  358. parser->status_code = 200;
  359. int result = luat_fota_done();
  360. LLOGD("result1:%d",result);
  361. while (result>0){ // TODO 应该有超时机制
  362. luat_timer_mdelay(100);
  363. result = luat_fota_done();
  364. }
  365. LLOGD("result2:%d",result);
  366. if (result==0){
  367. if (luat_fota_end(1)){
  368. LLOGE("fota finish error");
  369. http_resp_error(http_ctrl, HTTP_ERROR_FOTA);
  370. return -1;
  371. }
  372. }else{
  373. luat_fota_end(0);
  374. http_resp_error(http_ctrl, HTTP_ERROR_FOTA);
  375. return -1;
  376. }
  377. }else{
  378. luat_fota_end(0);
  379. http_ctrl->close_state = 1;
  380. // network_close(http_ctrl->netc, 0);
  381. http_resp_error(http_ctrl, HTTP_ERROR_FOTA);
  382. return -1;
  383. }
  384. }
  385. #endif
  386. // http_ctrl->close_state = 1;
  387. network_close(http_ctrl->netc, 0);
  388. luat_http_client_onevent(http_ctrl, HTTP_OK, 0);
  389. return 0;
  390. }
  391. #endif
  392. static int on_message_complete(http_parser* parser){
  393. LLOGD("on_message_complete");
  394. luat_http_ctrl_t *http_ctrl =(luat_http_ctrl_t *)parser->data;
  395. #ifdef __LUATOS__
  396. http_ctrl->close_state = 1;
  397. #else
  398. if (http_ctrl->done_len != http_ctrl->total_len)
  399. {
  400. LLOGD("http rx body len error %u,%u", http_ctrl->done_len, http_ctrl->total_len);
  401. }
  402. http_ctrl->http_cb(HTTP_STATE_GET_BODY, NULL, 0, http_ctrl->http_cb_userdata);
  403. http_ctrl->error_code = 0;
  404. http_ctrl->state = HTTP_STATE_DONE;
  405. luat_rtos_timer_stop(http_ctrl->timeout_timer);
  406. #endif
  407. return 0;
  408. }
  409. static int on_chunk_header(http_parser* parser){
  410. (void)parser;
  411. LLOGD("on_chunk_header");
  412. LLOGD("content_length:%lld",parser->content_length);
  413. // luat_http_ctrl_t *http_ctrl =(luat_http_ctrl_t *)parser->data;
  414. // http_ctrl->is_chunk = 1;
  415. return 0;
  416. }
  417. static const http_parser_settings parser_settings = {
  418. .on_header_field = on_header_field,
  419. .on_header_value = on_header_value,
  420. .on_headers_complete = on_headers_complete,
  421. .on_body = on_body,
  422. .on_message_complete = on_message_complete,
  423. .on_chunk_header = on_chunk_header
  424. };
  425. #ifdef __LUATOS__
  426. int luat_http_client_init(luat_http_ctrl_t* http_ctrl, int use_ipv6) {
  427. network_init_ctrl(http_ctrl->netc, NULL, luat_lib_http_callback, http_ctrl);
  428. network_set_base_mode(http_ctrl->netc, 1, 10000, 0, 0, 0, 0);
  429. network_set_local_port(http_ctrl->netc, 0);
  430. if (use_ipv6) {
  431. LLOGI("enable ipv6 support for http request");
  432. network_connect_ipv6_domain(http_ctrl->netc, 1);
  433. }
  434. return 0;
  435. }
  436. #endif
  437. #define HTTP_SEND_LEN_MAX (4096)
  438. static uint32_t http_send(luat_http_ctrl_t *http_ctrl, uint8_t* data, size_t len) {
  439. if (len == 0)
  440. return 0;
  441. uint32_t tx_len = 0;
  442. // LLOGD("http_send data:%.*s",len,data);
  443. network_tx(http_ctrl->netc, data, len, 0, NULL, 0, &tx_len, 0);
  444. return tx_len;
  445. }
  446. static void http_send_message(luat_http_ctrl_t *http_ctrl){
  447. // 发送请求行, 主要,这里都借用了resp_buff,但这并不会与resp冲突
  448. #ifdef __LUATOS__
  449. http_send(http_ctrl, (uint8_t*)http_ctrl->request_line, strlen((char*)http_ctrl->request_line));
  450. // 判断自定义headers是否有host
  451. if (http_ctrl->custom_host == 0) {
  452. snprintf_((char*)http_ctrl->resp_buff, HTTP_RESP_BUFF_SIZE, "Host: %s:%d\r\n", http_ctrl->host, http_ctrl->remote_port);
  453. http_send(http_ctrl, (uint8_t*)http_ctrl->resp_buff, strlen((char*)http_ctrl->resp_buff));
  454. }
  455. if (http_ctrl->headers_complete){
  456. snprintf_((char*)http_ctrl->resp_buff, HTTP_RESP_BUFF_SIZE, "Range: bytes=%d-\r\n", http_ctrl->body_len);
  457. http_send(http_ctrl, (uint8_t*)http_ctrl->resp_buff, strlen((char*)http_ctrl->resp_buff));
  458. }
  459. if (http_ctrl->req_auth) {
  460. http_send(http_ctrl, (uint8_t*)http_ctrl->req_auth, strlen((char*)http_ctrl->req_auth));
  461. }
  462. // 发送自定义头部
  463. if (http_ctrl->req_header){
  464. http_send(http_ctrl, (uint8_t*)http_ctrl->req_header, strlen((char*)http_ctrl->req_header));
  465. }
  466. // 结束头部
  467. http_send(http_ctrl, (uint8_t*)"\r\n", 2);
  468. // 发送body
  469. if (http_ctrl->req_body){
  470. if (http_ctrl->req_body_len > HTTP_SEND_LEN_MAX){
  471. http_send(http_ctrl, (uint8_t*)http_ctrl->req_body, HTTP_SEND_LEN_MAX);
  472. http_ctrl->tx_offset = HTTP_SEND_LEN_MAX;
  473. }else{
  474. http_send(http_ctrl, (uint8_t*)http_ctrl->req_body, http_ctrl->req_body_len);
  475. http_ctrl->tx_offset = 0;
  476. }
  477. }else if(http_ctrl->is_post==1 && http_ctrl->zbuff_body!=NULL){
  478. if (http_ctrl->zbuff_body->used > HTTP_SEND_LEN_MAX){
  479. http_send(http_ctrl, http_ctrl->zbuff_body->addr, HTTP_SEND_LEN_MAX);
  480. http_ctrl->tx_offset = HTTP_SEND_LEN_MAX;
  481. }else{
  482. http_send(http_ctrl, http_ctrl->zbuff_body->addr, http_ctrl->zbuff_body->used);
  483. http_ctrl->tx_offset = 0;
  484. }
  485. }
  486. #else
  487. int result;
  488. const char line[] = "Accept: application/octet-stream\r\n";
  489. uint8_t *temp = calloc(1, 320);
  490. http_ctrl->state = HTTP_STATE_SEND_HEAD;
  491. http_send(http_ctrl, (uint8_t *)http_ctrl->request_line, strlen((char*)http_ctrl->request_line));
  492. // 判断自定义headers是否有host
  493. if (http_ctrl->custom_host == 0) {
  494. result = snprintf_((char*)temp, 320, "Host: %s\r\n", http_ctrl->host);
  495. http_send(http_ctrl, temp, result);
  496. }
  497. if (http_ctrl->data_mode && (http_ctrl->offset || http_ctrl->done_len)){
  498. result = snprintf_((char *)temp, 320, "Range: bytes=%u-\r\n", (http_ctrl->offset + http_ctrl->done_len));
  499. if (http_ctrl->debug_onoff)
  500. {
  501. LLOGD("get offset %u+%u", http_ctrl->offset, http_ctrl->done_len);
  502. }
  503. http_send(http_ctrl, temp, result);
  504. }
  505. // 发送自定义头部
  506. if (http_ctrl->request_head_buffer.Data && http_ctrl->request_head_buffer.Pos){
  507. http_send(http_ctrl, http_ctrl->request_head_buffer.Data, http_ctrl->request_head_buffer.Pos);
  508. }
  509. if (http_ctrl->data_mode)
  510. {
  511. http_send(http_ctrl, (uint8_t *)line, sizeof(line) - 1);
  512. }
  513. // 结束头部
  514. http_send(http_ctrl, (uint8_t*)"\r\n", 2);
  515. // 发送body
  516. free(temp);
  517. http_ctrl->state = HTTP_STATE_GET_HEAD;
  518. if (http_ctrl->is_post)
  519. {
  520. http_ctrl->http_cb(HTTP_STATE_SEND_BODY_START, NULL, 0, http_ctrl->http_cb_userdata);
  521. }
  522. #endif
  523. }
  524. LUAT_RT_RET_TYPE luat_http_timer_callback(LUAT_RT_CB_PARAM){
  525. luat_http_ctrl_t * http_ctrl = (luat_http_ctrl_t *)param;
  526. #ifdef __LUATOS__
  527. http_resp_error(http_ctrl, HTTP_ERROR_TIMEOUT);
  528. #else
  529. if (http_ctrl->new_data)
  530. {
  531. http_ctrl->new_data = 0;
  532. }
  533. else
  534. {
  535. LLOGD("http timeout error!");
  536. http_ctrl->error_code = HTTP_ERROR_TIMEOUT;
  537. http_network_close(http_ctrl);
  538. }
  539. #endif
  540. }
  541. #ifdef __LUATOS__
  542. int32_t luat_lib_http_callback(void *data, void *param){
  543. OS_EVENT *event = (OS_EVENT *)data;
  544. luat_http_ctrl_t *http_ctrl =(luat_http_ctrl_t *)param;
  545. int ret = 0;
  546. LLOGD("LINK %d ON_LINE %d EVENT %d TX_OK %d CLOSED %d",EV_NW_RESULT_LINK & 0x0fffffff,EV_NW_RESULT_CONNECT & 0x0fffffff,EV_NW_RESULT_EVENT & 0x0fffffff,EV_NW_RESULT_TX & 0x0fffffff,EV_NW_RESULT_CLOSE & 0x0fffffff);
  547. LLOGD("luat_lib_http_callback %d %d %p",event->ID & 0x0fffffff,event->Param1, http_ctrl);
  548. if (event->Param1){
  549. LLOGD("LINK %d ON_LINE %d EVENT %d TX_OK %d CLOSED %d",EV_NW_RESULT_LINK & 0x0fffffff,EV_NW_RESULT_CONNECT & 0x0fffffff,EV_NW_RESULT_EVENT & 0x0fffffff,EV_NW_RESULT_TX & 0x0fffffff,EV_NW_RESULT_CLOSE & 0x0fffffff);
  550. LLOGE("http_ctrl close %08X %d",event->ID & 0x0fffffff, event->Param1);
  551. http_resp_error(http_ctrl, HTTP_ERROR_CLOSE);
  552. return -1;
  553. }
  554. if (event->ID == EV_NW_RESULT_LINK){
  555. return 0;
  556. }else if(event->ID == EV_NW_RESULT_CONNECT){
  557. http_ctrl->resp_buff_offset = 0; // 复位resp缓冲区
  558. http_ctrl->resp_headers_done = 0;
  559. http_parser_init(&http_ctrl->parser, HTTP_RESPONSE);
  560. http_ctrl->parser.data = http_ctrl;
  561. // TODO header 保持原始数据,在lua回调时才导出数据
  562. // if (http_ctrl->resp_headers) {
  563. // luat_heap_free(http_ctrl->resp_headers);
  564. // http_ctrl->resp_headers = NULL;
  565. // }
  566. http_send_message(http_ctrl);
  567. return 0;
  568. }else if(event->ID == EV_NW_RESULT_EVENT){
  569. uint32_t total_len = 0;
  570. uint32_t rx_len = 0;
  571. while (1) {
  572. int result = network_rx(http_ctrl->netc, NULL, 0, 0, NULL, NULL, &total_len);
  573. if (result) {
  574. http_resp_error(http_ctrl, HTTP_ERROR_RX);
  575. return -1;
  576. }
  577. if (0 == total_len)
  578. break;
  579. if (http_ctrl->resp_buff_offset + total_len > (HTTP_RESP_BUFF_SIZE - 1)) {
  580. total_len = HTTP_RESP_BUFF_SIZE - 1 - http_ctrl->resp_buff_offset;
  581. if (total_len < 1) {
  582. // 能到这里的就是片段太长了
  583. // 要么header太长, 要么chunked太长,拒绝吧
  584. http_resp_error(http_ctrl, HTTP_ERROR_RX);
  585. return -1;
  586. }
  587. }
  588. result = network_rx(http_ctrl->netc, (uint8_t*)http_ctrl->resp_buff+http_ctrl->resp_buff_offset, total_len, 0, NULL, NULL, &rx_len);
  589. LLOGD("result:%d rx_len:%d",result,rx_len);
  590. if (rx_len == 0||result!=0) {
  591. http_resp_error(http_ctrl, HTTP_ERROR_RX);
  592. return -1;
  593. }
  594. http_ctrl->resp_buff_offset += rx_len;
  595. //LLOGD("resp_buff_offset:%d resp_buff:%s",http_ctrl->resp_buff_offset,http_ctrl->resp_buff);
  596. // uint8_t *tmp = (uint8_t*)http_ctrl->resp_buff;
  597. //LLOGD("resp buff %.*s", http_ctrl->resp_buff_offset, http_ctrl->resp_buff);
  598. if (0 == http_ctrl->resp_headers_done) {
  599. LLOGD("search headers, buff len %d", http_ctrl->resp_buff_offset);
  600. if (http_ctrl->resp_buff_offset > 4) {
  601. uint8_t *tmp = (uint8_t*)http_ctrl->resp_buff;
  602. size_t search = http_ctrl->resp_buff_offset;
  603. for (size_t i = 0; i < search; i++)
  604. {
  605. // \\r\\n\\r\\n
  606. // \\n\\n
  607. // \\r\\r
  608. if ((0x0D == tmp[i] && 0x0A == tmp[i+1] && 0x0D == tmp[i+2] && 0x0A == tmp[i+3]) ||
  609. (0x0A == tmp[i] && 0x0A == tmp[i+1]) ||
  610. (0x0D == tmp[i] && 0x0D == tmp[i+1]) ){
  611. http_ctrl->resp_headers_done = 1;
  612. LLOGD("found headers end at %d", i);
  613. break;
  614. }
  615. }
  616. }
  617. }
  618. if (http_ctrl->resp_headers_done) {
  619. size_t nParseBytes = http_parser_execute(&http_ctrl->parser, &parser_settings, http_ctrl->resp_buff, http_ctrl->resp_buff_offset);
  620. LLOGD("nParseBytes %d resp_buff_offset %d", nParseBytes, http_ctrl->resp_buff_offset);
  621. if (http_ctrl->close_state) {
  622. http_ctrl->resp_buff_offset = 0;
  623. on_complete(&http_ctrl->parser, http_ctrl);
  624. return 0;
  625. }
  626. if (http_ctrl->resp_buff_offset <= nParseBytes) {
  627. http_ctrl->resp_buff_offset = 0;
  628. }
  629. else {
  630. memmove(http_ctrl->resp_buff, http_ctrl->resp_buff + nParseBytes, http_ctrl->resp_buff_offset - nParseBytes);
  631. http_ctrl->resp_buff_offset -= nParseBytes;
  632. }
  633. }
  634. else {
  635. LLOGD("wait headers %.*s", http_ctrl->resp_buff_offset, http_ctrl->resp_buff);
  636. }
  637. if (http_ctrl->close_state){
  638. return 0;
  639. }
  640. }
  641. }else if(event->ID == EV_NW_RESULT_TX){
  642. if (http_ctrl->tx_offset){
  643. if (http_ctrl->req_body){
  644. if (http_ctrl->req_body_len-http_ctrl->tx_offset > HTTP_SEND_LEN_MAX){
  645. http_send(http_ctrl, (uint8_t*)http_ctrl->req_body+http_ctrl->tx_offset, HTTP_SEND_LEN_MAX);
  646. http_ctrl->tx_offset += HTTP_SEND_LEN_MAX;
  647. }else{
  648. http_send(http_ctrl, (uint8_t*)http_ctrl->req_body+http_ctrl->tx_offset, http_ctrl->req_body_len-http_ctrl->tx_offset);
  649. http_ctrl->tx_offset = 0;
  650. }
  651. }else if(http_ctrl->is_post==1 && http_ctrl->zbuff_body!=NULL){
  652. if (http_ctrl->zbuff_body->used-http_ctrl->tx_offset > HTTP_SEND_LEN_MAX){
  653. http_send(http_ctrl, http_ctrl->zbuff_body->addr+http_ctrl->tx_offset, HTTP_SEND_LEN_MAX);
  654. http_ctrl->tx_offset += HTTP_SEND_LEN_MAX;
  655. }else{
  656. http_send(http_ctrl, http_ctrl->zbuff_body->addr+http_ctrl->tx_offset, http_ctrl->zbuff_body->used-http_ctrl->tx_offset);
  657. http_ctrl->tx_offset = 0;
  658. }
  659. }
  660. }
  661. return 0;
  662. }else if(event->ID == EV_NW_RESULT_CLOSE){
  663. // http_close(http_ctrl);
  664. return 0;
  665. }
  666. ret = network_wait_event(http_ctrl->netc, NULL, 0, NULL);
  667. LLOGD("network_wait_event %d", ret);
  668. if (ret < 0){
  669. http_resp_error(http_ctrl, HTTP_ERROR_CLOSE);
  670. return -1;
  671. }
  672. return 0;
  673. }
  674. #else
  675. static int32_t luat_lib_http_callback(void *data, void *param){
  676. OS_EVENT *event = (OS_EVENT *)data;
  677. luat_http_ctrl_t *http_ctrl =(luat_http_ctrl_t *)param;
  678. if (HTTP_STATE_IDLE == http_ctrl->state)
  679. {
  680. LLOGD("http state error %d", http_ctrl->state);
  681. return 0;
  682. }
  683. int ret = 0;
  684. size_t nParseBytes;
  685. uint32_t rx_len = 0;
  686. if (event->Param1){
  687. LLOGD("http network error!");
  688. http_ctrl->error_code = HTTP_ERROR_STATE;
  689. http_network_close(http_ctrl);
  690. return -1;
  691. }
  692. switch(event->ID)
  693. {
  694. case EV_NW_RESULT_EVENT:
  695. http_ctrl->new_data = 1;
  696. if (http_ctrl->is_pause)
  697. {
  698. if (http_ctrl->debug_onoff)
  699. {
  700. LLOGD("rx pause");
  701. }
  702. break;
  703. }
  704. while (1)
  705. {
  706. int result = network_rx(http_ctrl->netc, http_ctrl->response_cache.Data + http_ctrl->response_cache.Pos, http_ctrl->response_cache.MaxLen - http_ctrl->response_cache.Pos, 0, NULL, NULL, &rx_len);
  707. if (result)
  708. {
  709. http_ctrl->error_code = HTTP_ERROR_RX;
  710. http_network_close(http_ctrl);
  711. }
  712. if (rx_len > 0)
  713. {
  714. http_ctrl->response_cache.Pos += rx_len;
  715. nParseBytes = http_parser_execute(&http_ctrl->parser, &parser_settings, (const char*)http_ctrl->response_cache.Data, http_ctrl->response_cache.Pos);
  716. OS_BufferRemove(&http_ctrl->response_cache, nParseBytes);
  717. }
  718. else
  719. {
  720. break;
  721. }
  722. }
  723. break;
  724. case EV_NW_RESULT_CONNECT:
  725. http_ctrl->response_cache.Pos = 0;
  726. http_parser_init(&http_ctrl->parser, HTTP_RESPONSE);
  727. http_ctrl->parser.data = http_ctrl;
  728. http_send_message(http_ctrl);
  729. break;
  730. case EV_NW_RESULT_TX:
  731. if (http_ctrl->is_post)
  732. {
  733. http_ctrl->http_cb(HTTP_STATE_SEND_BODY, NULL, 0, http_ctrl->http_cb_userdata);
  734. }
  735. http_ctrl->state = HTTP_STATE_GET_HEAD;
  736. break;
  737. case EV_NW_RESULT_CLOSE:
  738. if (http_ctrl->error_code && (http_ctrl->state != HTTP_STATE_DONE))
  739. {
  740. if (http_ctrl->debug_onoff)
  741. {
  742. LLOGD("http network closed");
  743. }
  744. http_network_error(http_ctrl);
  745. }
  746. else
  747. {
  748. http_ctrl->state = HTTP_STATE_IDLE;
  749. http_ctrl->http_cb(http_ctrl->state, NULL, 0, http_ctrl->http_cb_userdata);
  750. }
  751. return 0;
  752. case EV_NW_RESULT_LINK:
  753. return 0;
  754. }
  755. ret = network_wait_event(http_ctrl->netc, NULL, 0, NULL);
  756. if (ret < 0){
  757. http_ctrl->error_code = HTTP_ERROR_STATE;
  758. http_network_close(http_ctrl);
  759. return -1;
  760. }
  761. return 0;
  762. }
  763. #endif
  764. #ifndef __LUATOS__
  765. luat_http_ctrl_t* luat_http_client_create(luat_http_cb cb, void *user_param, int adapter_index)
  766. {
  767. luat_http_ctrl_t *http_ctrl = calloc(1, sizeof(luat_http_ctrl_t));
  768. if (!http_ctrl) return NULL;
  769. http_ctrl->timeout_timer = luat_create_rtos_timer(luat_http_timer_callback, http_ctrl, NULL);
  770. if (!http_ctrl->timeout_timer)
  771. {
  772. free(http_ctrl);
  773. LLOGD("no more timer");
  774. return NULL;
  775. }
  776. if (adapter_index >= 0)
  777. {
  778. http_ctrl->netc = network_alloc_ctrl(adapter_index);
  779. }
  780. else
  781. {
  782. http_ctrl->netc = network_alloc_ctrl(network_get_last_register_adapter());
  783. }
  784. if (!http_ctrl->netc)
  785. {
  786. luat_release_rtos_timer(http_ctrl->timeout_timer);
  787. free(http_ctrl);
  788. LLOGD("no more network ctrl");
  789. return NULL;
  790. }
  791. network_init_ctrl(http_ctrl->netc, NULL, luat_lib_http_callback, http_ctrl);
  792. network_set_base_mode(http_ctrl->netc, 1, 10000, 0, 0, 0, 0);
  793. network_set_local_port(http_ctrl->netc, 0);
  794. http_ctrl->http_cb = cb?cb:luat_http_dummy_cb;
  795. http_ctrl->http_cb_userdata = user_param;
  796. http_ctrl->timeout = 15000;
  797. http_ctrl->retry_cnt_max = 3;
  798. http_ctrl->state = HTTP_STATE_IDLE;
  799. http_ctrl->debug_onoff = 0;
  800. http_ctrl->netc->is_debug = 0;
  801. return http_ctrl;
  802. }
  803. int luat_http_client_base_config(luat_http_ctrl_t* http_ctrl, uint32_t timeout, uint8_t debug_onoff, uint8_t retry_cnt)
  804. {
  805. if (!http_ctrl) return -ERROR_PARAM_INVALID;
  806. if (http_ctrl->state)
  807. {
  808. if (http_ctrl->debug_onoff)
  809. {
  810. LLOGD("http running, please stop and set");
  811. }
  812. return -ERROR_PERMISSION_DENIED;
  813. }
  814. http_ctrl->timeout = timeout;
  815. http_ctrl->debug_onoff = debug_onoff;
  816. http_ctrl->netc->is_debug = debug_onoff;
  817. http_ctrl->retry_cnt_max = retry_cnt;
  818. return 0;
  819. }
  820. int luat_http_client_ssl_config(luat_http_ctrl_t* http_ctrl, int mode, const char *server_cert, uint32_t server_cert_len,
  821. const char *client_cert, uint32_t client_cert_len,
  822. const char *client_cert_key, uint32_t client_cert_key_len,
  823. const char *client_cert_key_password, uint32_t client_cert_key_password_len)
  824. {
  825. if (!http_ctrl) return -ERROR_PARAM_INVALID;
  826. if (http_ctrl->state)
  827. {
  828. if (http_ctrl->debug_onoff)
  829. {
  830. LLOGD("http running, please stop and set");
  831. }
  832. return -ERROR_PERMISSION_DENIED;
  833. }
  834. if (mode < 0)
  835. {
  836. network_deinit_tls(http_ctrl->netc);
  837. return 0;
  838. }
  839. if (mode > 2)
  840. {
  841. return -ERROR_PARAM_INVALID;
  842. }
  843. int result;
  844. // network_init_tls(http_ctrl->netc, (server_cert || client_cert)?2:0);
  845. network_init_tls(http_ctrl->netc, 0);
  846. if (server_cert){
  847. result = network_set_server_cert(http_ctrl->netc, (const unsigned char *)server_cert, server_cert_len);
  848. if (result)
  849. {
  850. LLOGD("set server cert failed %d", result);
  851. return -ERROR_OPERATION_FAILED;
  852. }
  853. }
  854. if (client_cert){
  855. result = network_set_client_cert(http_ctrl->netc, (const unsigned char *)client_cert, client_cert_len,
  856. (const unsigned char *)client_cert_key, client_cert_key_len,
  857. (const unsigned char *)client_cert_key_password, client_cert_key_password_len);
  858. if (result)
  859. {
  860. LLOGD("set client cert failed %d", result);
  861. return -ERROR_OPERATION_FAILED;
  862. }
  863. }
  864. return 0;
  865. }
  866. int luat_http_client_clear(luat_http_ctrl_t *http_ctrl)
  867. {
  868. OS_DeInitBuffer(&http_ctrl->request_head_buffer);
  869. return 0;
  870. }
  871. int luat_http_client_set_user_head(luat_http_ctrl_t *http_ctrl, const char *name, const char *value)
  872. {
  873. if (!http_ctrl) return -ERROR_PARAM_INVALID;
  874. if (http_ctrl->state)
  875. {
  876. if (http_ctrl->debug_onoff)
  877. {
  878. LLOGD("http running, please stop and set");
  879. }
  880. return -ERROR_PERMISSION_DENIED;
  881. }
  882. if (!http_ctrl->request_head_buffer.Data)
  883. {
  884. OS_InitBuffer(&http_ctrl->request_head_buffer, HTTP_RESP_BUFF_SIZE);
  885. }
  886. int ret = sprintf_((char *)http_ctrl->request_head_buffer.Data + http_ctrl->request_head_buffer.Pos, "%s:%s\r\n", name, value);
  887. if (ret > 0)
  888. {
  889. http_ctrl->request_head_buffer.Pos += ret;
  890. if (!strcmp("Host", name) || !strcmp("host", name))
  891. {
  892. http_ctrl->custom_host = 1;
  893. }
  894. return 0;
  895. }
  896. else
  897. {
  898. return -ERROR_OPERATION_FAILED;
  899. }
  900. }
  901. int luat_http_client_close(luat_http_ctrl_t *http_ctrl)
  902. {
  903. if (!http_ctrl) return -ERROR_PARAM_INVALID;
  904. if (http_ctrl->debug_onoff)
  905. {
  906. LLOGD("user close http!");
  907. }
  908. http_ctrl->state = HTTP_STATE_WAIT_CLOSE;
  909. http_ctrl->retry_cnt = http_ctrl->retry_cnt_max;
  910. network_force_close_socket(http_ctrl->netc);
  911. luat_rtos_timer_stop(http_ctrl->timeout_timer);
  912. http_ctrl->state = HTTP_STATE_IDLE;
  913. http_ctrl->offset = 0;
  914. return 0;
  915. }
  916. int luat_http_client_destroy(luat_http_ctrl_t **p_http_ctrl)
  917. {
  918. if (!p_http_ctrl) return -ERROR_PARAM_INVALID;
  919. luat_http_ctrl_t *http_ctrl = *p_http_ctrl;
  920. if (!http_ctrl) return -ERROR_PARAM_INVALID;
  921. if (http_ctrl->debug_onoff)
  922. {
  923. LLOGD("user destroy http!");
  924. }
  925. http_ctrl->state = HTTP_STATE_WAIT_CLOSE;
  926. network_force_close_socket(http_ctrl->netc);
  927. luat_rtos_timer_stop(http_ctrl->timeout_timer);
  928. luat_release_rtos_timer(http_ctrl->timeout_timer);
  929. network_release_ctrl(http_ctrl->netc);
  930. if (http_ctrl->host){
  931. free(http_ctrl->host);
  932. }
  933. if (http_ctrl->request_line){
  934. free(http_ctrl->request_line);
  935. }
  936. OS_DeInitBuffer(&http_ctrl->request_head_buffer);
  937. OS_DeInitBuffer(&http_ctrl->response_head_buffer);
  938. OS_DeInitBuffer(&http_ctrl->response_cache);
  939. free(http_ctrl);
  940. *p_http_ctrl = NULL;
  941. return 0;
  942. }
  943. int luat_http_client_get_status_code(luat_http_ctrl_t *http_ctrl)
  944. {
  945. if (!http_ctrl) return -ERROR_PARAM_INVALID;
  946. return http_ctrl->parser.status_code;
  947. }
  948. int luat_http_client_set_get_offset(luat_http_ctrl_t *http_ctrl, uint32_t offset)
  949. {
  950. if (!http_ctrl) return -ERROR_PARAM_INVALID;
  951. if (http_ctrl->state)
  952. {
  953. if (http_ctrl->debug_onoff)
  954. {
  955. LLOGD("http running, stop and set!");
  956. }
  957. return -ERROR_PERMISSION_DENIED;
  958. }
  959. http_ctrl->offset = offset;
  960. return 0;
  961. }
  962. int luat_http_client_pause(luat_http_ctrl_t *http_ctrl, uint8_t is_pause)
  963. {
  964. if (!http_ctrl) return -ERROR_PARAM_INVALID;
  965. if (http_ctrl->state != HTTP_STATE_GET_BODY)
  966. {
  967. if (http_ctrl->debug_onoff)
  968. {
  969. LLOGD("http not recv body data, no use!");
  970. }
  971. return -ERROR_PERMISSION_DENIED;
  972. }
  973. if (http_ctrl->debug_onoff)
  974. {
  975. LLOGD("http pause state %d!", is_pause);
  976. }
  977. http_ctrl->is_pause = is_pause;
  978. if (!http_ctrl->is_pause)
  979. {
  980. OS_EVENT event = {EV_NW_RESULT_EVENT, 0, 0, 0};
  981. luat_lib_http_callback(&event, http_ctrl);
  982. }
  983. return 0;
  984. }
  985. int luat_http_client_post_body(luat_http_ctrl_t *http_ctrl, void *data, uint32_t len)
  986. {
  987. if (!http_ctrl) return -ERROR_PARAM_INVALID;
  988. if (http_ctrl->state != HTTP_STATE_GET_HEAD)
  989. {
  990. return -ERROR_PERMISSION_DENIED;
  991. }
  992. http_send(http_ctrl, data, len);
  993. return 0;
  994. }
  995. int luat_http_client_start(luat_http_ctrl_t *http_ctrl, const char *url, uint8_t type, uint8_t ipv6, uint8_t data_mode)
  996. {
  997. if (!http_ctrl) return -ERROR_PARAM_INVALID;
  998. if (http_ctrl->state)
  999. {
  1000. if (http_ctrl->debug_onoff)
  1001. {
  1002. LLOGD("http running, please stop and start");
  1003. }
  1004. return -ERROR_PERMISSION_DENIED;
  1005. }
  1006. switch(type)
  1007. {
  1008. case 0:
  1009. case 3:
  1010. http_ctrl->is_post = 0;
  1011. break;
  1012. case 1:
  1013. case 2:
  1014. http_ctrl->is_post = 1;
  1015. break;
  1016. default:
  1017. return -ERROR_PARAM_INVALID;
  1018. }
  1019. http_ctrl->data_mode = data_mode;
  1020. http_ctrl->retry_cnt = 0;
  1021. http_ctrl->total_len = 0;
  1022. http_ctrl->done_len = 0;
  1023. http_ctrl->remote_port = 0;
  1024. http_ctrl->parser.status_code = 0;
  1025. OS_ReInitBuffer(&http_ctrl->response_head_buffer, HTTP_HEADER_BASE_SIZE);
  1026. OS_ReInitBuffer(&http_ctrl->response_cache, HTTP_RESP_BUFF_SIZE);
  1027. network_connect_ipv6_domain(http_ctrl->netc, ipv6);
  1028. if (http_ctrl->host)
  1029. {
  1030. free(http_ctrl->host);
  1031. http_ctrl->host = NULL;
  1032. }
  1033. if (http_ctrl->request_line)
  1034. {
  1035. free(http_ctrl->request_line);
  1036. http_ctrl->request_line = NULL;
  1037. }
  1038. char *tmp = (char *)url;
  1039. if (!strncmp("https://", url, strlen("https://"))) {
  1040. http_ctrl->is_tls = 1;
  1041. tmp += strlen("https://");
  1042. }
  1043. else if (!strncmp("http://", url, strlen("http://"))) {
  1044. http_ctrl->is_tls = 0;
  1045. tmp += strlen("http://");
  1046. }
  1047. else {
  1048. LLOGD("only http/https supported %s", url);
  1049. return -ERROR_PARAM_INVALID;
  1050. }
  1051. int tmplen = strlen(tmp);
  1052. if (tmplen < 5) {
  1053. LLOGD("url too short %s", url);
  1054. return -ERROR_PARAM_INVALID;
  1055. }
  1056. char tmphost[256] = {0};
  1057. char *tmpuri = NULL;
  1058. for (size_t i = 0; i < tmplen; i++){
  1059. if (tmp[i] == '/') {
  1060. if (i > 255) {
  1061. LLOGD("host too long %s", url);
  1062. return -ERROR_PARAM_INVALID;
  1063. }
  1064. tmpuri = tmp + i;
  1065. break;
  1066. }else if(i == tmplen-1){
  1067. tmphost[i+2] = '/';
  1068. tmpuri = tmp + i+1;
  1069. }
  1070. tmphost[i] = tmp[i];
  1071. }
  1072. if (strlen(tmphost) < 1) {
  1073. LLOGD("host not found %s", url);
  1074. return -ERROR_PARAM_INVALID;
  1075. }
  1076. if (strlen(tmpuri) == 0) {
  1077. tmpuri = "/";
  1078. }
  1079. // LLOGD("tmphost:%s",tmphost);
  1080. // LLOGD("tmpuri:%s",tmpuri);
  1081. for (size_t i = 1; i < strlen(tmphost); i++){
  1082. if (tmphost[i] == ':') {
  1083. tmphost[i] = '\0';
  1084. http_ctrl->remote_port = atoi(tmphost + i + 1);
  1085. break;
  1086. }
  1087. }
  1088. if (http_ctrl->remote_port <= 0) {
  1089. if (http_ctrl->is_tls)
  1090. http_ctrl->remote_port = 443;
  1091. else
  1092. http_ctrl->remote_port = 80;
  1093. }
  1094. http_ctrl->host = malloc(strlen(tmphost) + 1);
  1095. if (http_ctrl->host == NULL) {
  1096. LLOGD("out of memory when malloc host");
  1097. return -ERROR_NO_MEMORY;
  1098. }
  1099. memcpy(http_ctrl->host, tmphost, strlen(tmphost) + 1);
  1100. size_t linelen = strlen((char*)tmpuri) + 32;
  1101. http_ctrl->request_line = malloc(linelen);
  1102. if (http_ctrl->request_line == NULL) {
  1103. LLOGD("out of memory when malloc url/request_line");
  1104. return -ERROR_NO_MEMORY;
  1105. }
  1106. const char *me[4] = {
  1107. "GET","POST","PUT","DELETE"
  1108. };
  1109. snprintf_((char*)http_ctrl->request_line, 8192, "%s %s HTTP/1.1\r\n", me[type], tmpuri);
  1110. if (http_ctrl->timeout)
  1111. {
  1112. luat_start_rtos_timer(http_ctrl->timeout_timer, http_ctrl->timeout, 1);
  1113. }
  1114. else
  1115. {
  1116. luat_stop_rtos_timer(http_ctrl->timeout_timer);
  1117. }
  1118. http_ctrl->state = HTTP_STATE_CONNECT;
  1119. if (http_ctrl->debug_onoff)
  1120. {
  1121. LLOGD("http connect %s:%d", http_ctrl->host, http_ctrl->remote_port);
  1122. }
  1123. http_ctrl->error_code = HTTP_ERROR_CONNECT;
  1124. if (network_connect(http_ctrl->netc, http_ctrl->host, strlen(http_ctrl->host), NULL, http_ctrl->remote_port, 0) < 0)
  1125. {
  1126. LLOGD("http can not connect!");
  1127. network_close(http_ctrl->netc, 0);
  1128. http_ctrl->state = HTTP_STATE_IDLE;
  1129. return -1;
  1130. }
  1131. return 0;
  1132. }
  1133. #endif
  1134. #ifdef __LUATOS__
  1135. int http_set_url(luat_http_ctrl_t *http_ctrl, const char* url, const char* method) {
  1136. const char *tmp = url;
  1137. if (strcmp("POST", method) != 0 && strcmp("GET", method) != 0 && strcmp("PUT", method) != 0){
  1138. LLOGE("NOT SUPPORT %s",method);
  1139. return -1;
  1140. }
  1141. if (!strncmp("https://", url, strlen("https://"))) {
  1142. http_ctrl->is_tls = 1;
  1143. tmp += strlen("https://");
  1144. }
  1145. else if (!strncmp("http://", url, strlen("http://"))) {
  1146. http_ctrl->is_tls = 0;
  1147. tmp += strlen("http://");
  1148. }
  1149. else {
  1150. LLOGI("only http/https supported %s", url);
  1151. return -1;
  1152. }
  1153. size_t tmplen = strlen(tmp);
  1154. if (tmplen < 5) {
  1155. LLOGI("url too short %s", url);
  1156. return -1;
  1157. }
  1158. #define HOST_MAX_LEN (256)
  1159. #define AUTH_MAX_LEN (128)
  1160. char tmphost[HOST_MAX_LEN] = {0};
  1161. char tmpauth[AUTH_MAX_LEN] = {0};
  1162. const char *tmpuri = NULL;
  1163. for (size_t i = 0; i < tmplen; i++){
  1164. if (tmp[i] == '/') {
  1165. if (i > 255) {
  1166. LLOGI("host too long %s", url);
  1167. return -1;
  1168. }
  1169. tmpuri = tmp + i;
  1170. break;
  1171. }else if(i == tmplen-1){
  1172. tmphost[i+2] = '/';
  1173. tmpuri = tmp + i+1;
  1174. }
  1175. tmphost[i] = tmp[i];
  1176. }
  1177. if (strlen(tmphost) < 1) {
  1178. LLOGI("host not found %s", url);
  1179. return -1;
  1180. }
  1181. if (strlen(tmpuri) == 0) {
  1182. tmpuri = "/";
  1183. }
  1184. // 先判断有无鉴权信息
  1185. for (size_t i = 1; i < AUTH_MAX_LEN; i++){
  1186. if (tmphost[i] == '@') {
  1187. memcpy(tmpauth, tmphost, i);
  1188. memmove(tmphost, tmphost + i + 1, strlen(tmphost) - i - 1);
  1189. tmphost[strlen(tmphost) - i - 1] = 0x00;
  1190. break;
  1191. }
  1192. }
  1193. // LLOGD("tmphost:%s",tmphost);
  1194. // LLOGD("tmpauth:%s", tmpauth);
  1195. // LLOGD("tmpuri:%s",tmpuri);
  1196. for (size_t i = 1; i < strlen(tmphost); i++){
  1197. if (tmphost[i] == ':') {
  1198. tmphost[i] = '\0';
  1199. http_ctrl->remote_port = atoi(tmphost + i + 1);
  1200. break;
  1201. }
  1202. }
  1203. if (http_ctrl->remote_port <= 0) {
  1204. if (http_ctrl->is_tls)
  1205. http_ctrl->remote_port = 443;
  1206. else
  1207. http_ctrl->remote_port = 80;
  1208. }
  1209. http_ctrl->host = luat_heap_malloc(strlen(tmphost) + 1);
  1210. if (http_ctrl->host == NULL) {
  1211. LLOGE("out of memory when malloc host");
  1212. return -1;
  1213. }
  1214. if (tmpauth[0]) {
  1215. size_t tmplen = 0;
  1216. http_ctrl->req_auth = luat_heap_malloc(strlen(tmpauth) * 2 + 64);
  1217. if (http_ctrl->req_auth == NULL) {
  1218. LLOGE("out of memory when malloc auth");
  1219. return -1;
  1220. }
  1221. memset(http_ctrl->req_auth, 0, strlen(tmpauth) * 2 + 64);
  1222. memcpy(http_ctrl->req_auth, "Authorization: Basic ", strlen("Authorization: Basic "));
  1223. luat_str_base64_encode((unsigned char *)http_ctrl->req_auth + strlen(http_ctrl->req_auth),
  1224. strlen(tmpauth) * 2, &tmplen, (const unsigned char *)tmpauth, strlen(tmpauth));
  1225. memcpy(http_ctrl->req_auth + strlen(http_ctrl->req_auth), "\r\n", 2);
  1226. }
  1227. memcpy(http_ctrl->host, tmphost, strlen(tmphost) + 1);
  1228. size_t linelen = strlen((char*)method) + strlen((char*)tmpuri) + 16;
  1229. http_ctrl->request_line = luat_heap_malloc(linelen);
  1230. if (http_ctrl->request_line == NULL) {
  1231. LLOGE("out of memory when malloc url/request_line");
  1232. return -1;
  1233. }
  1234. snprintf_((char*)http_ctrl->request_line, 8192, "%s %s HTTP/1.1\r\n", method, tmpuri);
  1235. return 0;
  1236. }
  1237. int luat_http_client_start(luat_http_ctrl_t* http_ctrl) {
  1238. if(http_ctrl->timeout){
  1239. http_ctrl->timeout_timer = luat_create_rtos_timer(luat_http_timer_callback, http_ctrl, NULL);
  1240. luat_start_rtos_timer(http_ctrl->timeout_timer, http_ctrl->timeout, 0);
  1241. }
  1242. if(network_connect(http_ctrl->netc, http_ctrl->host, strlen(http_ctrl->host), NULL, http_ctrl->remote_port, 0) < 0){
  1243. // network_close(http_ctrl->netc, 0);
  1244. return -1;
  1245. }
  1246. return 0;
  1247. }
  1248. #endif