refactor: reorganize into subdirs (config/ util/ http/ notifs/ queue/ integrations/ static/)
This commit is contained in:
+144
@@ -0,0 +1,144 @@
|
||||
#include "http.h"
|
||||
#include "config.h" /* g_cfg */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
char *g_header = NULL; int g_header_len = 0;
|
||||
char *g_footer = NULL; int g_footer_len = 0;
|
||||
char *g_css = NULL; int g_css_len = 0;
|
||||
|
||||
StaticJS g_js[] = {
|
||||
{ "/iptv.js", "iptv.js", NULL, 0 },
|
||||
{ "/downloads.js", "downloads.js", NULL, 0 },
|
||||
{ "/series_show.js", "series_show.js", NULL, 0 },
|
||||
{ NULL, NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
static int load_file(const char *path, char **out, int *out_len) {
|
||||
FILE *f = fopen(path, "rb");
|
||||
if (!f) { fprintf(stderr, "iptv-dl: cannot open %s: %s\n", path, strerror(errno)); return 0; }
|
||||
fseek(f, 0, SEEK_END); long sz = ftell(f); fseek(f, 0, SEEK_SET);
|
||||
*out = malloc(sz + 1);
|
||||
if (!*out) { fclose(f); return 0; }
|
||||
*out_len = (int)fread(*out, 1, sz, f);
|
||||
(*out)[*out_len] = '\0';
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int http_load_templates(void) {
|
||||
char path[512];
|
||||
snprintf(path, sizeof(path), "%s/header.html", g_cfg.template_dir);
|
||||
if (!load_file(path, &g_header, &g_header_len)) return 0;
|
||||
snprintf(path, sizeof(path), "%s/footer.html", g_cfg.template_dir);
|
||||
if (!load_file(path, &g_footer, &g_footer_len)) return 0;
|
||||
snprintf(path, sizeof(path), "%s/iptv.css", g_cfg.template_dir);
|
||||
if (!load_file(path, &g_css, &g_css_len)) return 0;
|
||||
for (int i = 0; g_js[i].url_path; i++) {
|
||||
snprintf(path, sizeof(path), "%s/%s", g_cfg.template_dir, g_js[i].fs_name);
|
||||
/* non-fatal if JS file missing */
|
||||
load_file(path, &g_js[i].data, &g_js[i].len);
|
||||
}
|
||||
fprintf(stderr, "iptv-dl: templates loaded (header=%d footer=%d css=%d bytes)\n",
|
||||
g_header_len, g_footer_len, g_css_len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int parse_request(int fd, Req *req) {
|
||||
char buf[131072]; int total = 0, n;
|
||||
memset(req, 0, sizeof(*req));
|
||||
while ((n = read(fd, buf+total, sizeof(buf)-1-total)) > 0) {
|
||||
total += n; buf[total] = 0;
|
||||
if (strstr(buf, "\r\n\r\n")) break;
|
||||
}
|
||||
if (total <= 0) return -1;
|
||||
buf[total] = 0;
|
||||
char *sp1 = strchr(buf, ' '); if (!sp1) return -1;
|
||||
size_t mlen = sp1 - buf; if (mlen >= 8) mlen = 7;
|
||||
memcpy(req->method, buf, mlen); req->method[mlen] = 0;
|
||||
char *sp2 = strchr(sp1+1, ' '); if (!sp2) return -1;
|
||||
size_t plen = sp2 - sp1 - 1; if (plen >= 256) plen = 255;
|
||||
char full[256]; memcpy(full, sp1+1, plen); full[plen] = 0;
|
||||
char *qm = strchr(full, '?');
|
||||
if (qm) { *qm = 0; strncpy(req->query, qm+1, sizeof(req->query)-1); }
|
||||
strncpy(req->path, full, sizeof(req->path)-1);
|
||||
char *body_start = strstr(buf, "\r\n\r\n");
|
||||
if (body_start) {
|
||||
body_start += 4;
|
||||
int blen = total - (int)(body_start - buf);
|
||||
if (blen > 0 && blen < (int)sizeof(req->body)) { memcpy(req->body, body_start, blen); req->body_len = blen; }
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void send_page(int fd, const char *title, Buf *body, const char *script_src) {
|
||||
Buf page; buf_init(&page);
|
||||
buf_str(&page, "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\nConnection: close\r\n\r\n");
|
||||
const char *ph = strstr(g_header, "{{TITLE}}");
|
||||
if (ph) {
|
||||
buf_append(&page, g_header, ph - g_header);
|
||||
buf_str(&page, title);
|
||||
buf_str(&page, ph + 9);
|
||||
} else {
|
||||
buf_str(&page, g_header);
|
||||
}
|
||||
buf_append(&page, body->data, body->len);
|
||||
if (script_src && script_src[0])
|
||||
buf_fmt(&page, "<script src=\"%s\"></script>", script_src);
|
||||
buf_str(&page, g_footer);
|
||||
write(fd, page.data, page.len);
|
||||
buf_free(&page);
|
||||
}
|
||||
|
||||
void send_css(int fd) {
|
||||
char hdr[256];
|
||||
int hl = snprintf(hdr, sizeof(hdr),
|
||||
"HTTP/1.1 200 OK\r\nContent-Type: text/css\r\n"
|
||||
"Content-Length: %d\r\nConnection: close\r\n\r\n", g_css_len);
|
||||
write(fd, hdr, hl);
|
||||
write(fd, g_css, g_css_len);
|
||||
}
|
||||
|
||||
void send_static_js(int fd, const char *path) {
|
||||
for (int i = 0; g_js[i].url_path; i++) {
|
||||
if (strcmp(g_js[i].url_path, path) == 0) {
|
||||
if (!g_js[i].data) { send_404(fd); return; }
|
||||
char hdr[256];
|
||||
int hl = snprintf(hdr, sizeof(hdr),
|
||||
"HTTP/1.1 200 OK\r\nContent-Type: application/javascript\r\n"
|
||||
"Content-Length: %d\r\nConnection: close\r\n\r\n", g_js[i].len);
|
||||
write(fd, hdr, hl);
|
||||
write(fd, g_js[i].data, g_js[i].len);
|
||||
return;
|
||||
}
|
||||
}
|
||||
send_404(fd);
|
||||
}
|
||||
|
||||
void send_json(int fd, const char *json) {
|
||||
char hdr[256];
|
||||
snprintf(hdr, sizeof(hdr),
|
||||
"HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n"
|
||||
"Access-Control-Allow-Origin: *\r\n"
|
||||
"Content-Length: %zu\r\nConnection: close\r\n\r\n", strlen(json));
|
||||
write(fd, hdr, strlen(hdr));
|
||||
write(fd, json, strlen(json));
|
||||
}
|
||||
|
||||
void send_json_buf(int fd, Buf *b) {
|
||||
char hdr[256];
|
||||
snprintf(hdr, sizeof(hdr),
|
||||
"HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n"
|
||||
"Access-Control-Allow-Origin: *\r\n"
|
||||
"Content-Length: %zu\r\nConnection: close\r\n\r\n", b->len);
|
||||
write(fd, hdr, strlen(hdr));
|
||||
write(fd, b->data, b->len);
|
||||
}
|
||||
|
||||
void send_404(int fd) {
|
||||
const char *r = "HTTP/1.1 404 Not Found\r\nContent-Length: 9\r\nConnection: close\r\n\r\nNot Found";
|
||||
write(fd, r, strlen(r));
|
||||
}
|
||||
Reference in New Issue
Block a user