annotate src/c/cgi.c @ 1739:c414850f206f

Add support for -boot flag, which allows in-tree execution of Ur/Web The boot flag rewrites most hardcoded paths to point to the build directory, and also forces static compilation. This is convenient for developing Ur/Web, or if you cannot 'sudo make install' Ur/Web. The following changes were made: * Header files were moved to include/urweb instead of include; this lets FFI users point their C_INCLUDE_PATH at this directory at write <urweb/urweb.h>. For internal Ur/Web executables, we simply pass -I$PATH/include/urweb as normal. * Differentiate between LIB and SRCLIB; SRCLIB is Ur and JavaScript source files, while LIB is compiled products from libtool. For in-tree compilation these live in different places. * No longer reference Config for paths; instead use Settings; these settings can be changed dynamically by Compiler.enableBoot () (TODO: add a disableBoot function.) * config.h is now generated directly in include/urweb/config.h, for consistency's sake (especially since it gets installed along with the rest of the headers!) * All of the autotools build products got updated. * The linkStatic field in protocols now only contains the name of the build product, and not the absolute path. Future users have to be careful not to reference the Settings files to early, lest they get an old version (this was the source of two bugs during development of this patch.)
author Edward Z. Yang <ezyang@mit.edu>
date Wed, 02 May 2012 17:17:57 -0400
parents ea131de361d9
children 3d922a28370b
rev   line source
adamc@1268 1 #include "config.h"
adamc@1268 2
adamc@856 3 #include <stdio.h>
adamc@856 4 #include <ctype.h>
adamc@856 5 #include <string.h>
adamc@856 6 #include <stdlib.h>
adamc@856 7 #include <unistd.h>
adamc@856 8 #include <stdarg.h>
adamc@856 9
adamc@1094 10 #include "urweb.h"
adamc@856 11 #include "request.h"
adamc@856 12
adamc@1094 13 extern uw_app uw_application;
adamc@1094 14
adamc@856 15 static char *uppercased;
adamc@856 16 static size_t uppercased_len;
adamc@856 17
adamc@856 18 static char *get_header(void *data, const char *h) {
adamc@856 19 size_t len = strlen(h);
adamc@856 20 char *s, *r;
adamc@856 21 const char *saved_h = h;
adamc@856 22
adamc@856 23 if (len > uppercased_len) {
adamc@856 24 uppercased_len = len;
adamc@856 25 uppercased = realloc(uppercased, len + 6);
adamc@856 26 }
adamc@856 27
adamc@856 28 strcpy(uppercased, "HTTP_");
adamc@856 29 for (s = uppercased+5; *h; ++h)
adamc@1154 30 *s++ = *h == '-' ? '_' : toupper((int)*h);
adamc@856 31 *s = 0;
adamc@856 32
adamc@1134 33 if ((r = getenv(uppercased)))
adamc@856 34 return r;
adamc@856 35 else if (!strcasecmp(saved_h, "Content-length")
adamc@856 36 || !strcasecmp(saved_h, "Content-type"))
adamc@856 37 return getenv(uppercased + 5);
adamc@856 38 else
adamc@856 39 return NULL;
adamc@856 40 }
adamc@856 41
adamc@856 42 static void on_success(uw_context ctx) { }
adamc@856 43
adamc@856 44 static void on_failure(uw_context ctx) {
adamc@856 45 uw_write_header(ctx, "Status: 500 Internal Server Error\r\n");
adamc@856 46 }
adamc@856 47
adamc@856 48 static void log_error(void *data, const char *fmt, ...) {
adamc@856 49 va_list ap;
adamc@856 50 va_start(ap, fmt);
adamc@856 51
adamc@856 52 vfprintf(stderr, fmt, ap);
adamc@856 53 }
adamc@856 54
adamc@856 55 static void log_debug(void *data, const char *fmt, ...) {
adamc@856 56 }
adamc@856 57
adamc@856 58 int main(int argc, char *argv[]) {
adam@1446 59 uw_context ctx = uw_request_new_context(0, &uw_application, NULL, log_error, log_debug);
adamc@856 60 uw_request_context rc = uw_new_request_context();
adamc@856 61 request_result rr;
adamc@856 62 char *method = getenv("REQUEST_METHOD"),
adamc@856 63 *path = getenv("SCRIPT_NAME"), *path_info = getenv("PATH_INFO"),
adamc@856 64 *query_string = getenv("QUERY_STRING");
adamc@856 65 char *body = malloc(1);
adamc@856 66 ssize_t body_len = 1, body_pos = 0, res;
adamc@856 67
adamc@856 68 uppercased = malloc(6);
adamc@856 69
adamc@856 70 if (!method) {
adamc@856 71 log_error(NULL, "REQUEST_METHOD not set\n");
adamc@856 72 exit(1);
adamc@856 73 }
adamc@856 74
adamc@856 75 if (!path) {
adamc@856 76 log_error(NULL, "SCRIPT_NAME not set\n");
adamc@856 77 exit(1);
adamc@856 78 }
adamc@856 79
adamc@856 80 if (path_info) {
adamc@856 81 char *new_path = malloc(strlen(path) + strlen(path_info) + 1);
adamc@856 82 sprintf(new_path, "%s%s", path, path_info);
adamc@856 83 path = new_path;
adamc@856 84 }
adamc@856 85
adamc@856 86 if (!query_string)
adamc@856 87 query_string = "";
adamc@856 88
adamc@856 89 while ((res = read(0, body + body_pos, body_len - body_pos)) > 0) {
adamc@856 90 body_pos += res;
adamc@856 91
adamc@856 92 if (body_pos == body_len) {
adamc@856 93 body_len *= 2;
adamc@856 94 body = realloc(body, body_len);
adamc@856 95 }
adamc@856 96 }
adamc@856 97
adamc@856 98 if (res < 0) {
adamc@856 99 log_error(NULL, "Error reading stdin\n");
adamc@856 100 exit(1);
adamc@856 101 }
adamc@856 102
adamc@856 103 uw_set_on_success("");
adamc@856 104 uw_set_headers(ctx, get_header, NULL);
adamc@1094 105 uw_request_init(&uw_application, NULL, log_error, log_debug);
adamc@856 106
adamc@856 107 body[body_pos] = 0;
adamc@856 108 rr = uw_request(rc, ctx, method, path, query_string, body, body_pos,
adamc@856 109 on_success, on_failure,
adamc@856 110 NULL, log_error, log_debug,
adamc@863 111 -1, NULL, NULL);
adamc@856 112 uw_print(ctx, 1);
adamc@856 113
adamc@856 114 if (rr == SERVED)
adamc@856 115 return 0;
adamc@856 116 else
adamc@856 117 return 1;
adamc@856 118 }
adamc@1121 119
adamc@1121 120 void *uw_init_client_data() {
adamc@1121 121 return NULL;
adamc@1121 122 }
adamc@1121 123
adamc@1121 124 void uw_free_client_data(void *data) {
adamc@1121 125 }
adamc@1121 126
adamc@1121 127 void uw_copy_client_data(void *dst, void *src) {
adamc@1121 128 }
adamc@1121 129
adamc@1121 130 void uw_do_expunge(uw_context ctx, uw_Basis_client cli, void *data) {
adamc@1121 131 if (uw_get_app(ctx)->db_begin(ctx))
adamc@1121 132 uw_error(ctx, FATAL, "Error running SQL BEGIN");
adamc@1121 133 uw_get_app(ctx)->expunger(ctx, cli);
adam@1672 134 uw_commit(ctx);
adamc@1121 135 }
adamc@1121 136
adamc@1121 137 void uw_post_expunge(uw_context ctx, void *data) {
adamc@1121 138 }
adam@1320 139
adam@1320 140 int uw_supports_direct_status = 1;