#include "http.h" #include "config.h" /* g_cfg */ #include #include #include #include #include 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); 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)); }