X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fuhttpd.git;a=blobdiff_plain;f=proc.c;h=9c4b685ad1bc75c11dc7eac93255cbb0f2168d4c;hp=d24649f78d1313321b73fbd45f3429854aa0d151;hb=d09bf11d572207b79286cdb5e6253278ebec147c;hpb=0590256080feb5e8f8742938efa539f2aec90601 diff --git a/proc.c b/proc.c index d24649f..9c4b685 100644 --- a/proc.c +++ b/proc.c @@ -1,20 +1,20 @@ /* * uhttpd - Tiny single-threaded httpd * - * Copyright (C) 2010-2012 Jo-Philipp Wich - * Copyright (C) 2012 Felix Fietkau + * Copyright (C) 2010-2013 Jo-Philipp Wich + * Copyright (C) 2013 Felix Fietkau * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include @@ -22,18 +22,18 @@ #include "uhttpd.h" #define __headers \ - __header(accept) \ - __header(accept_charset) \ - __header(accept_encoding) \ - __header(accept_language) \ - __header(authorization) \ - __header(connection) \ - __header(cookie) \ - __header(host) \ - __header(referer) \ - __header(user_agent) \ - __header(content_type) \ - __header(content_length) + __header(accept, accept) \ + __header(accept_charset, accept-charset) \ + __header(accept_encoding, accept-encoding) \ + __header(accept_language, accept-language) \ + __header(authorization, authorization) \ + __header(connection, connection) \ + __header(cookie, cookie) \ + __header(host, host) \ + __header(referer, referer) \ + __header(user_agent, user-agent) \ + __header(content_type, content-type) \ + __header(content_length, content-length) #undef __header #define __header __enum_header @@ -214,14 +214,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 +244,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 +266,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 +285,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 +305,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 +367,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;