Mercurial > urweb
comparison src/c/cgi.c @ 856:86ec89baee01
cgi protocol
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Tue, 23 Jun 2009 17:59:23 -0400 |
parents | |
children | 305bc0a431de |
comparison
equal
deleted
inserted
replaced
855:28e42b22424d | 856:86ec89baee01 |
---|---|
1 #include <stdio.h> | |
2 #include <ctype.h> | |
3 #include <string.h> | |
4 #include <stdlib.h> | |
5 #include <unistd.h> | |
6 #include <stdarg.h> | |
7 | |
8 #include "request.h" | |
9 | |
10 static char *uppercased; | |
11 static size_t uppercased_len; | |
12 | |
13 static char *get_header(void *data, const char *h) { | |
14 size_t len = strlen(h); | |
15 char *s, *r; | |
16 const char *saved_h = h; | |
17 | |
18 if (len > uppercased_len) { | |
19 uppercased_len = len; | |
20 uppercased = realloc(uppercased, len + 6); | |
21 } | |
22 | |
23 strcpy(uppercased, "HTTP_"); | |
24 for (s = uppercased+5; *h; ++h) | |
25 *s++ = *h == '-' ? '_' : toupper(*h); | |
26 *s = 0; | |
27 | |
28 if (r = getenv(uppercased)) | |
29 return r; | |
30 else if (!strcasecmp(saved_h, "Content-length") | |
31 || !strcasecmp(saved_h, "Content-type")) | |
32 return getenv(uppercased + 5); | |
33 else | |
34 return NULL; | |
35 } | |
36 | |
37 static void on_success(uw_context ctx) { } | |
38 | |
39 static void on_failure(uw_context ctx) { | |
40 uw_write_header(ctx, "Status: 500 Internal Server Error\r\n"); | |
41 } | |
42 | |
43 static void log_error(void *data, const char *fmt, ...) { | |
44 va_list ap; | |
45 va_start(ap, fmt); | |
46 | |
47 vfprintf(stderr, fmt, ap); | |
48 } | |
49 | |
50 static void log_debug(void *data, const char *fmt, ...) { | |
51 } | |
52 | |
53 int main(int argc, char *argv[]) { | |
54 uw_context ctx = uw_request_new_context(NULL, log_error, log_debug); | |
55 uw_request_context rc = uw_new_request_context(); | |
56 request_result rr; | |
57 char *method = getenv("REQUEST_METHOD"), | |
58 *path = getenv("SCRIPT_NAME"), *path_info = getenv("PATH_INFO"), | |
59 *query_string = getenv("QUERY_STRING"); | |
60 char *body = malloc(1); | |
61 ssize_t body_len = 1, body_pos = 0, res; | |
62 | |
63 uppercased = malloc(6); | |
64 | |
65 if (!method) { | |
66 log_error(NULL, "REQUEST_METHOD not set\n"); | |
67 exit(1); | |
68 } | |
69 | |
70 if (!path) { | |
71 log_error(NULL, "SCRIPT_NAME not set\n"); | |
72 exit(1); | |
73 } | |
74 | |
75 if (path_info) { | |
76 char *new_path = malloc(strlen(path) + strlen(path_info) + 1); | |
77 sprintf(new_path, "%s%s", path, path_info); | |
78 path = new_path; | |
79 } | |
80 | |
81 if (!query_string) | |
82 query_string = ""; | |
83 | |
84 while ((res = read(0, body + body_pos, body_len - body_pos)) > 0) { | |
85 body_pos += res; | |
86 | |
87 if (body_pos == body_len) { | |
88 body_len *= 2; | |
89 body = realloc(body, body_len); | |
90 } | |
91 } | |
92 | |
93 if (res < 0) { | |
94 log_error(NULL, "Error reading stdin\n"); | |
95 exit(1); | |
96 } | |
97 | |
98 uw_set_on_success(""); | |
99 uw_set_headers(ctx, get_header, NULL); | |
100 uw_request_init(NULL, log_error, log_debug); | |
101 | |
102 body[body_pos] = 0; | |
103 rr = uw_request(rc, ctx, method, path, query_string, body, body_pos, | |
104 on_success, on_failure, | |
105 NULL, log_error, log_debug, | |
106 -1); | |
107 uw_print(ctx, 1); | |
108 | |
109 if (rr == SERVED) | |
110 return 0; | |
111 else | |
112 return 1; | |
113 } |