luat_http.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. #include "luat_base.h"
  2. #include "luat_http.h"
  3. #include "luat_malloc.h"
  4. #include "string.h"
  5. #define LUAT_LOG_TAG "http"
  6. #include "luat_log.h"
  7. int luat_http_init(luat_http_ctx_t *ctx) {
  8. if (ctx == NULL)
  9. return -1;
  10. memset(ctx, 0, sizeof(ctx));
  11. return 0;
  12. }
  13. int luat_http_set_url(luat_http_ctx_t *ctx, char* url, int method) {
  14. if (ctx == NULL || url == NULL)
  15. return -1;
  16. ctx->method = method;
  17. // 首先, 截取 http/https头部
  18. char *tmp = url;
  19. if (!strncmp("https://", url, strlen("https://"))) {
  20. ctx->ssl = 1;
  21. tmp += strlen("https://");
  22. }
  23. else if (!strncmp("http://", url, strlen("http://"))) {
  24. ctx->ssl = 0;
  25. tmp += strlen("http://");
  26. }
  27. else {
  28. LLOGI("only http/https supported %s", url);
  29. return -2;
  30. }
  31. // 然后, 分解URL成 host:port 和 uri 两部分
  32. int tmplen = strlen(tmp);
  33. if (tmplen < 5) {
  34. LLOGI("url too short %s", url);
  35. return -3;
  36. }
  37. char tmphost[256] = {0};
  38. char *tmpuri = NULL;
  39. for (size_t i = 1; i < tmplen; i++)
  40. {
  41. if (tmp[i] == '/') {
  42. if (i > 255) {
  43. LLOGI("host too long %s", url);
  44. return -4;
  45. }
  46. memcpy(tmphost, tmp, i);
  47. tmpuri = tmp + i;
  48. break;
  49. }
  50. }
  51. if (strlen(tmphost) < 1) {
  52. LLOGI("host not found %s", url);
  53. return -5;
  54. }
  55. // 如果uri是\0, 那就指向 "/"
  56. if (strlen(tmpuri) == 0) {
  57. tmpuri = "/";
  58. }
  59. // 分解host:port
  60. for (size_t i = 1; i < strlen(tmphost); i++)
  61. {
  62. if (tmp[i] == ":") {
  63. tmp[i] = 0x00;
  64. ctx->port = atoi(&tmp[i+1]);
  65. break;
  66. }
  67. }
  68. // 对port进行修正
  69. if (ctx->port <= 0) {
  70. if (ctx->ssl)
  71. ctx->port = 443;
  72. else
  73. ctx->port = 80;
  74. }
  75. ctx->host = luat_heap_malloc(strlen(tmphost + 1));
  76. if (ctx->host == NULL) {
  77. LLOGE("out of memory when malloc host");
  78. goto exit;
  79. }
  80. memcpy(ctx->host, tmphost, strlen(tmphost + 1));
  81. ctx->uri = luat_heap_malloc(strlen(tmpuri + 1));
  82. if (ctx->uri == NULL) {
  83. LLOGE("out of memory when malloc url");
  84. goto exit;
  85. }
  86. memcpy(ctx->uri, tmpuri, strlen(tmpuri + 1));
  87. return 0;
  88. exit:
  89. return -0xAF;
  90. }
  91. int luat_http_set_ca(luat_http_ctx_t *ctx, char* server_ca, char* client_ca) {
  92. LLOGE("luat_http_set_ca NOT support yet");
  93. return -1;
  94. }
  95. typedef struct {
  96. char* old_str;
  97. char* str;
  98. }URL_PARAMETES;
  99. int luat_http_add_header(luat_http_ctx_t *ctx, char* name, char* value) {
  100. if (ctx->req_headers_size >= LUAT_HTTP_MAX_REQ_HEADER_COUNT) {
  101. LLOGE("too many custom header");
  102. return -1;
  103. }
  104. if (strlen(name) > 256 || strlen(value) > 256) {
  105. LLOGE("header key/value MUST less than 256 byte");
  106. return -2;
  107. }
  108. // URL encode
  109. char temp[256 * 3] = {0};
  110. URL_PARAMETES url_patametes[] = {
  111. {"+","%2B"},
  112. {" ","%20"},
  113. {"/","%2F"},
  114. {"?","%3F"},
  115. {"%","%25"},
  116. {"#","%23"},
  117. {"&","%26"},
  118. {"=","%3D"},
  119. };
  120. size_t slen = strlen(value);
  121. int i = 0, j = 0, k = 0;
  122. for (i = 0,j = 0; i < slen; i++) {
  123. for(k = 0; k < 8; k++){
  124. if(value[i] == url_patametes[k].old_str[0]) {
  125. memcpy(&temp[j],url_patametes[k].str,strlen(url_patametes[k].str));
  126. j+=3;
  127. break;
  128. }
  129. }
  130. if (k == 8) {
  131. temp[j++] = value[i];
  132. }
  133. }
  134. char *header = luat_heap_malloc(strlen(name) + strlen(temp) + 3);
  135. if (header == NULL) {
  136. LLOGW("out of memory when malloc header");
  137. return -3;
  138. }
  139. sprintf("%s: %s", header, name, temp);
  140. ctx->req_headers[ctx->req_headers_size] = header;
  141. ctx->req_headers_size ++;
  142. return 0;
  143. }
  144. // int luat_http_set_header(luat_http_ctx_t *ctx, char* name, char* value);
  145. int luat_http_set_body(luat_http_ctx_t *ctx, uint8_t body_type, char* body, int body_size) {
  146. if (ctx->req_body != NULL) {
  147. luat_heap_free(ctx->req_body);
  148. }
  149. ctx->req_body = luat_heap_malloc(body_size + 1);
  150. if (ctx->req_body == NULL) {
  151. LLOGW("out of memory when malloc header");
  152. return -1;
  153. }
  154. ctx->req_body_size = body_size;
  155. ctx->req_body_type = body_type;
  156. memcpy(ctx->req_body, body, body_size);
  157. ctx->req_body[ctx->req_body_size] = 0x00;
  158. return 0;
  159. }
  160. int luat_http_uninit(luat_http_ctx_t *ctx) {
  161. if (ctx == NULL)
  162. return 0;
  163. if (ctx->host) {
  164. luat_heap_free(ctx->host);
  165. ctx->host = NULL;
  166. }
  167. if (ctx->uri) {
  168. luat_heap_free(ctx->uri);
  169. ctx->uri = NULL;
  170. }
  171. if (ctx->server_ca) {
  172. luat_heap_free(ctx->server_ca);
  173. ctx->server_ca = NULL;
  174. }
  175. if (ctx->client_ca) {
  176. luat_heap_free(ctx->client_ca);
  177. ctx->client_ca = NULL;
  178. }
  179. if (ctx->req_body) {
  180. luat_heap_free(ctx->req_body);
  181. ctx->req_body = NULL;
  182. // ctx->req_body_size = 0;
  183. // ctx->req_body_type = 0;
  184. }
  185. if (ctx->req_headers_size) {
  186. for (size_t i = 0; i < ctx->req_headers_size; i++)
  187. {
  188. if (ctx->req_headers[i]) {
  189. luat_heap_free(ctx->req_headers[i]);
  190. ctx->req_headers[i] = NULL;
  191. }
  192. }
  193. ctx->req_headers_size = 0;
  194. }
  195. return 0;
  196. }
  197. int luat_http_send(luat_http_ctx_t *ctx, http_cb cb);