diff options
Diffstat (limited to 'xs_httpd.h')
| -rw-r--r-- | xs_httpd.h | 54 |
1 files changed, 34 insertions, 20 deletions
| @@ -15,41 +15,48 @@ xs_dict *xs_httpd_request(FILE *f, xs_str **payload, int *p_size) | |||
| 15 | { | 15 | { |
| 16 | xs *q_vars = NULL; | 16 | xs *q_vars = NULL; |
| 17 | xs *p_vars = NULL; | 17 | xs *p_vars = NULL; |
| 18 | xs *l1, *l2; | 18 | xs *l1; |
| 19 | const char *v; | 19 | const char *v; |
| 20 | char *saveptr; | ||
| 20 | 21 | ||
| 21 | xs_socket_timeout(fileno(f), 2.0, 0.0); | 22 | xs_socket_timeout(fileno(f), 2.0, 0.0); |
| 22 | 23 | ||
| 23 | /* read the first line and split it */ | 24 | /* read the first line and split it */ |
| 24 | l1 = xs_strip_i(xs_readline(f)); | 25 | l1 = xs_strip_i(xs_readline(f)); |
| 25 | l2 = xs_split(l1, " "); | 26 | char *raw_path; |
| 27 | const char *mtd; | ||
| 28 | const char *proto; | ||
| 29 | |||
| 30 | if (!(mtd = strtok_r(l1, " ", &saveptr)) || | ||
| 31 | !(raw_path = strtok_r(NULL, " ", &saveptr)) || | ||
| 32 | !(proto = strtok_r(NULL, " ", &saveptr)) || | ||
| 33 | strtok_r(NULL, " ", &saveptr)) | ||
| 34 | return NULL; | ||
| 26 | 35 | ||
| 27 | if (xs_list_len(l2) != 3) { | 36 | if (!xs_is_string(mtd) || !xs_is_string(raw_path) || !xs_is_string(proto)) |
| 28 | /* error or timeout */ | ||
| 29 | return NULL; | 37 | return NULL; |
| 30 | } | ||
| 31 | 38 | ||
| 32 | xs_dict *req = xs_dict_new(); | 39 | xs_dict *req = xs_dict_new(); |
| 33 | 40 | ||
| 34 | req = xs_dict_append(req, "method", xs_list_get(l2, 0)); | 41 | req = xs_dict_append(req, "method", mtd); |
| 35 | req = xs_dict_append(req, "raw_path", xs_list_get(l2, 1)); | 42 | req = xs_dict_append(req, "raw_path", raw_path); |
| 36 | req = xs_dict_append(req, "proto", xs_list_get(l2, 2)); | 43 | req = xs_dict_append(req, "proto", proto); |
| 37 | 44 | ||
| 38 | { | 45 | { |
| 39 | /* split the path with its optional variables */ | 46 | char *q = strchr(raw_path, '?'); |
| 40 | const xs_val *udp = xs_list_get(l2, 1); | ||
| 41 | xs *pnv = xs_split_n(udp, "?", 1); | ||
| 42 | |||
| 43 | /* store the path */ | ||
| 44 | req = xs_dict_append(req, "path", xs_list_get(pnv, 0)); | ||
| 45 | 47 | ||
| 46 | /* get the variables */ | 48 | /* get the variables */ |
| 47 | q_vars = xs_url_vars(xs_list_get(pnv, 1)); | 49 | if (q) { |
| 50 | *q++ = '\0'; | ||
| 51 | q_vars = xs_url_vars(q); | ||
| 52 | } | ||
| 53 | /* store the path */ | ||
| 54 | req = xs_dict_append(req, "path", raw_path); | ||
| 48 | } | 55 | } |
| 49 | 56 | ||
| 50 | /* read the headers */ | 57 | /* read the headers */ |
| 51 | for (;;) { | 58 | for (;;) { |
| 52 | xs *l, *p = NULL; | 59 | xs *l; |
| 53 | 60 | ||
| 54 | l = xs_strip_i(xs_readline(f)); | 61 | l = xs_strip_i(xs_readline(f)); |
| 55 | 62 | ||
| @@ -58,11 +65,18 @@ xs_dict *xs_httpd_request(FILE *f, xs_str **payload, int *p_size) | |||
| 58 | break; | 65 | break; |
| 59 | 66 | ||
| 60 | /* split header and content */ | 67 | /* split header and content */ |
| 61 | p = xs_split_n(l, ": ", 1); | 68 | char *cnt = strchr(l, ':'); |
| 69 | if (!cnt) | ||
| 70 | continue; | ||
| 71 | |||
| 72 | *cnt++ = '\0'; | ||
| 73 | cnt += strspn(cnt, " \r\n\t\v\f"); | ||
| 74 | xs_rstrip_chars_i(l, " \r\n\t\v\f"); | ||
| 75 | |||
| 76 | if (!xs_is_string(cnt)) | ||
| 77 | continue; | ||
| 62 | 78 | ||
| 63 | if (xs_list_len(p) == 2) | 79 | req = xs_dict_append(req, xs_tolower_i(l), cnt); |
| 64 | req = xs_dict_append(req, xs_tolower_i( | ||
| 65 | (xs_str *)xs_list_get(p, 0)), xs_list_get(p, 1)); | ||
| 66 | } | 80 | } |
| 67 | 81 | ||
| 68 | xs_socket_timeout(fileno(f), 5.0, 0.0); | 82 | xs_socket_timeout(fileno(f), 5.0, 0.0); |