commit 85547c2

uint  ·  2026-01-28 19:22:31 +0000 UTC
parent 23d70fc
unify replies futher to reply()
1 files changed,  +58, -105
+58, -105
  1@@ -25,7 +25,7 @@ static const char* mime_from_path(const char* path);
  2 static int parse_hex64(const char* s, uint64_t* out);
  3 static int parse_range(const char* hdr, size_t total, size_t* start, size_t* end);
  4 static int read_request(int c, char* method, size_t msz, char* path, size_t psz, char* hdr, size_t hsz);
  5-static void reply_hdr(int c, const char* hdr, const char* status, const char* ctype, size_t len, int preflight);
  6+static void reply(int c, const char* hdr, const char* status, const char* ctype, const char* extra, const void* body, size_t len, int send_body, int preflight);
  7 static void reply_json(int c, const char* hdr, const char* status, const char* body, size_t len, int send_body);
  8 static void reply_m3u(int c, const char* hdr, const char* status, size_t len);
  9 static void reply_preflight(int c, const char* hdr);
 10@@ -326,47 +326,30 @@ static int read_request(int c, char* method, size_t msz, char* path, size_t psz,
 11 	return 0;
 12 }
 13 
 14-static void reply_hdr(int c, const char* hdr, const char* status, const char* ctype, size_t len, int preflight)
 15+static void reply(int c, const char* hdr, const char* status, const char* ctype, const char* extra, const void* body, size_t len, int send_body, int preflight)
 16 {
 17 	char resp[HTTP_RESP_MAX];
 18 	char cors[512];
 19 
 20 	(void)cors_build(cors, sizeof(cors), hdr, preflight);
 21 
 22-	int n;
 23-
 24-	if (ctype && ctype[0]) {
 25-		n = snprintf(
 26-			resp, sizeof(resp),
 27-
 28-			"%s"
 29-			"%s"
 30-			"%s"
 31-			HTTP_LENGTH
 32-			HTTP_CLOSE
 33-			"\r\n",
 34-
 35-			status,
 36-			cors,
 37-			ctype,
 38-			len
 39-		);
 40-	}
 41-	else {
 42-		n = snprintf(
 43-			resp, sizeof(resp),
 44+	int n = snprintf(
 45+		resp, sizeof(resp),
 46 
 47-			"%s"
 48-			"%s"
 49-			HTTP_LENGTH
 50-			HTTP_CLOSE
 51-			"\r\n",
 52+		"%s"
 53+		"%s"
 54+		"%s"
 55+		"%s"
 56+		HTTP_LENGTH
 57+		HTTP_CLOSE
 58+		"\r\n",
 59 
 60-			status,
 61-			cors,
 62-			len
 63-		);
 64-	}
 65+		status,
 66+		cors,
 67+		(ctype && ctype[0]) ? ctype : "",
 68+		(extra && extra[0]) ? extra : "",
 69+		len
 70+	);
 71 
 72 	if (n < 0)
 73 		return;
 74@@ -375,33 +358,30 @@ static void reply_hdr(int c, const char* hdr, const char* status, const char* ct
 75 		n = (int)(sizeof(resp) - 1);
 76 
 77 	(void)write_all(c, resp, (size_t)n);
 78+
 79+	if (send_body && body && len > 0)
 80+		(void)write_all(c, body, len);
 81 }
 82 
 83 static void reply_json(int c, const char* hdr, const char* status, const char* body, size_t len, int send_body)
 84 {
 85-	reply_hdr(c, hdr, status, HTTP_JSON, len, 0);
 86-
 87-	if (send_body)
 88-		(void)write_all(c, body, len);
 89+	reply(c, hdr, status, HTTP_JSON, NULL, body, len, send_body, 0);
 90 }
 91 
 92-
 93 static void reply_m3u(int c, const char* hdr, const char* status, size_t len)
 94 {
 95-	reply_hdr(c, hdr, status, HTTP_M3U, len, 0);
 96+	reply(c, hdr, status, HTTP_M3U, NULL, NULL, len, 0, 0);
 97 }
 98 
 99 static void reply_preflight(int c, const char* hdr)
100 {
101-	reply_hdr(c, hdr, HTTP_204, NULL, (size_t)0, 1);
102+	reply(c, hdr, HTTP_204, NULL, NULL, NULL, (size_t)0, 0, 1);
103 }
104 
105 static void reply_text(int c, const char* hdr, const char* status, const char* body)
106 {
107 	size_t len = strlen(body);
108-
109-	reply_hdr(c, hdr, status, HTTP_TEXT, len, 0);
110-	(void)write_all(c, body, len);
111+	reply(c, hdr, status, HTTP_TEXT, NULL, body, len, 1, 0);
112 }
113 
114 static void reply_unauth(int c, const char* hdr, int send_body)
115@@ -409,31 +389,16 @@ static void reply_unauth(int c, const char* hdr, int send_body)
116 	const char* body = "unauthorized\n";
117 	size_t blen = strlen(body);
118 
119-	char cors[512];
120-	(void)cors_build(cors, sizeof(cors), hdr, 0);
121-
122-	char resp[HTTP_RESP_MAX];
123-	int n = snprintf(
124-		resp, sizeof(resp),
125-		"HTTP/1.1 401 Unauthorized\r\n"
126-		"%s"
127-		"WWW-Authenticate: Basic realm=\"parados\"\r\n"
128-		HTTP_TEXT
129-		HTTP_LENGTH
130-		HTTP_CLOSE
131-		"\r\n",
132-		cors,
133-		blen
134+	reply(
135+		c, hdr,
136+		"HTTP/1.1 401 Unauthorized\r\n",
137+		HTTP_TEXT,
138+		"WWW-Authenticate: Basic realm=\"parados\"\r\n",
139+		body,
140+		blen,
141+		send_body,
142+		0
143 	);
144-
145-	if (n < 0)
146-		return;
147-	if ((size_t)n >= sizeof(resp))
148-		n = (int)(sizeof(resp) - 1);
149-
150-	(void)write_all(c, resp, (size_t)n);
151-	if (send_body)
152-		(void)write_all(c, body, blen);
153 }
154 
155 static int queue_write(int c, const char* hdr, int head_only, const struct user* u)
156@@ -557,9 +522,6 @@ static int stream_file(int c, const struct item* it, const char* hdr, int head_o
157 	size_t start = 0;
158 	size_t end = total ? (total - 1) : 0;
159 	const char* type = mime_from_path(it->path);
160-	char cors[512];
161-
162-	(void)cors_build(cors, sizeof(cors), hdr, 0);
163 
164 	int partial = parse_range(hdr, total, &start, &end);
165 	if (partial == RANGE_BAD) {
166@@ -585,50 +547,41 @@ static int stream_file(int c, const struct item* it, const char* hdr, int head_o
167 	size_t len = (total == 0) ? 0 : (end - start + 1);
168 
169 	/* build response header */
170-	char resp[HTTP_RESP_MAX];
171-	int n;
172+	char ctype[128];
173+	char extra[256];
174+
175+	if (snprintf(ctype, sizeof(ctype), HTTP_CTYPE, type) >= (int)sizeof(ctype)) {
176+		close(fd);
177+		reply_text(c, hdr, HTTP_500, "Server error\n");
178+		return -1;
179+	}
180 
181 	if (partial == RANGE_OK) {
182 		/* partial */
183-		n = snprintf(
184-			resp, sizeof(resp),
185-			"%s"
186-			HTTP_CTYPE
187-			"%s"
188+		if (snprintf(
189+			extra, sizeof(extra),
190 			HTTP_RANGE
191-			HTTP_CRG
192-			HTTP_LENGTH
193-			HTTP_CLOSE
194-			"\r\n",
195-			HTTP_206, type, cors, start, end, total, len
196-		);
197+			HTTP_CRG,
198+			start, end, total
199+		) >= (int)sizeof(extra)) {
200+			close(fd);
201+			reply_text(c, hdr, HTTP_500, "Server error\n");
202+			return -1;
203+		}
204+
205+		reply(c, hdr, HTTP_206, ctype, extra, NULL, len, 0, 0);
206 	}
207 	else {
208 		/* non-partial */
209-		n = snprintf(
210-			resp, sizeof(resp),
211-			"%s"
212-			HTTP_CTYPE
213-			"%s"
214-			HTTP_RANGE
215-			HTTP_LENGTH
216-			HTTP_CLOSE
217-			"\r\n",
218-			HTTP_200, type, cors, len
219-		);
220-	}
221+		if (snprintf(extra, sizeof(extra), HTTP_RANGE) >= (int)sizeof(extra)) {
222+			close(fd);
223+			reply_text(c, hdr, HTTP_500, "Server error\n");
224+			return -1;
225+		}
226 
227-	if (n < 0) {
228-		close(fd);
229-		return -1;
230+		reply(c, hdr, HTTP_200, ctype, extra, NULL, len, 0, 0);
231 	}
232 
233-	if ((size_t)n >= sizeof(resp))
234-		n = (int)(sizeof(resp) - 1);
235-
236-	/* send headers */
237-	(void)write_all(c, resp, (size_t)n);
238-
239 	/* HEAD: no body */
240 	if (head_only) {
241 		close(fd);