Files
Juli bd05fca812 Add opentopia.com as a second camera provider
Listing pages (rated/newest) and per-camera pages are fetched over HTTPS
with the certificate bundle; the camera page's Live Feed mode yields the
camera's own MJPEG URL (Current Still as fallback), resolved just before
playing and cached in favourites. New Provider menu row: insecam /
opentopia / mixed. cam_info_t gains provider + title fields and the
settings blob a version byte; older favourites and settings still load.
2026-09-17 02:04:57 +02:00

54 lines
1.9 KiB
C

#include "webpage.h"
#include "esp_crt_bundle.h"
#include "esp_heap_caps.h"
#include "esp_http_client.h"
#include "esp_log.h"
#include <stdlib.h>
#include <string.h>
static const char *TAG = "webpage";
typedef struct { char *buf; size_t len, cap; bool overflow; } sink_t;
static esp_err_t on_event(esp_http_client_event_t *e)
{
sink_t *s = e->user_data;
if (e->event_id == HTTP_EVENT_ON_DATA && s) {
size_t room = s->cap - 1 - s->len;
size_t n = e->data_len < room ? e->data_len : room;
memcpy(s->buf + s->len, e->data, n);
s->len += n;
if (n < (size_t)e->data_len) s->overflow = true;
}
return ESP_OK;
}
esp_err_t webpage_get(const char *url, const char *user_agent, size_t cap, char **out, size_t *len)
{
sink_t sink = {.buf = heap_caps_malloc(cap, MALLOC_CAP_SPIRAM), .cap = cap};
if (!sink.buf) return ESP_ERR_NO_MEM;
esp_http_client_config_t cfg = {
.url = url, .user_agent = user_agent, .timeout_ms = 10000,
.event_handler = on_event, .user_data = &sink,
.crt_bundle_attach = esp_crt_bundle_attach,
.buffer_size = 4096, .buffer_size_tx = 1024,
.max_redirection_count = 3,
};
esp_http_client_handle_t client = esp_http_client_init(&cfg);
if (!client) { free(sink.buf); return ESP_FAIL; }
esp_err_t err = esp_http_client_perform(client);
int status = esp_http_client_get_status_code(client);
esp_http_client_cleanup(client);
if (err != ESP_OK || status != 200) {
ESP_LOGW(TAG, "%s -> %s / HTTP %d", url, esp_err_to_name(err), status);
free(sink.buf);
return err != ESP_OK ? err : ESP_FAIL;
}
if (sink.overflow) ESP_LOGW(TAG, "%s truncated at %u bytes", url, (unsigned)sink.len);
for (size_t i = 0; i < sink.len; i++) if (!sink.buf[i]) sink.buf[i] = ' ';
sink.buf[sink.len] = 0;
*out = sink.buf;
*len = sink.len;
return ESP_OK;
}