X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fuhttpd.git;a=blobdiff_plain;f=proc.c;h=88ec31ea8caedff8b1cff5a85cdad2bfbe56f6bb;hp=a1d48ad51ed61dd865db817eff384cccb007197c;hb=HEAD;hpb=1f4c517bb889413e55ccee466d9dfe79156092e8 diff --git a/proc.c b/proc.c index a1d48ad..88ec31e 100644 --- a/proc.c +++ b/proc.c @@ -30,10 +30,14 @@ __header(connection, connection) \ __header(cookie, cookie) \ __header(host, host) \ + __header(origin, origin) \ __header(referer, referer) \ __header(user_agent, user-agent) \ __header(content_type, content-type) \ - __header(content_length, content-length) + __header(content_length, content-length) \ + __header(x_http_method_override, x-http-method-override) \ + __header(http_auth_user, http-auth-user) \ + __header(http_auth_pass, http-auth-pass) #undef __header #define __header __enum_header @@ -60,8 +64,12 @@ static const struct { { "HTTP_CONNECTION", HDR_connection }, { "HTTP_COOKIE", HDR_cookie }, { "HTTP_HOST", HDR_host }, + { "HTTP_ORIGIN", HDR_origin }, { "HTTP_REFERER", HDR_referer }, { "HTTP_USER_AGENT", HDR_user_agent }, + { "HTTP_X_HTTP_METHOD_OVERRIDE", HDR_x_http_method_override }, + { "HTTP_AUTH_USER", HDR_http_auth_user }, + { "HTTP_AUTH_PASS", HDR_http_auth_pass }, { "CONTENT_TYPE", HDR_content_type }, { "CONTENT_LENGTH", HDR_content_length }, }; @@ -81,6 +89,7 @@ enum extra_vars { VAR_METHOD, VAR_PATH_INFO, VAR_USER, + VAR_HTTPS, VAR_REDIRECT, VAR_SERVER_NAME, VAR_SERVER_ADDR, @@ -108,6 +117,7 @@ static struct env_var extra_vars[] = { [VAR_METHOD] = { "REQUEST_METHOD" }, [VAR_PATH_INFO] = { "PATH_INFO" }, [VAR_USER] = { "REMOTE_USER" }, + [VAR_HTTPS] = { "HTTPS" }, [VAR_REDIRECT] = { "REDIRECT_STATUS", redirect_status }, [VAR_SERVER_NAME] = { "SERVER_NAME", local_addr }, [VAR_SERVER_ADDR] = { "SERVER_ADDR", local_addr }, @@ -143,6 +153,7 @@ struct env_var *uh_get_process_vars(struct client *cl, struct path_info *pi) extra_vars[VAR_METHOD].value = http_methods[req->method]; extra_vars[VAR_PATH_INFO].value = pi->info; extra_vars[VAR_USER].value = req->realm ? req->realm->user : NULL; + extra_vars[VAR_HTTPS].value = cl->tls ? "on" : NULL; snprintf(redirect_status, sizeof(redirect_status), "%d", req->redirect_status); @@ -157,7 +168,7 @@ struct env_var *uh_get_process_vars(struct client *cl, struct path_info *pi) cur = tb[proc_header_env[i].idx]; vars[i].name = proc_header_env[i].name; - vars[i].value = cur ? blobmsg_data(cur) : ""; + vars[i].value = cur ? blobmsg_data(cur) : NULL; } memcpy(&vars[i], extra_vars, sizeof(extra_vars)); @@ -214,14 +225,19 @@ static void proc_handle_header(struct relay *r, const char *name, const char *va static void proc_handle_header_end(struct relay *r) { struct client *cl = r->cl; + struct dispatch_proc *p = &cl->dispatch.proc; struct blob_attr *cur; int rem; + uloop_timeout_cancel(&p->timeout); uh_http_header(cl, cl->dispatch.proc.status_code, cl->dispatch.proc.status_msg); blob_for_each_attr(cur, cl->dispatch.proc.hdr.head, rem) ustream_printf(cl->us, "%s: %s\r\n", blobmsg_name(cur), blobmsg_data(cur)); ustream_printf(cl->us, "\r\n"); + + if (cl->request.method == UH_HTTP_MSG_HEAD) + r->skip_data = true; } static void proc_write_close(struct client *cl) @@ -239,6 +255,8 @@ static void proc_write_close(struct client *cl) static void proc_free(struct client *cl) { struct dispatch_proc *p = &cl->dispatch.proc; + + uloop_timeout_cancel(&p->timeout); blob_buf_free(&p->hdr); proc_write_close(cl); uh_relay_free(&p->r); @@ -259,6 +277,7 @@ static void proc_relay_write_cb(struct client *cl) return; ustream_set_read_blocked(&p->r.sfd.stream, false); + p->r.sfd.stream.notify_read(&p->r.sfd.stream, 0); } static int proc_data_send(struct client *cl, const char *data, int len) @@ -277,9 +296,8 @@ static int proc_data_send(struct client *cl, const char *data, int len) if (errno == EAGAIN || errno == EWOULDBLOCK) break; - /* error, no retry */ - len = 0; - break; + /* consume all data */ + ret = len; } if (!ret) @@ -298,6 +316,14 @@ static int proc_data_send(struct client *cl, const char *data, int len) return retlen; } +static void proc_timeout_cb(struct uloop_timeout *timeout) +{ + struct dispatch_proc *proc = container_of(timeout, struct dispatch_proc, timeout); + struct client *cl = container_of(proc, struct client, dispatch.proc); + + uh_relay_kill(cl, &proc->r); +} + bool uh_create_process(struct client *cl, struct path_info *pi, char *url, void (*cb)(struct client *cl, struct path_info *pi, char *url)) { @@ -352,6 +378,9 @@ bool uh_create_process(struct client *cl, struct path_info *pi, char *url, proc->r.header_end = proc_handle_header_end; proc->r.close = proc_handle_close; proc->wrfd.cb = proc_write_cb; + proc->timeout.cb = proc_timeout_cb; + if (conf.script_timeout > 0) + uloop_timeout_set(&proc->timeout, conf.script_timeout * 1000); return true;