From: Felix Fietkau Date: Wed, 2 Jan 2013 12:23:55 +0000 (+0100) Subject: add local/remote address env vars for cgi X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fuhttpd.git;a=commitdiff_plain;h=a6aca5fc1be4409c47f88f730814b41dc9c95475 add local/remote address env vars for cgi --- diff --git a/client.c b/client.c index a76d11e..1b9c524 100644 --- a/client.c +++ b/client.c @@ -300,6 +300,21 @@ static void client_notify_state(struct ustream *s) return client_close(cl); } +static void set_addr(struct uh_addr *addr, void *src) +{ + struct sockaddr_in *sin = src; + struct sockaddr_in6 *sin6 = src; + + addr->family = sin->sin_family; + if (addr->family == AF_INET) { + addr->port = ntohs(sin->sin_port); + memcpy(&addr->in, &sin->sin_addr, sizeof(addr->in)); + } else { + addr->port = ntohs(sin6->sin6_port); + memcpy(&addr->in6, &sin6->sin6_addr, sizeof(addr->in6)); + } +} + void uh_accept_client(int fd) { static struct client *next_client; @@ -307,19 +322,22 @@ void uh_accept_client(int fd) unsigned int sl; int sfd; static int client_id = 0; + struct sockaddr_in6 addr; if (!next_client) next_client = calloc(1, sizeof(*next_client)); cl = next_client; - sl = sizeof(cl->peeraddr); - sfd = accept(fd, (struct sockaddr *) &cl->peeraddr, &sl); + sl = sizeof(addr); + sfd = accept(fd, (struct sockaddr *) &addr, &sl); if (sfd < 0) return; - sl = sizeof(cl->servaddr); - getsockname(fd, (struct sockaddr *) &cl->servaddr, &sl); + set_addr(&cl->peer_addr, &addr); + sl = sizeof(addr); + getsockname(fd, (struct sockaddr *) &addr, &sl); + set_addr(&cl->srv_addr, &addr); cl->us = &cl->sfd.stream; cl->us->string_data = true; cl->us->notify_read = client_ustream_read_cb; diff --git a/proc.c b/proc.c index 4880727..a4c919a 100644 --- a/proc.c +++ b/proc.c @@ -17,6 +17,7 @@ * limitations under the License. */ +#include #include #include "uhttpd.h" @@ -81,10 +82,20 @@ enum extra_vars { VAR_PATH_INFO, VAR_USER, VAR_REDIRECT, + VAR_SERVER_NAME, + VAR_SERVER_ADDR, + VAR_SERVER_PORT, + VAR_REMOTE_NAME, + VAR_REMOTE_ADDR, + VAR_REMOTE_PORT, __VAR_MAX, }; +static char local_addr[INET6_ADDRSTRLEN], remote_addr[INET6_ADDRSTRLEN]; +static char local_port[6], remote_port[6]; +static char redirect_status[4]; + static struct env_var extra_vars[] = { [_VAR_GW] = { "GATEWAY_INTERFACE", "CGI/1.1" }, [_VAR_SOFTWARE] = { "SERVER_SOFTWARE", "uhttpd" }, @@ -97,7 +108,13 @@ static struct env_var extra_vars[] = { [VAR_METHOD] = { "REQUEST_METHOD" }, [VAR_PATH_INFO] = { "PATH_INFO" }, [VAR_USER] = { "REMOTE_USER" }, - [VAR_REDIRECT] = { "REDIRECT_STATUS" }, + [VAR_REDIRECT] = { "REDIRECT_STATUS", redirect_status }, + [VAR_SERVER_NAME] = { "SERVER_NAME", local_addr }, + [VAR_SERVER_ADDR] = { "SERVER_ADDR", local_addr }, + [VAR_SERVER_PORT] = { "SERVER_PORT", local_port }, + [VAR_REMOTE_NAME] = { "REMOTE_HOST", remote_addr }, + [VAR_REMOTE_ADDR] = { "REMOTE_ADDR", remote_addr }, + [VAR_REMOTE_PORT] = { "REMOTE_PORT", remote_port }, }; struct env_var *uh_get_process_vars(struct client *cl, struct path_info *pi) @@ -106,7 +123,6 @@ struct env_var *uh_get_process_vars(struct client *cl, struct path_info *pi) struct blob_attr *data = cl->hdr.head; struct env_var *vars = (void *) uh_buf; struct blob_attr *tb[__HDR_MAX]; - static char buf[4]; int len; int i; @@ -126,8 +142,10 @@ struct env_var *uh_get_process_vars(struct client *cl, struct path_info *pi) extra_vars[VAR_PATH_INFO].value = pi->info; extra_vars[VAR_USER].value = req->realm ? req->realm->user : NULL; - snprintf(buf, sizeof(buf), "%d", req->redirect_status); - extra_vars[VAR_REDIRECT].value = buf; + snprintf(redirect_status, sizeof(redirect_status), + "%d", req->redirect_status); + inet_ntop(cl->srv_addr.family, &cl->srv_addr.in, local_addr, sizeof(local_addr)); + inet_ntop(cl->peer_addr.family, &cl->peer_addr.in, remote_addr, sizeof(remote_addr)); blobmsg_parse(hdr_policy, __HDR_MAX, tb, blob_data(data), blob_len(data)); for (i = 0; i < ARRAY_SIZE(proc_header_env); i++) { diff --git a/uhttpd.h b/uhttpd.h index 24ad83d..3cbe46f 100644 --- a/uhttpd.h +++ b/uhttpd.h @@ -136,6 +136,15 @@ struct dispatch_handler { void (*handle_request)(struct client *cl, const char *url, struct path_info *pi); }; +struct uh_addr { + uint8_t family; + uint16_t port; + union { + struct in_addr in; + struct in6_addr in6; + }; +}; + struct client { struct list_head list; int id; @@ -150,8 +159,7 @@ struct client { enum client_state state; struct http_request request; - struct sockaddr_in6 servaddr; - struct sockaddr_in6 peeraddr; + struct uh_addr srv_addr, peer_addr; struct blob_buf hdr;