younow.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #include <curl/curl.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <util/dstr.h>
  5. #include "util/base.h"
  6. #include "younow.h"
  7. struct younow_mem_struct {
  8. char *memory;
  9. size_t size;
  10. };
  11. static char *current_ingest = NULL;
  12. static size_t younow_write_cb(void *contents, size_t size, size_t nmemb,
  13. void *userp)
  14. {
  15. size_t realsize = size * nmemb;
  16. struct younow_mem_struct *mem = (struct younow_mem_struct *)userp;
  17. mem->memory = realloc(mem->memory, mem->size + realsize + 1);
  18. if (mem->memory == NULL) {
  19. blog(LOG_WARNING, "yyounow_write_cb: realloc returned NULL");
  20. return 0;
  21. }
  22. memcpy(&(mem->memory[mem->size]), contents, realsize);
  23. mem->size += realsize;
  24. mem->memory[mem->size] = 0;
  25. return realsize;
  26. }
  27. const char *younow_get_ingest(const char *server, const char *key)
  28. {
  29. CURL *curl_handle;
  30. CURLcode res;
  31. struct younow_mem_struct chunk;
  32. struct dstr uri;
  33. long response_code;
  34. // find the delimiter in stream key
  35. const char *delim = strchr(key, '_');
  36. if (delim == NULL) {
  37. blog(LOG_WARNING,
  38. "younow_get_ingest: delimiter not found in stream key");
  39. return server;
  40. }
  41. curl_handle = curl_easy_init();
  42. chunk.memory = malloc(1); /* will be grown as needed by realloc */
  43. chunk.size = 0; /* no data at this point */
  44. dstr_init(&uri);
  45. dstr_copy(&uri, server);
  46. dstr_ncat(&uri, key, delim - key);
  47. curl_easy_setopt(curl_handle, CURLOPT_URL, uri.array);
  48. curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, true);
  49. curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 2L);
  50. curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, 3L);
  51. curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, younow_write_cb);
  52. curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
  53. #if LIBCURL_VERSION_NUM >= 0x072400
  54. // A lot of servers don't yet support ALPN
  55. curl_easy_setopt(curl_handle, CURLOPT_SSL_ENABLE_ALPN, 0);
  56. #endif
  57. res = curl_easy_perform(curl_handle);
  58. dstr_free(&uri);
  59. if (res != CURLE_OK) {
  60. blog(LOG_WARNING,
  61. "younow_get_ingest: curl_easy_perform() failed: %s",
  62. curl_easy_strerror(res));
  63. curl_easy_cleanup(curl_handle);
  64. free(chunk.memory);
  65. return server;
  66. }
  67. curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &response_code);
  68. if (response_code != 200) {
  69. blog(LOG_WARNING,
  70. "younow_get_ingest: curl_easy_perform() returned code: %ld",
  71. response_code);
  72. curl_easy_cleanup(curl_handle);
  73. free(chunk.memory);
  74. return server;
  75. }
  76. curl_easy_cleanup(curl_handle);
  77. if (chunk.size == 0) {
  78. blog(LOG_WARNING,
  79. "younow_get_ingest: curl_easy_perform() returned empty response");
  80. free(chunk.memory);
  81. return server;
  82. }
  83. if (current_ingest) {
  84. free(current_ingest);
  85. current_ingest = NULL;
  86. }
  87. current_ingest = strdup(chunk.memory);
  88. free(chunk.memory);
  89. blog(LOG_INFO, "younow_get_ingest: returning ingest: %s",
  90. current_ingest);
  91. return current_ingest;
  92. }