adamc@856: #include <stdio.h>
adamc@856: #include <ctype.h>
adamc@856: #include <string.h>
adamc@856: #include <stdlib.h>
adamc@856: #include <unistd.h>
adamc@856: #include <stdarg.h>
adamc@856: 
adamc@856: #include "request.h"
adamc@856: 
adamc@856: static char *uppercased;
adamc@856: static size_t uppercased_len;
adamc@856: 
adamc@856: static char *get_header(void *data, const char *h) {
adamc@856:   size_t len = strlen(h);
adamc@856:   char *s, *r;
adamc@856:   const char *saved_h = h;
adamc@856: 
adamc@856:   if (len > uppercased_len) {
adamc@856:     uppercased_len = len;
adamc@856:     uppercased = realloc(uppercased, len + 6);
adamc@856:   }
adamc@856: 
adamc@856:   strcpy(uppercased, "HTTP_");
adamc@856:   for (s = uppercased+5; *h; ++h)
adamc@856:     *s++ = *h == '-' ? '_' : toupper(*h);
adamc@856:   *s = 0;
adamc@856: 
adamc@856:   if (r = getenv(uppercased))
adamc@856:     return r;
adamc@856:   else if (!strcasecmp(saved_h, "Content-length")
adamc@856:            || !strcasecmp(saved_h, "Content-type"))
adamc@856:     return getenv(uppercased + 5);
adamc@856:   else
adamc@856:     return NULL;
adamc@856: }
adamc@856: 
adamc@856: static void on_success(uw_context ctx) { }
adamc@856: 
adamc@856: static void on_failure(uw_context ctx) {
adamc@856:   uw_write_header(ctx, "Status: 500 Internal Server Error\r\n");
adamc@856: }
adamc@856: 
adamc@856: static void log_error(void *data, const char *fmt, ...) {
adamc@856:   va_list ap;
adamc@856:   va_start(ap, fmt);
adamc@856: 
adamc@856:   vfprintf(stderr, fmt, ap);
adamc@856: }
adamc@856: 
adamc@856: static void log_debug(void *data, const char *fmt, ...) {
adamc@856: }
adamc@856: 
adamc@856: int main(int argc, char *argv[]) {
adamc@856:   uw_context ctx = uw_request_new_context(NULL, log_error, log_debug);
adamc@856:   uw_request_context rc = uw_new_request_context();
adamc@856:   request_result rr;
adamc@856:   char *method = getenv("REQUEST_METHOD"),
adamc@856:     *path = getenv("SCRIPT_NAME"), *path_info = getenv("PATH_INFO"),
adamc@856:     *query_string = getenv("QUERY_STRING");
adamc@856:   char *body = malloc(1);
adamc@856:   ssize_t body_len = 1, body_pos = 0, res;
adamc@856: 
adamc@856:   uppercased = malloc(6);
adamc@856: 
adamc@856:   if (!method) {
adamc@856:     log_error(NULL, "REQUEST_METHOD not set\n");
adamc@856:     exit(1);
adamc@856:   }
adamc@856: 
adamc@856:   if (!path) {
adamc@856:     log_error(NULL, "SCRIPT_NAME not set\n");
adamc@856:     exit(1);
adamc@856:   }
adamc@856: 
adamc@856:   if (path_info) {
adamc@856:     char *new_path = malloc(strlen(path) + strlen(path_info) + 1);
adamc@856:     sprintf(new_path, "%s%s", path, path_info);
adamc@856:     path = new_path;
adamc@856:   }
adamc@856: 
adamc@856:   if (!query_string)
adamc@856:     query_string = "";
adamc@856: 
adamc@856:   while ((res = read(0, body + body_pos, body_len - body_pos)) > 0) {
adamc@856:     body_pos += res;
adamc@856: 
adamc@856:     if (body_pos == body_len) {
adamc@856:       body_len *= 2;
adamc@856:       body = realloc(body, body_len);
adamc@856:     }
adamc@856:   }
adamc@856: 
adamc@856:   if (res < 0) {
adamc@856:     log_error(NULL, "Error reading stdin\n");
adamc@856:     exit(1);
adamc@856:   }
adamc@856: 
adamc@856:   uw_set_on_success("");
adamc@856:   uw_set_headers(ctx, get_header, NULL);
adamc@856:   uw_request_init(NULL, log_error, log_debug);
adamc@856: 
adamc@856:   body[body_pos] = 0;
adamc@856:   rr = uw_request(rc, ctx, method, path, query_string, body, body_pos,
adamc@856:                   on_success, on_failure,
adamc@856:                   NULL, log_error, log_debug,
adamc@863:                   -1, NULL, NULL);
adamc@856:   uw_print(ctx, 1);
adamc@856: 
adamc@856:   if (rr == SERVED)
adamc@856:     return 0;
adamc@856:   else
adamc@856:     return 1;
adamc@856: }