http.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /*
  2. * Copyright (C) 2019-2020 Alibaba Group Holding Limited
  3. */
  4. #include <string.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include "../http/http.h"
  8. #include <yoc/fota.h>
  9. #include <yoc/netio.h>
  10. #include <aos/kernel.h>
  11. #include "util/network.h"
  12. #include "ulog/ulog.h"
  13. #define TAG "fota"
  14. static int http_read(netio_t *io, uint8_t *buffer, int length, int timeoutms)
  15. {
  16. int content_len;
  17. char *head_end;
  18. http_t *http = (http_t*)io->private;
  19. if (io->offset >= io->size) {
  20. LOGD(TAG, "http_read done: %d %d", io->size, io->offset);
  21. return 0;
  22. }
  23. memset(http->buffer, 0, BUFFER_SIZE);
  24. http->buffer_offset = 0;
  25. http_head_sets(http, "Host", http->host);
  26. int range_end = io->offset + io->block_size - 1;
  27. char *range;
  28. range = aos_zalloc(56);
  29. if (io->size > 0) {
  30. range_end = range_end < (io->size - 1)? range_end : (io->size - 1);
  31. }
  32. snprintf(range, 56, "bytes=%d-%d", io->offset, range_end);
  33. http_head_sets(http, "Range", range);
  34. aos_free(range);
  35. http_head_sets(http, "Connection", "keep-alive");
  36. http_head_sets(http, "Cache-Control", "no-cache");
  37. http_get(http, 10000);
  38. if ((content_len = http_wait_resp(http, &head_end, 10000)) < 0) {
  39. LOGE(TAG, "recv failed: %d", content_len);
  40. return content_len;
  41. }
  42. if (content_len != (range_end - io->offset + 1)) {
  43. LOGE(TAG, "content_len overflow :%d", content_len);
  44. return -1;
  45. }
  46. // LOGD(TAG, "recv sucess: %d", content_len);
  47. io->offset += content_len;
  48. memcpy(buffer, head_end, content_len);
  49. return content_len;
  50. }
  51. static int http_open(netio_t *io, const char *path)
  52. {
  53. http_t *http;
  54. if ((http = http_init(path)) == NULL) {
  55. LOGD(TAG, "e http init");
  56. return -1;
  57. }
  58. io->offset = 0;
  59. io->block_size = CONFIG_FOTA_BUFFER_SIZE;// 1024
  60. // io->private = http;
  61. int content_len;
  62. char *range;
  63. char *head_end;
  64. memset(http->buffer, 0, BUFFER_SIZE);
  65. http->buffer_offset = 0;
  66. http_head_sets(http, "Host", http->host);
  67. int range_end = io->offset + io->block_size - 1;
  68. range = (void *)aos_zalloc(56);
  69. if (io->size > 0) {
  70. range_end = range_end < (io->size - 1)? range_end : (io->size - 1);
  71. }
  72. snprintf(range, 56, "bytes=%d-%d", io->offset, range_end);
  73. http_head_sets(http, "Range", range);
  74. aos_free(range);
  75. http_head_sets(http, "Connection", "keep-alive");
  76. http_head_sets(http, "Cache-Control", "no-cache");
  77. http_get(http, 10000);
  78. if ((content_len = http_wait_resp(http, &head_end, 10000)) < 0) {
  79. LOGD(TAG, "recv failed: %d", content_len);
  80. return -1;
  81. }
  82. if ((range = strstr((char *)http->buffer, "Content-Range: bytes ")) == NULL) {
  83. LOGD(TAG, "no Content-Range");
  84. return -1;
  85. }
  86. io->size = atoi(strchr(range, '/') + 1);
  87. LOGD(TAG, "range_len: %d", io->size);
  88. io->private = http;
  89. return 0;
  90. }
  91. static int http_seek(netio_t *io, size_t offset, int whence)
  92. {
  93. // http_t *http = (http_t*)io->private;
  94. io->offset = offset;
  95. return 0;
  96. }
  97. static int http_close(netio_t *io)
  98. {
  99. http_t *http = (http_t*)io->private;
  100. return http_deinit(http);
  101. }
  102. const netio_cls_t http_cls = {
  103. .name = "http",
  104. .read = http_read,
  105. .seek = http_seek,
  106. .open = http_open,
  107. .close = http_close,
  108. // .private = http,
  109. // .getinfo = http_getinfo,
  110. };
  111. int netio_register_http(void)
  112. {
  113. return netio_register(&http_cls);
  114. }