X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Fhttp.c;h=05198d653b03e432458a1f4ff8e2b6c5e4580632;hb=b6c78d80b41b2944279f6c62f777a0d1e44164db;hp=474401db776a2eb74f2ff2819ae41e529282c9b4;hpb=49088b6680bed3c069be10ff0cb7cc16f3733729;p=pazpar2-moved-to-github.git diff --git a/src/http.c b/src/http.c index 474401d..05198d6 100644 --- a/src/http.c +++ b/src/http.c @@ -1,5 +1,5 @@ /* This file is part of Pazpar2. - Copyright (C) 2006-2008 Index Data + Copyright (C) 2006-2010 Index Data Pazpar2 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -62,24 +62,23 @@ typedef int socklen_t; #include #include -#include "util.h" -#include "eventl.h" #include "pazpar2.h" #include "http.h" -#include "http_command.h" #define MAX_HTTP_HEADER 4096 +#ifdef WIN32 +#define strncasecmp _strnicmp +#define strcasecmp _stricmp +#endif + static void proxy_io(IOCHAN i, int event); -static struct http_channel *http_create(const char *addr); +static struct http_channel *http_create(const char *addr, + struct conf_server *server); static void http_destroy(IOCHAN i); -// If this is set, we proxy normal HTTP requests -static struct sockaddr_in *proxy_addr = 0; -static char proxy_url[256] = ""; -static char myurl[256] = ""; -static struct http_buf *http_buf_freelist = 0; -static struct http_channel *http_channel_freelist = 0; +static struct http_buf *http_buf_freelist = 0; /* thread pr */ +static struct http_channel *http_channel_freelist = 0; /* thread pr */ struct http_channel_observer_s { void *data; @@ -90,8 +89,8 @@ struct http_channel_observer_s { }; -static const char *http_lookup_header(struct http_header *header, - const char *name) +const char *http_lookup_header(struct http_header *header, + const char *name) { for (; header; header = header->next) if (!strcasecmp(name, header->name)) @@ -99,7 +98,7 @@ static const char *http_lookup_header(struct http_header *header, return 0; } -static struct http_buf *http_buf_create() +static struct http_buf *http_buf_create(void) { struct http_buf *r; @@ -271,7 +270,7 @@ void http_addheader(struct http_response *r, const char *name, const char *value r->headers = h; } -char *http_argbyname(struct http_request *r, char *name) +const char *http_argbyname(struct http_request *r, const char *name) { struct http_argument *p; if (!name) @@ -282,7 +281,7 @@ char *http_argbyname(struct http_request *r, char *name) return 0; } -char *http_headerbyname(struct http_header *h, char *name) +const char *http_headerbyname(struct http_header *h, const char *name) { for (; h; h = h->next) if (!strcmp(h->name, name)) @@ -665,7 +664,8 @@ static struct http_buf *http_serialize_request(struct http_request *r) static int http_weshouldproxy(struct http_request *rq) { - if (proxy_addr && !strstr(rq->path, "search.pz2")) + struct http_channel *c = rq->channel; + if (c->server->proxy_addr && !strstr(rq->path, "search.pz2")) return 1; return 0; } @@ -733,9 +733,8 @@ static int http_proxy(struct http_request *rq) struct http_proxy *p = c->proxy; struct http_header *hp; struct http_buf *requestbuf; - char server_via[128] = ""; char server_port[16] = ""; - struct conf_server *ser = global_parameters.server; + struct conf_server *ser = c->server; if (!p) // This is a new connection. Create a proxy channel { @@ -755,8 +754,8 @@ static int http_proxy(struct http_request *rq) &one, sizeof(one)) < 0) abort(); enable_nonblock(sock); - if (connect(sock, (struct sockaddr *) proxy_addr, - sizeof(*proxy_addr)) < 0) + if (connect(sock, (struct sockaddr *) c->server->proxy_addr, + sizeof(*c->server->proxy_addr)) < 0) { if (!is_inprogress()) { @@ -785,6 +784,8 @@ static int http_proxy(struct http_request *rq) // Add new header about paraz2 version, host, remote client address, etc. { + char server_via[128]; + hp = rq->headers; hp = http_header_append(c, hp, "X-Pazpar2-Version", PACKAGE_VERSION); @@ -793,8 +794,10 @@ static int http_proxy(struct http_request *rq) sprintf(server_port, "%d", ser->port); hp = http_header_append(c, hp, "X-Pazpar2-Server-Port", server_port); - sprintf(server_via, "1.1 %s:%s (%s/%s)", - ser->host, server_port, PACKAGE_NAME, PACKAGE_VERSION); + yaz_snprintf(server_via, sizeof(server_via), + "1.1 %s:%s (%s/%s)", + ser->host ? ser->host : "@", + server_port, PACKAGE_NAME, PACKAGE_VERSION); hp = http_header_append(c, hp, "Via" , server_via); hp = http_header_append(c, hp, "X-Forwarded-For", c->addr); } @@ -1063,7 +1066,8 @@ static void http_destroy(IOCHAN i) iochan_destroy(i); } -static struct http_channel *http_create(const char *addr) +static struct http_channel *http_create(const char *addr, + struct conf_server *server) { struct http_channel *r = http_channel_freelist; @@ -1079,6 +1083,7 @@ static struct http_channel *http_create(const char *addr) r->nmem = nmem_create(); r->wrbuf = wrbuf_alloc(); } + r->server = server; r->proxy = 0; r->iochan = 0; r->iqueue = r->oqueue = 0; @@ -1106,6 +1111,7 @@ static void http_accept(IOCHAN i, int event) int s; IOCHAN c; struct http_channel *ch; + struct conf_server *server = iochan_getdata(i); len = sizeof addr; if ((s = accept(fd, (struct sockaddr *) &addr, &len)) < 0) @@ -1118,17 +1124,15 @@ static void http_accept(IOCHAN i, int event) yaz_log(YLOG_DEBUG, "New command connection"); c = iochan_create(s, http_io, EVENT_INPUT | EVENT_EXCEPT); - ch = http_create(inet_ntoa(addr.sin_addr)); + ch = http_create(inet_ntoa(addr.sin_addr), server); ch->iochan = c; iochan_setdata(c, ch); pazpar2_add_channel(c); } -static int listener_socket = 0; - /* Create a http-channel listener, syntax [host:]port */ -int http_init(const char *addr) +int http_init(const char *addr, struct conf_server *server) { IOCHAN c; int l; @@ -1145,17 +1149,19 @@ int http_init(const char *addr) pp = strchr(addr, ':'); if (pp) { - int len = pp - addr; - char hostname[128]; + WRBUF w = wrbuf_alloc(); struct hostent *he; - strncpy(hostname, addr, len); - hostname[len] = '\0'; - if (!(he = gethostbyname(hostname))){ - yaz_log(YLOG_FATAL, "Unable to resolve '%s'", hostname); + wrbuf_write(w, addr, pp - addr); + wrbuf_puts(w, ""); + + he = gethostbyname(wrbuf_cstr(w)); + wrbuf_destroy(w); + if (!he) + { + yaz_log(YLOG_FATAL, "Unable to resolve '%s'", addr); return 1; } - memcpy(&myaddr.sin_addr.s_addr, he->h_addr_list[0], he->h_length); port = atoi(pp + 1); } @@ -1187,52 +1193,59 @@ int http_init(const char *addr) return 1; } - listener_socket = l; + server->listener_socket = l; c = iochan_create(l, http_accept, EVENT_INPUT | EVENT_EXCEPT); + iochan_setdata(c, server); pazpar2_add_channel(c); return 0; } -void http_close_server(void) +void http_close_server(struct conf_server *server) { /* break the event_loop (select) by closing down the HTTP listener sock */ - if (listener_socket) + if (server->listener_socket) { #ifdef WIN32 - closesocket(listener_socket); + closesocket(server->listener_socket); #else - close(listener_socket); + close(server->listener_socket); #endif } } -void http_set_proxyaddr(char *host, char *base_url) +void http_set_proxyaddr(const char *host, struct conf_server *server) { - char *p; + const char *p; short port; struct hostent *he; + WRBUF w = wrbuf_alloc(); + + yaz_log(YLOG_LOG, "HTTP backend %s", host); - strcpy(myurl, base_url); - strcpy(proxy_url, host); p = strchr(host, ':'); - yaz_log(YLOG_DEBUG, "Proxying for %s", host); - yaz_log(YLOG_LOG, "HTTP backend %s", proxy_url); - if (p) { + if (p) + { port = atoi(p + 1); - *p = '\0'; + wrbuf_write(w, host, p - host); + wrbuf_puts(w, ""); } else + { port = 80; - if (!(he = gethostbyname(host))) + wrbuf_puts(w, host); + } + if (!(he = gethostbyname(wrbuf_cstr(w)))) { - fprintf(stderr, "Failed to lookup '%s'\n", host); + fprintf(stderr, "Failed to lookup '%s'\n", wrbuf_cstr(w)); exit(1); } - proxy_addr = xmalloc(sizeof(struct sockaddr_in)); - proxy_addr->sin_family = he->h_addrtype; - memcpy(&proxy_addr->sin_addr.s_addr, he->h_addr_list[0], he->h_length); - proxy_addr->sin_port = htons(port); + wrbuf_destroy(w); + + server->proxy_addr = xmalloc(sizeof(struct sockaddr_in)); + server->proxy_addr->sin_family = he->h_addrtype; + memcpy(&server->proxy_addr->sin_addr.s_addr, he->h_addr_list[0], he->h_length); + server->proxy_addr->sin_port = htons(port); } static void http_fire_observers(struct http_channel *c) @@ -1294,7 +1307,9 @@ void http_observer_set_data2(http_channel_observer_t obs, void *data2) /* * Local variables: * c-basic-offset: 4 + * c-file-style: "Stroustrup" * indent-tabs-mode: nil * End: * vim: shiftwidth=4 tabstop=8 expandtab */ +