%s
\r\n\r\n", + code, code, info); + if (s == NULL) { + stream_terminate_connection(web->conn, "http_error: out of memory"); + return; + } + http_writeBlock(web, s, strlen(s)); + http_setResponseCode(web, code); + http_output_headers(web); + EVENT_FD_NOT_READABLE(web->conn->event.fde); + EVENT_FD_WRITEABLE(web->conn->event.fde); + web->output.output_pending = true; +} + +/* + map a unix error code to a http error +*/ +void http_error_unix(struct websrv_context *web, const char *info) +{ + int code = 500; + switch (errno) { + case ENOENT: + case EISDIR: + code = 404; + break; + case EACCES: + code = 403; + break; + } + info = talloc_asprintf(web, "%s
%s
\n", info, strerror(errno)); + http_error(web, code, info); +} + + +/* + a simple file request +*/ +static void http_simple_request(struct websrv_context *web) +{ + const char *url = web->input.url; + const char *path; + struct stat st; + + path = http_local_path(web, url, lp_swat_directory(web->task->lp_ctx)); + if (path == NULL) goto invalid; + + /* looks ok */ + web->output.fd = open(path, O_RDONLY); + if (web->output.fd == -1) { + DEBUG(0,("Failed to read file %s - %s\n", path, strerror(errno))); + http_error_unix(web, path); + return; + } + + if (fstat(web->output.fd, &st) != 0 || !S_ISREG(st.st_mode)) { + close(web->output.fd); + goto invalid; + } + + return; + +invalid: + http_error(web, 400, "Malformed URL"); +} + +/* + setup the standard ESP arrays +*/ +static void http_setup_arrays(struct esp_state *esp) +{ + struct websrv_context *web = esp->web; + struct esp_data *edata = talloc_get_type(web->task->private, struct esp_data); + struct EspRequest *req = esp->req; + struct socket_address *socket_address = socket_get_my_addr(web->conn->socket, esp); + struct socket_address *peer_address = socket_get_peer_addr(web->conn->socket, esp); + char *p; + +#define SETVAR(type, name, value) do { \ + const char *v = value; \ + if (v) espSetStringVar(req, type, name, v); \ +} while (0) + + SETVAR(ESP_REQUEST_OBJ, "CONTENT_LENGTH", + talloc_asprintf(esp, "%u", web->input.content_length)); + SETVAR(ESP_REQUEST_OBJ, "QUERY_STRING", web->input.query_string); + SETVAR(ESP_REQUEST_OBJ, "POST_DATA", + talloc_strndup(esp, + web->input.partial.data, + web->input.partial.length)); + SETVAR(ESP_REQUEST_OBJ, "REQUEST_METHOD", web->input.post_request?"POST":"GET"); + SETVAR(ESP_REQUEST_OBJ, "REQUEST_URI", web->input.url); + p = strrchr(web->input.url, '/'); + SETVAR(ESP_REQUEST_OBJ, "SCRIPT_NAME", p+1); + SETVAR(ESP_REQUEST_OBJ, "SCRIPT_FILENAME", web->input.url); + if (peer_address) { + struct MprVar mpv = mprObject("socket_address"); + mprSetPtrChild(&mpv, "socket_address", peer_address); + espSetVar(req, ESP_REQUEST_OBJ, "REMOTE_SOCKET_ADDRESS", mpv); + SETVAR(ESP_REQUEST_OBJ, "REMOTE_ADDR", peer_address->addr); + } + p = socket_get_peer_name(web->conn->socket, esp); + SETVAR(ESP_REQUEST_OBJ, "REMOTE_HOST", p); + SETVAR(ESP_REQUEST_OBJ, "REMOTE_USER", ""); + SETVAR(ESP_REQUEST_OBJ, "CONTENT_TYPE", web->input.content_type); + if (web->session) { + SETVAR(ESP_REQUEST_OBJ, "SESSION_ID", web->session->id); + } + SETVAR(ESP_REQUEST_OBJ, "COOKIE_SUPPORT", web->input.cookie?"true":"false"); + + SETVAR(ESP_HEADERS_OBJ, "HTTP_REFERER", web->input.referer); + SETVAR(ESP_HEADERS_OBJ, "HOST", web->input.host); + SETVAR(ESP_HEADERS_OBJ, "ACCEPT_ENCODING", web->input.accept_encoding); + SETVAR(ESP_HEADERS_OBJ, "ACCEPT_LANGUAGE", web->input.accept_language); + SETVAR(ESP_HEADERS_OBJ, "ACCEPT_CHARSET", web->input.accept_charset); + SETVAR(ESP_HEADERS_OBJ, "COOKIE", web->input.cookie); + SETVAR(ESP_HEADERS_OBJ, "USER_AGENT", web->input.user_agent); + + if (socket_address) { + SETVAR(ESP_SERVER_OBJ, "SERVER_ADDR", socket_address->addr); + SETVAR(ESP_SERVER_OBJ, "SERVER_NAME", socket_address->addr); + SETVAR(ESP_SERVER_OBJ, "SERVER_HOST", socket_address->addr); + SETVAR(ESP_SERVER_OBJ, "SERVER_PORT", + talloc_asprintf(esp, "%u", socket_address->port)); + } + + SETVAR(ESP_SERVER_OBJ, "DOCUMENT_ROOT", lp_swat_directory(esp->web->task->lp_ctx)); + SETVAR(ESP_SERVER_OBJ, "SERVER_PROTOCOL", tls_enabled(web->conn->socket)?"https":"http"); + SETVAR(ESP_SERVER_OBJ, "SERVER_SOFTWARE", "SAMBA"); + SETVAR(ESP_SERVER_OBJ, "GATEWAY_INTERFACE", "CGI/1.1"); + SETVAR(ESP_SERVER_OBJ, "TLS_SUPPORT", tls_support(edata->tls_params)?"true":"false"); +} + +#if HAVE_SETJMP_H +/* the esp scripting lirary generates exceptions when + it hits a major error. We need to catch these and + report a internal server error via http +*/ +static jmp_buf ejs_exception_buf; +static const char *exception_reason; + +static void web_server_ejs_exception(const char *reason) +{ + Ejs *ep = ejsPtr(0); + if (ep) { + ejsSetErrorMsg(0, "%s", reason); + exception_reason = ep->error; + } else { + exception_reason = reason; + } + DEBUG(0,("%s", exception_reason)); + longjmp(ejs_exception_buf, -1); +} +#else +static void web_server_ejs_exception(const char *reason) +{ + DEBUG(0,("%s", reason)); + smb_panic(reason); +} +#endif + +/* + process a esp request +*/ +static void esp_request(struct esp_state *esp, const char *url) +{ + struct websrv_context *web = esp->web; + int size; + int res; + char *emsg = NULL, *buf; + + if (http_readFile(web, &buf, &size, url, lp_swat_directory(esp->web->task->lp_ctx)) != 0) { + http_error_unix(web, url); + return; + } + +#if HAVE_SETJMP_H + if (setjmp(ejs_exception_buf) != 0) { + http_error(web, 500, exception_reason); + return; + } +#endif + + res = espProcessRequest(esp->req, url, buf, &emsg); + if (res != 0 && emsg) { + http_writeBlock(web, "
", 5); + http_writeBlock(web, emsg, strlen(emsg)); + http_writeBlock(web, "", 6); + } + talloc_free(buf); +} + +/* + perform pre-authentication on every page if /scripting/preauth.esp + exists. If this script generates any non-whitepace output at all, + then we don't run the requested URL. + + note that the preauth is run even for static pages such as images +*/ +static bool http_preauth(struct esp_state *esp) +{ + const char *path = http_local_path(esp->web, + HTTP_PREAUTH_URI, + lp_swat_directory(esp->web->task->lp_ctx)); + int i; + if (path == NULL) { + http_error(esp->web, 500, "Internal server error"); + return false; + } + if (!file_exist(path)) { + /* if the preath script is not installed then allow access */ + return true; + } + esp_request(esp, HTTP_PREAUTH_URI); + for (i=0;i
%s
\r\n\r\n", - code, code, info); - if (s == NULL) { - stream_terminate_connection(web->conn, "http_error: out of memory"); - return; - } - http_writeBlock(web, s, strlen(s)); - http_setResponseCode(web, code); - http_output_headers(web); - EVENT_FD_NOT_READABLE(web->conn->event.fde); - EVENT_FD_WRITEABLE(web->conn->event.fde); - web->output.output_pending = true; -} - -/* - map a unix error code to a http error -*/ -void http_error_unix(struct websrv_context *web, const char *info) -{ - int code = 500; - switch (errno) { - case ENOENT: - case EISDIR: - code = 404; - break; - case EACCES: - code = 403; - break; - } - info = talloc_asprintf(web, "%s
%s
\n", info, strerror(errno)); - http_error(web, code, info); -} - - -/* - a simple file request -*/ -static void http_simple_request(struct websrv_context *web) -{ - const char *url = web->input.url; - const char *path; - struct stat st; - - path = http_local_path(web, url, lp_swat_directory(web->task->lp_ctx)); - if (path == NULL) goto invalid; - - /* looks ok */ - web->output.fd = open(path, O_RDONLY); - if (web->output.fd == -1) { - DEBUG(0,("Failed to read file %s - %s\n", path, strerror(errno))); - http_error_unix(web, path); - return; - } - - if (fstat(web->output.fd, &st) != 0 || !S_ISREG(st.st_mode)) { - close(web->output.fd); - goto invalid; - } - - return; - -invalid: - http_error(web, 400, "Malformed URL"); -} - -/* - setup the standard ESP arrays -*/ -static void http_setup_arrays(struct esp_state *esp) -{ - struct websrv_context *web = esp->web; - struct esp_data *edata = talloc_get_type(web->task->private, struct esp_data); - struct EspRequest *req = esp->req; - struct socket_address *socket_address = socket_get_my_addr(web->conn->socket, esp); - struct socket_address *peer_address = socket_get_peer_addr(web->conn->socket, esp); - char *p; - -#define SETVAR(type, name, value) do { \ - const char *v = value; \ - if (v) espSetStringVar(req, type, name, v); \ -} while (0) - - SETVAR(ESP_REQUEST_OBJ, "CONTENT_LENGTH", - talloc_asprintf(esp, "%u", web->input.content_length)); - SETVAR(ESP_REQUEST_OBJ, "QUERY_STRING", web->input.query_string); - SETVAR(ESP_REQUEST_OBJ, "POST_DATA", - talloc_strndup(esp, - web->input.partial.data, - web->input.partial.length)); - SETVAR(ESP_REQUEST_OBJ, "REQUEST_METHOD", web->input.post_request?"POST":"GET"); - SETVAR(ESP_REQUEST_OBJ, "REQUEST_URI", web->input.url); - p = strrchr(web->input.url, '/'); - SETVAR(ESP_REQUEST_OBJ, "SCRIPT_NAME", p+1); - SETVAR(ESP_REQUEST_OBJ, "SCRIPT_FILENAME", web->input.url); - if (peer_address) { - struct MprVar mpv = mprObject("socket_address"); - mprSetPtrChild(&mpv, "socket_address", peer_address); - espSetVar(req, ESP_REQUEST_OBJ, "REMOTE_SOCKET_ADDRESS", mpv); - SETVAR(ESP_REQUEST_OBJ, "REMOTE_ADDR", peer_address->addr); - } - p = socket_get_peer_name(web->conn->socket, esp); - SETVAR(ESP_REQUEST_OBJ, "REMOTE_HOST", p); - SETVAR(ESP_REQUEST_OBJ, "REMOTE_USER", ""); - SETVAR(ESP_REQUEST_OBJ, "CONTENT_TYPE", web->input.content_type); - if (web->session) { - SETVAR(ESP_REQUEST_OBJ, "SESSION_ID", web->session->id); - } - SETVAR(ESP_REQUEST_OBJ, "COOKIE_SUPPORT", web->input.cookie?"true":"false"); - - SETVAR(ESP_HEADERS_OBJ, "HTTP_REFERER", web->input.referer); - SETVAR(ESP_HEADERS_OBJ, "HOST", web->input.host); - SETVAR(ESP_HEADERS_OBJ, "ACCEPT_ENCODING", web->input.accept_encoding); - SETVAR(ESP_HEADERS_OBJ, "ACCEPT_LANGUAGE", web->input.accept_language); - SETVAR(ESP_HEADERS_OBJ, "ACCEPT_CHARSET", web->input.accept_charset); - SETVAR(ESP_HEADERS_OBJ, "COOKIE", web->input.cookie); - SETVAR(ESP_HEADERS_OBJ, "USER_AGENT", web->input.user_agent); - - if (socket_address) { - SETVAR(ESP_SERVER_OBJ, "SERVER_ADDR", socket_address->addr); - SETVAR(ESP_SERVER_OBJ, "SERVER_NAME", socket_address->addr); - SETVAR(ESP_SERVER_OBJ, "SERVER_HOST", socket_address->addr); - SETVAR(ESP_SERVER_OBJ, "SERVER_PORT", - talloc_asprintf(esp, "%u", socket_address->port)); - } - - SETVAR(ESP_SERVER_OBJ, "DOCUMENT_ROOT", lp_swat_directory(esp->web->task->lp_ctx)); - SETVAR(ESP_SERVER_OBJ, "SERVER_PROTOCOL", tls_enabled(web->conn->socket)?"https":"http"); - SETVAR(ESP_SERVER_OBJ, "SERVER_SOFTWARE", "SAMBA"); - SETVAR(ESP_SERVER_OBJ, "GATEWAY_INTERFACE", "CGI/1.1"); - SETVAR(ESP_SERVER_OBJ, "TLS_SUPPORT", tls_support(edata->tls_params)?"true":"false"); -} - -#if HAVE_SETJMP_H -/* the esp scripting lirary generates exceptions when - it hits a major error. We need to catch these and - report a internal server error via http -*/ -static jmp_buf ejs_exception_buf; -static const char *exception_reason; - -static void web_server_ejs_exception(const char *reason) -{ - Ejs *ep = ejsPtr(0); - if (ep) { - ejsSetErrorMsg(0, "%s", reason); - exception_reason = ep->error; - } else { - exception_reason = reason; - } - DEBUG(0,("%s", exception_reason)); - longjmp(ejs_exception_buf, -1); -} -#else -static void web_server_ejs_exception(const char *reason) -{ - DEBUG(0,("%s", reason)); - smb_panic(reason); -} -#endif - -/* - process a esp request -*/ -static void esp_request(struct esp_state *esp, const char *url) -{ - struct websrv_context *web = esp->web; - int size; - int res; - char *emsg = NULL, *buf; - - if (http_readFile(web, &buf, &size, url, lp_swat_directory(esp->web->task->lp_ctx)) != 0) { - http_error_unix(web, url); - return; - } - -#if HAVE_SETJMP_H - if (setjmp(ejs_exception_buf) != 0) { - http_error(web, 500, exception_reason); - return; - } -#endif - - res = espProcessRequest(esp->req, url, buf, &emsg); - if (res != 0 && emsg) { - http_writeBlock(web, "
", 5); - http_writeBlock(web, emsg, strlen(emsg)); - http_writeBlock(web, "", 6); - } - talloc_free(buf); -} - -/* - perform pre-authentication on every page if /scripting/preauth.esp - exists. If this script generates any non-whitepace output at all, - then we don't run the requested URL. - - note that the preauth is run even for static pages such as images -*/ -static bool http_preauth(struct esp_state *esp) -{ - const char *path = http_local_path(esp->web, - HTTP_PREAUTH_URI, - lp_swat_directory(esp->web->task->lp_ctx)); - int i; - if (path == NULL) { - http_error(esp->web, 500, "Internal server error"); - return false; - } - if (!file_exist(path)) { - /* if the preath script is not installed then allow access */ - return true; - } - esp_request(esp, HTTP_PREAUTH_URI); - for (i=0;i
%s
\r\n\r\n", - code, code, info); - if (s == NULL) { - stream_terminate_connection(web->conn, "http_error: out of memory"); - return; - } - http_writeBlock(web, s, strlen(s)); - http_setResponseCode(web, code); - http_output_headers(web); - EVENT_FD_NOT_READABLE(web->conn->event.fde); - EVENT_FD_WRITEABLE(web->conn->event.fde); - web->output.output_pending = true; -} - -/* - map a unix error code to a http error -*/ -void http_error_unix(struct websrv_context *web, const char *info) -{ - int code = 500; - switch (errno) { - case ENOENT: - case EISDIR: - code = 404; - break; - case EACCES: - code = 403; - break; - } - info = talloc_asprintf(web, "%s
%s
\n", info, strerror(errno)); - http_error(web, code, info); -} - - -/* - a simple file request -*/ -static void http_simple_request(struct websrv_context *web) -{ - const char *url = web->input.url; - const char *path; - struct stat st; - - path = http_local_path(web, url, lp_swat_directory(web->task->lp_ctx)); - if (path == NULL) goto invalid; - - /* looks ok */ - web->output.fd = open(path, O_RDONLY); - if (web->output.fd == -1) { - DEBUG(0,("Failed to read file %s - %s\n", path, strerror(errno))); - http_error_unix(web, path); - return; - } - - if (fstat(web->output.fd, &st) != 0 || !S_ISREG(st.st_mode)) { - close(web->output.fd); - goto invalid; - } - - return; - -invalid: - http_error(web, 400, "Malformed URL"); -} - -/* - setup the standard ESP arrays -*/ -static void http_setup_arrays(struct web_server_data *wdata, struct esp_state *esp) -{ - struct websrv_context *web = esp->web; - struct EspRequest *req = esp->req; - struct socket_address *socket_address = socket_get_my_addr(web->conn->socket, esp); - struct socket_address *peer_address = socket_get_peer_addr(web->conn->socket, esp); - char *p; - -#define SETVAR(type, name, value) do { \ - const char *v = value; \ - if (v) espSetStringVar(req, type, name, v); \ -} while (0) - - SETVAR(ESP_REQUEST_OBJ, "CONTENT_LENGTH", - talloc_asprintf(esp, "%u", web->input.content_length)); - SETVAR(ESP_REQUEST_OBJ, "QUERY_STRING", web->input.query_string); - SETVAR(ESP_REQUEST_OBJ, "POST_DATA", - talloc_strndup(esp, - web->input.partial.data, - web->input.partial.length)); - SETVAR(ESP_REQUEST_OBJ, "REQUEST_METHOD", web->input.post_request?"POST":"GET"); - SETVAR(ESP_REQUEST_OBJ, "REQUEST_URI", web->input.url); - p = strrchr(web->input.url, '/'); - SETVAR(ESP_REQUEST_OBJ, "SCRIPT_NAME", p+1); - SETVAR(ESP_REQUEST_OBJ, "SCRIPT_FILENAME", web->input.url); - if (peer_address) { - struct MprVar mpv = mprObject("socket_address"); - mprSetPtrChild(&mpv, "socket_address", peer_address); - espSetVar(req, ESP_REQUEST_OBJ, "REMOTE_SOCKET_ADDRESS", mpv); - SETVAR(ESP_REQUEST_OBJ, "REMOTE_ADDR", peer_address->addr); - } - p = socket_get_peer_name(web->conn->socket, esp); - SETVAR(ESP_REQUEST_OBJ, "REMOTE_HOST", p); - SETVAR(ESP_REQUEST_OBJ, "REMOTE_USER", ""); - SETVAR(ESP_REQUEST_OBJ, "CONTENT_TYPE", web->input.content_type); - if (web->session) { - SETVAR(ESP_REQUEST_OBJ, "SESSION_ID", web->session->id); - } - SETVAR(ESP_REQUEST_OBJ, "COOKIE_SUPPORT", web->input.cookie?"true":"false"); - - SETVAR(ESP_HEADERS_OBJ, "HTTP_REFERER", web->input.referer); - SETVAR(ESP_HEADERS_OBJ, "HOST", web->input.host); - SETVAR(ESP_HEADERS_OBJ, "ACCEPT_ENCODING", web->input.accept_encoding); - SETVAR(ESP_HEADERS_OBJ, "ACCEPT_LANGUAGE", web->input.accept_language); - SETVAR(ESP_HEADERS_OBJ, "ACCEPT_CHARSET", web->input.accept_charset); - SETVAR(ESP_HEADERS_OBJ, "COOKIE", web->input.cookie); - SETVAR(ESP_HEADERS_OBJ, "USER_AGENT", web->input.user_agent); - - if (socket_address) { - SETVAR(ESP_SERVER_OBJ, "SERVER_ADDR", socket_address->addr); - SETVAR(ESP_SERVER_OBJ, "SERVER_NAME", socket_address->addr); - SETVAR(ESP_SERVER_OBJ, "SERVER_HOST", socket_address->addr); - SETVAR(ESP_SERVER_OBJ, "SERVER_PORT", - talloc_asprintf(esp, "%u", socket_address->port)); - } - - SETVAR(ESP_SERVER_OBJ, "DOCUMENT_ROOT", lp_swat_directory(esp->web->task->lp_ctx)); - SETVAR(ESP_SERVER_OBJ, "SERVER_PROTOCOL", tls_enabled(web->conn->socket)?"https":"http"); - SETVAR(ESP_SERVER_OBJ, "SERVER_SOFTWARE", "SAMBA"); - SETVAR(ESP_SERVER_OBJ, "GATEWAY_INTERFACE", "CGI/1.1"); - SETVAR(ESP_SERVER_OBJ, "TLS_SUPPORT", tls_support(wdata->tls_params)?"true":"false"); -} - -#if HAVE_SETJMP_H -/* the esp scripting lirary generates exceptions when - it hits a major error. We need to catch these and - report a internal server error via http -*/ -static jmp_buf ejs_exception_buf; -static const char *exception_reason; - -static void web_server_ejs_exception(const char *reason) -{ - Ejs *ep = ejsPtr(0); - if (ep) { - ejsSetErrorMsg(0, "%s", reason); - exception_reason = ep->error; - } else { - exception_reason = reason; - } - DEBUG(0,("%s", exception_reason)); - longjmp(ejs_exception_buf, -1); -} -#else -static void web_server_ejs_exception(const char *reason) -{ - DEBUG(0,("%s", reason)); - smb_panic(reason); -} -#endif - -/* - process a esp request -*/ -static void esp_request(struct esp_state *esp, const char *url) -{ - struct websrv_context *web = esp->web; - int size; - int res; - char *emsg = NULL, *buf; - - if (http_readFile(web, &buf, &size, url, lp_swat_directory(esp->web->task->lp_ctx)) != 0) { - http_error_unix(web, url); - return; - } - -#if HAVE_SETJMP_H - if (setjmp(ejs_exception_buf) != 0) { - http_error(web, 500, exception_reason); - return; - } -#endif - - res = espProcessRequest(esp->req, url, buf, &emsg); - if (res != 0 && emsg) { - http_writeBlock(web, "
", 5); - http_writeBlock(web, emsg, strlen(emsg)); - http_writeBlock(web, "", 6); - } - talloc_free(buf); -} - -/* - perform pre-authentication on every page if /scripting/preauth.esp - exists. If this script generates any non-whitepace output at all, - then we don't run the requested URL. - - note that the preauth is run even for static pages such as images -*/ -static bool http_preauth(struct esp_state *esp) -{ - const char *path = http_local_path(esp->web, - HTTP_PREAUTH_URI, - lp_swat_directory(esp->web->task->lp_ctx)); - int i; - if (path == NULL) { - http_error(esp->web, 500, "Internal server error"); - return false; - } - if (!file_exist(path)) { - /* if the preath script is not installed then allow access */ - return true; - } - esp_request(esp, HTTP_PREAUTH_URI); - for (i=0;i
%s
\r\n\r\n",
+ code, code, info);
+ if (s == NULL) {
+ stream_terminate_connection(web->conn, "http_error: out of memory");
+ return;
+ }
+ /* FIXME:
+ http_writeBlock(web, s, strlen(s));
+ http_setResponseCode(web, code);
+ http_output_headers(web); */
+ EVENT_FD_NOT_READABLE(web->conn->event.fde);
+ EVENT_FD_WRITEABLE(web->conn->event.fde);
+ web->output.output_pending = true;
+}
+
+
+/*
+ parse one line of header input
+*/
+NTSTATUS http_parse_header(struct websrv_context *web, const char *line)
+{
+ if (line[0] == 0) {
+ web->input.end_of_headers = true;
+ } else if (strncasecmp(line,"GET ", 4)==0) {
+ web->input.url = talloc_strndup(web, &line[4], strcspn(&line[4], " \t"));
+ } else if (strncasecmp(line,"POST ", 5)==0) {
+ web->input.post_request = true;
+ web->input.url = talloc_strndup(web, &line[5], strcspn(&line[5], " \t"));
+ } else if (strchr(line, ':') == NULL) {
+ http_error(web, 400, "This server only accepts GET and POST requests");
+ return NT_STATUS_INVALID_PARAMETER;
+ } else if (strncasecmp(line, "Content-Length: ", 16)==0) {
+ web->input.content_length = strtoul(&line[16], NULL, 10);
+ } else {
+ struct http_header *hdr = talloc_zero(web, struct http_header);
+ char *colon = strchr(line, ':');
+ if (colon == NULL) {
+ http_error(web, 500, "invalidly formatted header");
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ hdr->name = talloc_strndup(hdr, line, colon-line);
+ hdr->value = talloc_strdup(hdr, colon+1);
+ DLIST_ADD(web->input.headers, hdr);
+ }
+
+ /* ignore all other headers for now */
+ return NT_STATUS_OK;
+}
+
/*
called when a web connection becomes readable
*/
@@ -199,7 +257,7 @@ static void websrv_accept(struct stream_connection *conn)
web = talloc_zero(conn, struct websrv_context);
if (web == NULL) goto failed;
- web->http_process_input = esp_process_http_input;
+ web->http_process_input = wsgi_process_http_input;
web->task = task;
web->conn = conn;
conn->private = web;
@@ -290,9 +348,6 @@ static void websrv_task_init(struct task_server *task)
wdata->tls_params = tls_initialise(wdata, task->lp_ctx);
if (wdata->tls_params == NULL) goto failed;
- wdata->private = http_setup_esp(task, task->lp_ctx);
- if (wdata->private == NULL) goto failed;
-
return;
failed:
diff --git a/source4/web_server/web_server.h b/source4/web_server/web_server.h
index 0ce68bdd17..7375a2e9ca 100644
--- a/source4/web_server/web_server.h
+++ b/source4/web_server/web_server.h
@@ -24,6 +24,12 @@ struct web_server_data {
void *private;
};
+struct http_header {
+ char *name;
+ char *value;
+ struct http_header *prev, *next;
+};
+
/*
context of one open web connection
*/
@@ -40,16 +46,8 @@ struct websrv_context {
char *url;
unsigned content_length;
bool post_request;
+ struct http_header *headers;
const char *content_type;
- const char *query_string;
- const char *user_agent;
- const char *referer;
- const char *host;
- const char *accept_encoding;
- const char *accept_language;
- const char *accept_charset;
- const char *cookie;
- const char *session_key;
} input;
struct {
bool output_pending;
@@ -57,7 +55,7 @@ struct websrv_context {
int fd;
unsigned nsent;
int response_code;
- const char **headers;
+ struct http_header *headers;
} output;
struct session_data *session;
};
diff --git a/source4/web_server/wsgi.c b/source4/web_server/wsgi.c
index 32b1f0dbc2..3391065dae 100644
--- a/source4/web_server/wsgi.c
+++ b/source4/web_server/wsgi.c
@@ -32,7 +32,7 @@ static PyObject *start_response(PyObject *self, PyObject *args, PyObject *kwargs
"status", "response_header", "exc_info", NULL
};
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, (char *)"sOO:start_response", (char **)kwnames, &status, &response_header, &exc_info)) {
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sOO:start_response", discard_const_p(char *, kwnames), &status, &response_header, &exc_info)) {
return NULL;
}
@@ -57,7 +57,7 @@ static PyObject *py_error_write(PyObject *self, PyObject *args, PyObject *kwargs
const char *kwnames[] = { "str", NULL };
char *str = NULL;
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, (char *)"s:write", (char **)kwnames, &str)) {
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s:write", discard_const_p(char *, kwnames), &str)) {
return NULL;
}
@@ -71,7 +71,7 @@ static PyObject *py_error_writelines(PyObject *self, PyObject *args, PyObject *k
const char *kwnames[] = { "seq", NULL };
PyObject *seq = NULL, *item;
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, (char *)"O:writelines", (char **)kwnames, &seq)) {
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:writelines", discard_const_p(char *, kwnames), &seq)) {
return NULL;
}
@@ -141,14 +141,14 @@ PyTypeObject input_Stream_Type = {
static PyObject *Py_InputHttpStream(void *foo)
{
- PyObject *ret = PyObject_New(input_Stream_Object, &input_Stream_Type);
- return ret;
+ input_Stream_Object *ret = PyObject_New(input_Stream_Object, &input_Stream_Type);
+ return (PyObject *)ret;
}
static PyObject *Py_ErrorHttpStream(void)
{
- PyObject *ret = PyObject_New(error_Stream_Object, &error_Stream_Type);
- return ret;
+ error_Stream_Object *ret = PyObject_New(error_Stream_Object, &error_Stream_Type);
+ return (PyObject *)ret;
}
static PyObject *create_environ(void)
--
cgit
From 4141e70da97d924969b48fcd198e5996d615e75d Mon Sep 17 00:00:00 2001
From: Jelmer Vernooij \r\n\r\n",
- code, code, info);
+ s = talloc_asprintf(web," \r\n\r\n",
+ status, status, info);
if (s == NULL) {
stream_terminate_connection(web->conn, "http_error: out of memory");
return;
}
- /* FIXME:
- http_writeBlock(web, s, strlen(s));
- http_setResponseCode(web, code);
- http_output_headers(web); */
- EVENT_FD_NOT_READABLE(web->conn->event.fde);
- EVENT_FD_WRITEABLE(web->conn->event.fde);
- web->output.output_pending = true;
+ websrv_output_headers(web, status, NULL);
+ websrv_output(web, s, strlen(s));
}
void websrv_output_headers(struct websrv_context *web, const char *status, struct http_header *headers)
{
- /* FIXME */
+ char *s;
+ DATA_BLOB b;
+ struct http_header *hdr;
+
+ s = talloc_asprintf(web, "HTTP/1.0 %s\r\n", status);
+ if (s == NULL) return;
+ for (hdr = headers; hdr; hdr = hdr->next) {
+ s = talloc_asprintf_append_buffer(s, "%s: %s\r\n", hdr->name, hdr->value);
+ }
+
+ s = talloc_asprintf_append_buffer(s, "\r\n");
+
+ b = web->output.content;
+ web->output.content = data_blob_string_const(s);
+ websrv_output(web, b.data, b.length);
+ data_blob_free(&b);
+}
+
+void websrv_output(struct websrv_context *web, void *data, size_t length)
+{
+ data_blob_append(web, &web->output.content, data, length);
+ EVENT_FD_NOT_READABLE(web->conn->event.fde);
+ EVENT_FD_WRITEABLE(web->conn->event.fde);
+ web->output.output_pending = true;
}
@@ -100,7 +118,7 @@ NTSTATUS http_parse_header(struct websrv_context *web, const char *line)
web->input.post_request = true;
web->input.url = talloc_strndup(web, &line[5], strcspn(&line[5], " \t"));
} else if (strchr(line, ':') == NULL) {
- http_error(web, 400, "This server only accepts GET and POST requests");
+ http_error(web, "400 Bad request", "This server only accepts GET and POST requests");
return NT_STATUS_INVALID_PARAMETER;
} else if (strncasecmp(line, "Content-Length: ", 16)==0) {
web->input.content_length = strtoul(&line[16], NULL, 10);
@@ -108,7 +126,7 @@ NTSTATUS http_parse_header(struct websrv_context *web, const char *line)
struct http_header *hdr = talloc_zero(web, struct http_header);
char *colon = strchr(line, ':');
if (colon == NULL) {
- http_error(web, 500, "invalidly formatted header");
+ http_error(web, "500 Internal Server Error", "invalidly formatted header");
return NT_STATUS_INVALID_PARAMETER;
}
diff --git a/source4/web_server/wsgi.c b/source4/web_server/wsgi.c
index 0709e0ba39..3d5d0b4bf0 100644
--- a/source4/web_server/wsgi.c
+++ b/source4/web_server/wsgi.c
@@ -314,8 +314,7 @@ static void wsgi_process_http_input(struct web_server_data *wdata,
/* Now, iter over all the data returned */
while ((item = PyIter_Next(iter))) {
- data_blob_append(web, &web->output.content,
- PyString_AsString(item), PyString_Size(item));
+ websrv_output(web, PyString_AsString(item), PyString_Size(item));
Py_DECREF(item);
}
--
cgit
From ef8d9f8a756936578dc770a0ec275e57aa3ee51b Mon Sep 17 00:00:00 2001
From: Jelmer Vernooij Error %u
%s
Error %s
%s
\n'
+
+ for key, value in environ.items():
+ if isinstance(value, str):
+ yield '\t
\n'
--
cgit
From f3d513b378fcc094255264de0c73f96fac461b68 Mon Sep 17 00:00:00 2001
From: Jelmer Vernooij \n' % (key, value)
+
+ yield '%s %s