From f13ac948b76f05aeb46350de335406f9626054ba Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Sat, 26 Mar 2011 21:18:49 +0100 Subject: [PATCH] Add facility to record HTTP requests to Pazpar2 The HTTP record facility is enabled by specifying option -R. --- doc/pazpar2.xml | 10 ++++++++++ src/http.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++- src/http.h | 3 ++- src/pazpar2.c | 9 +++++++-- src/pazpar2_config.c | 5 +++-- src/pazpar2_config.h | 3 ++- 6 files changed, 74 insertions(+), 7 deletions(-) diff --git a/doc/pazpar2.xml b/doc/pazpar2.xml index 9e7b662..32b499c 100644 --- a/doc/pazpar2.xml +++ b/doc/pazpar2.xml @@ -35,6 +35,7 @@ + @@ -119,6 +120,15 @@ + + + + + If this option is given, HTTP requests are logged to file named + recfile. + + + diff --git a/src/http.c b/src/http.c index d93c874..1ce0aa4 100644 --- a/src/http.c +++ b/src/http.c @@ -21,6 +21,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include #endif +#if HAVE_SYS_TIME_H +#include +#endif + #include #ifdef WIN32 #include @@ -106,6 +110,7 @@ struct http_server int ref_count; http_sessions_t http_sessions; struct sockaddr_in *proxy_addr; + FILE *record_file; }; struct http_channel_observer_s { @@ -914,7 +919,18 @@ static void http_io(IOCHAN i, int event) } if (res <= 0) { +#if HAVE_SYS_TIME_H + if (hc->http_server->record_file) + { + struct timeval tv; + gettimeofday(&tv, 0); + fprintf(hc->http_server->record_file, "%lld %lld %lld 0\n", + (long long) tv.tv_sec, (long long) tv.tv_usec, + (long long) iochan_getfd(i)); + } +#endif http_buf_destroy(hc->http_server, htbuf); + fflush(hc->http_server->record_file); http_channel_destroy(i); return; } @@ -931,6 +947,22 @@ static void http_io(IOCHAN i, int event) return; // we have a complete HTTP request nmem_reset(hc->nmem); +#if HAVE_SYS_TIME_H + if (hc->http_server->record_file) + { + struct timeval tv; + int sz = 0; + struct http_buf *hb; + for (hb = hc->iqueue; hb; hb = hb->next) + sz += hb->len; + gettimeofday(&tv, 0); + fprintf(hc->http_server->record_file, "%lld %lld %lld %d\n", + (long long) tv.tv_sec, (long long) tv.tv_usec, + (long long) iochan_getfd(i), sz); + for (hb = hc->iqueue; hb; hb = hb->next) + fwrite(hb->buf, 1, hb->len, hc->http_server->record_file); + } + #endif if (!(hc->request = http_parse_request(hc, &hc->iqueue, reqlen))) { yaz_log(YLOG_WARN, "Failed to parse request"); @@ -1223,7 +1255,8 @@ static void http_accept(IOCHAN i, int event) } /* Create a http-channel listener, syntax [host:]port */ -int http_init(const char *addr, struct conf_server *server) +int http_init(const char *addr, struct conf_server *server, + const char *record_fname) { IOCHAN c; int l; @@ -1232,9 +1265,21 @@ int http_init(const char *addr, struct conf_server *server) int one = 1; const char *pp; short port; + FILE *record_file = 0; yaz_log(YLOG_LOG, "HTTP listener %s", addr); + + if (record_fname) + { + record_file = fopen(record_fname, "wb"); + if (!record_file) + { + yaz_log(YLOG_FATAL|YLOG_ERRNO, "fopen %s", record_fname); + return 1; + } + } + memset(&myaddr, 0, sizeof myaddr); myaddr.sin_family = AF_INET; pp = strchr(addr, ':'); @@ -1286,6 +1331,7 @@ int http_init(const char *addr, struct conf_server *server) server->http_server = http_server_create(); + server->http_server->record_file = record_file; server->http_server->listener_socket = l; c = iochan_create(l, http_accept, EVENT_INPUT | EVENT_EXCEPT, "http_server"); @@ -1415,6 +1461,7 @@ http_server_t http_server_create(void) hs->http_buf_freelist_count = 0; /* Disable max check */ hs->http_buf_freelist_max = 0; + hs->record_file = 0; return hs; } @@ -1449,6 +1496,8 @@ void http_server_destroy(http_server_t hs) http_sessions_destroy(hs->http_sessions); xfree(hs->proxy_addr); yaz_mutex_destroy(&hs->mutex); + if (hs->record_file) + fclose(hs->record_file); xfree(hs); } } diff --git a/src/http.h b/src/http.h index 9a00fee..63d8d88 100644 --- a/src/http.h +++ b/src/http.h @@ -104,7 +104,8 @@ void http_mutex_init(struct conf_server *server); void http_server_destroy(http_server_t hs); void http_set_proxyaddr(const char *url, struct conf_server *ser); -int http_init(const char *addr, struct conf_server *ser); +int http_init(const char *addr, struct conf_server *ser, + const char *record_fname); void http_close_server(struct conf_server *ser); void http_addheader(struct http_response *r, const char *name, const char *value); diff --git a/src/pazpar2.c b/src/pazpar2.c index 6680662..7f69902 100644 --- a/src/pazpar2.c +++ b/src/pazpar2.c @@ -95,6 +95,7 @@ static int sc_main( const char *uid = 0; const char *listener_override = 0; const char *config_fname = 0; + const char *record_fname = 0; struct conf_config *config = 0; int test_mode = 0; @@ -108,7 +109,7 @@ static int sc_main( yaz_log_init_prefix("pazpar2"); yaz_log_xml_errors(0, YLOG_WARN); - while ((ret = options("dDf:h:l:p:tu:v:VX", argv, argc, &arg)) != -2) + while ((ret = options("dDf:h:l:p:R:tu:v:VX", argv, argc, &arg)) != -2) { switch (ret) { @@ -131,6 +132,9 @@ static int sc_main( case 'p': pidfile = arg; break; + case 'R': + record_fname = arg; + break; case 't': test_mode = 1; break; @@ -153,6 +157,7 @@ static int sc_main( " -h [host:]port Listener port\n" " -l file Log to file\n" " -p pidfile PID file\n" + " -R recfile HTTP recording file\n" " -t Test configuration\n" " -u uid Change user to uid\n" " -V Show version\n" @@ -197,7 +202,7 @@ static int sc_main( "mode"); return 1; } - ret = config_start_listeners(config, listener_override); + ret = config_start_listeners(config, listener_override, record_fname); if (ret) return ret; /* error starting http listener */ diff --git a/src/pazpar2_config.c b/src/pazpar2_config.c index 740ac9c..8b94b63 100644 --- a/src/pazpar2_config.c +++ b/src/pazpar2_config.c @@ -1122,7 +1122,8 @@ void config_process_events(struct conf_config *conf) } int config_start_listeners(struct conf_config *conf, - const char *listener_override) + const char *listener_override, + const char *record_fname) { struct conf_server *ser; @@ -1149,7 +1150,7 @@ int config_start_listeners(struct conf_config *conf, wrbuf_printf(w, "%d", ser->port); } } - r = http_init(wrbuf_cstr(w), ser); + r = http_init(wrbuf_cstr(w), ser, record_fname); wrbuf_destroy(w); if (r) return -1; diff --git a/src/pazpar2_config.h b/src/pazpar2_config.h index 0bb9cbe..60d7793 100644 --- a/src/pazpar2_config.h +++ b/src/pazpar2_config.h @@ -175,7 +175,8 @@ void service_incref(struct conf_service *service); void service_destroy(struct conf_service *service); int config_start_listeners(struct conf_config *conf, - const char *listener_override); + const char *listener_override, + const char *record_fname); void config_stop_listeners(struct conf_config *conf); -- 1.7.10.4