💾 Archived View for gemini.rmf-dev.com › repo › Vaati › Upload › files › 5ad51480e59f495723caa407d5c… captured on 2023-11-04 at 12:27:39. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2023-09-08)
-=-=-=-=-=-=-
0 /* See LICENSE for license details. */
1 #include "parser.h"
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <strings.h>
6 size_t strlcpy(char*, const char*, size_t);
7
8 int
9 get_parameter(struct http_request* req, char* name, int len,
10 char** ptr, int* psizeof)
11 {
12 if (!strncmp(name, "Content-Type", len)) {
13 *ptr = req->contenttype;
14 *psizeof = sizeof(req->contenttype);
15 return 0;
16 }
17 if (!strncmp(name, "Content-Length", len)) {
18 *ptr = req->contentlength;
19 *psizeof = sizeof(req->contentlength);
20 return 0;
21 }
22 return -1;
23 }
24
25 int
26 http_parse(struct http_request* req)
27 {
28 const char *pos[3], *start;
29 char buf[64];
30 size_t len;
31 const char* end = req->packet + req->size;
32 const char* ptr = req->packet;
33 int in_value = 0;
34 char parameter[4096];
35 char* value = NULL;
36 int sizeof_value = 0;
37 int i = 0;
38
39 /* header */
40 while (++ptr && ptr < end - 1) {
41 if (*ptr == '\r' && *(ptr+1) == '\n') {
42 pos[i] = ptr;
43 if (i != 2) return -1;
44 break;
45 }
46 if (*ptr != ' ') continue;
47 if (i > 1) {
48 return -1;
49 }
50 pos[i] = ptr+1;
51 i++;
52 }
53 len = pos[0] - req->packet;
54 if (len >= sizeof(buf)) return -2;
55 strlcpy(buf, req->packet, len);
56 if (strncmp(buf, "POST", len)) return -2;
57
58 /* parameters */
59 ptr+=2;
60 start = ptr;
61 ptr--;
62 req->boundary_found = 0;
63 while (ptr++ && ptr < end - 1) {
64 if ((ptr-1)[0] == '\n' && req->boundary_found &&
65 !memcmp(ptr, req->boundary,
66 strnlen(req->boundary, sizeof(req->boundary)))) {
67 start = ptr;
68 break;
69 }
70 if (in_value && ptr + sizeof("boundary=") < end - 1 &&
71 !memcmp(ptr, "boundary=", sizeof("boundary=")-1)) {
72 const char* bstart = ptr + sizeof("boundary=") - 1;
73 ptr += sizeof("boundary=") - 2;
74 while (ptr++ && ptr < end - 1 &&
75 *ptr != '\n' && *ptr != '\r')
76 req->boundary[ptr - bstart] = *ptr;
77 req->boundary_found = 1;
78 }
79 if (*ptr == '\r' && *(ptr+1) == '\n') {
80 ptr+=2;
81 start = ptr;
82 in_value = 0;
83 }
84 if (!in_value && *ptr == ':') {
85 if ((size_t)(ptr - start) > sizeof(parameter))
86 return -1;
87 strlcpy(parameter, start, ptr - start + 1);
88 if (!get_parameter(req, parameter, sizeof(parameter),
89 &value, &sizeof_value)) {
90 while (++ptr && ptr < end - 1 && *ptr != ' ') ;
91 start = ptr+1;
92 in_value = 1;
93 continue;
94 }
95 while (++ptr && ptr < end - 1 && *ptr != '\n') ;
96 ++ptr;
97 start = ptr;
98 }
99 if (in_value) {
100 if (ptr - start > sizeof_value)
101 return -1;
102 value[ptr - start] = *ptr;
103 }
104 }
105 return 0;
106 }
107