X-Git-Url: http://lists.indexdata.com/cgi-bin?a=blobdiff_plain;f=src%2Fhttp_command.c;h=dd3d5f5859052921ce73a6af550095be9f8d8dcf;hb=19a0803f7298f5a0d583f5f70582ba29cb373265;hp=8887e91e3dc2323561dc582ed604590cfac559a7;hpb=61a9c0fc574244c16e5a6bd44e796549de0bd559;p=pazpar2-moved-to-github.git diff --git a/src/http_command.c b/src/http_command.c index 8887e91..dd3d5f5 100644 --- a/src/http_command.c +++ b/src/http_command.c @@ -1,5 +1,5 @@ /* This file is part of Pazpar2. - Copyright (C) 2006-2012 Index Data + Copyright (C) 2006-2013 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 @@ -93,6 +93,8 @@ struct http_sessions { static YAZ_MUTEX g_http_session_mutex = 0; static int g_http_sessions = 0; +static void show_records_ready(void *data); + int get_version(struct http_request *rq) { const char *version = http_argbyname(rq, "version"); int version_no = 0; @@ -174,9 +176,13 @@ struct http_session *http_session_create(struct conf_service *service, http_sessions->session_list = r; yaz_mutex_leave(http_sessions->mutex); - r->timeout_iochan = iochan_create(-1, session_timeout, 0, "http_session_timeout"); + r->timeout_iochan = iochan_create(-1, session_timeout, 0, + "http_session_timeout"); iochan_setdata(r->timeout_iochan, r); - yaz_log(http_sessions->log_level, "Session %u created. timeout chan=%p timeout=%d", sesid, r->timeout_iochan, service->session_timeout); + + session_log(r->psession, http_sessions->log_level, + "HTTP session create. timeout chan=%p ses=%d", + r->timeout_iochan, service->session_timeout); iochan_settimeout(r->timeout_iochan, service->session_timeout); iochan_add(service->server->iochan_man, r->timeout_iochan); @@ -190,7 +196,8 @@ void http_session_destroy(struct http_session *s) http_sessions_t http_sessions = s->http_sessions; - yaz_log(http_sessions->log_level, "Session %u destroy", s->session_id); + session_log(s->psession, http_sessions->log_level, + "HTTP session destroy"); yaz_mutex_enter(http_sessions->mutex); /* only if http_session has no active http sessions on it can be destroyed */ if (s->destroy_counter == s->activity_counter) @@ -207,15 +214,17 @@ void http_session_destroy(struct http_session *s) yaz_mutex_leave(http_sessions->mutex); if (must_destroy) { /* destroying for real */ - yaz_log(http_sessions->log_level, "Session %u destroyed", s->session_id); + session_log(s->psession, http_sessions->log_level, "About to destroyd"); iochan_destroy(s->timeout_iochan); session_destroy(s->psession); http_session_use(-1); nmem_destroy(s->nmem); } - else { - yaz_log(http_sessions->log_level, "Session %u destroying delayed. Active clients (%d-%d). Waiting for new timeout.", - s->session_id, s->activity_counter, s->destroy_counter); + else + { + session_log(s->psession, http_sessions->log_level, + "Destroy delayed. Active clients (%d-%d)", + s->activity_counter, s->destroy_counter); } } @@ -405,7 +414,8 @@ static void cmd_exit(struct http_channel *c) response_open(c, "exit"); response_close(c, "exit"); - http_close_server(c->server); + if (global_parameters.debug_mode) + http_close_server(c->server); } static void cmd_init(struct http_channel *c) @@ -451,11 +461,10 @@ static void cmd_init(struct http_channel *c) sesid = make_sessionid(); s = http_session_create(service, c->http_sessions, sesid); - yaz_log(c->http_sessions->log_level, "Session init %u ", sesid); if (!clear || *clear == '0') session_init_databases(s->psession); else - yaz_log(YLOG_LOG, "Session %u init: No databases preloaded", sesid); + session_log(s->psession, YLOG_LOG, "No databases preloaded"); if (process_settings(s->psession, c->request, c->response) < 0) return; @@ -543,9 +552,8 @@ static void termlist_response(struct http_channel *c, struct http_session *s, co response_open_no_status(c, "termlist"); /* new protocol add a status to response. Triggered by a status parameter */ - if (cmd_status != 0) { + if (cmd_status != 0) wrbuf_printf(c->wrbuf, "%s\n", cmd_status); - } wrbuf_printf(c->wrbuf, "%d\n", status); perform_termlist(c, s->psession, name, num, version); @@ -562,8 +570,10 @@ static void termlist_result_ready(void *data) struct http_session *s = locate_session(c); if (report && !strcmp("status", report)) status = "OK"; - if (s) { - yaz_log(c->http_sessions->log_level, "Session %u termlist watch released", s->session_id); + if (s) + { + session_log(s->psession, c->http_sessions->log_level, + "termlist watch released"); termlist_response(c, s, status); release_session(c,s); } @@ -580,11 +590,14 @@ static void cmd_termlist(struct http_channel *c) int report_error = 0; const char *status_message = 0; int active_clients; - if (report && !strcmp("error", report)) { + + if (report && !strcmp("error", report)) + { report_error = 1; status_message = "OK"; } - if (report && !strcmp("status", report)) { + if (report && !strcmp("status", report)) + { report_status = 1; status_message = "OK"; } @@ -598,22 +611,23 @@ static void cmd_termlist(struct http_channel *c) if (session_set_watch(s->psession, SESSION_WATCH_TERMLIST, termlist_result_ready, c, c) != 0) { - yaz_log(YLOG_WARN, "Session %u: Attempt to block multiple times on termlist block. Not supported!", s->session_id); + session_log(s->psession, YLOG_WARN, "Attempt to block " + "multiple times on termlist block. Not supported!"); if (report_error) { error(rs, PAZPAR2_ALREADY_BLOCKED, "termlist"); release_session(c, s); return; } - else if (report_status) { + else if (report_status) status_message = "WARNING (Already blocked on termlist)"; - } - else { - yaz_log(YLOG_WARN, "Session %u: Ignoring termlist block. Return current result", s->session_id); - } + else + session_log(s->psession, YLOG_WARN, + "Ignoring termlist block. Return current result"); } else { - yaz_log(c->http_sessions->log_level, "Session %u: Blocking on command termlist", s->session_id); + session_log(s->psession, c->http_sessions->log_level, + "Blocking on command termlist"); release_session(c, s); return; } @@ -634,6 +648,17 @@ static void session_status(struct http_channel *c, struct http_session *s) wrbuf_printf(c->wrbuf, "%zu\n", session_nmem); } +static void cmd_service(struct http_channel *c) +{ + struct http_session *s = locate_session(c); + if (!s) + return; + + response_open(c, "service"); + response_close(c, "service"); + release_session(c, s); +} + static void cmd_session_status(struct http_channel *c) { struct http_session *s = locate_session(c); @@ -706,7 +731,8 @@ static void bytarget_response(struct http_channel *c, struct http_session *s, co } if (count == 0) - yaz_log(YLOG_WARN, "Empty bytarget Response. No targets found!"); + session_log(s->psession, YLOG_WARN, + "Empty bytarget Response. No targets found!"); for (i = 0; i < count; i++) { wrbuf_puts(c->wrbuf, "\n"); @@ -726,6 +752,9 @@ static void bytarget_response(struct http_channel *c, struct http_session *s, co wrbuf_printf(c->wrbuf, "%d\n", ht[i].diagnostic); if (ht[i].diagnostic) { + wrbuf_puts(c->wrbuf, ""); + wrbuf_xmlputs(c->wrbuf, ht[i].message); + wrbuf_puts(c->wrbuf, "\n"); wrbuf_puts(c->wrbuf, ""); if (ht[i].addinfo) wrbuf_xmlputs(c->wrbuf, ht[i].addinfo); @@ -761,14 +790,16 @@ static void bytarget_result_ready(void *data) struct http_channel *c = (struct http_channel *) data; struct http_session *s = locate_session(c); const char *status_message = "OK"; - if (s) { - yaz_log(c->http_sessions->log_level, "Session %u: bytarget watch released", s->session_id); + if (s) + { + session_log(s->psession, c->http_sessions->log_level, + "bytarget watch released"); bytarget_response(c, s, status_message); release_session(c, s); } - else { - yaz_log(c->http_sessions->log_level, "No Session found for released bytarget watch"); - } + else + yaz_log(c->http_sessions->log_level, + "No Session found for released bytarget watch"); } @@ -784,39 +815,40 @@ static void cmd_bytarget(struct http_channel *c) const char *status_message = "OK"; int no_active; - if (report && !strcmp("error", report)) { + if (report && !strcmp("error", report)) report_error = 1; - } - if (report && !strcmp("status", report)) { + if (report && !strcmp("status", report)) report_status = 1; - } if (!s) return; no_active = session_active_clients(s->psession); - if (block && !strcmp("1",block) && no_active) + if (block && !strcmp("1", block) && no_active) { // if there is already a watch/block. we do not block this one if (session_set_watch(s->psession, SESSION_WATCH_BYTARGET, bytarget_result_ready, c, c) != 0) { - yaz_log(YLOG_WARN, "Session %u: Attempt to block multiple times on bytarget block. Not supported!", s->session_id); - if (report_error) { + session_log(s->psession, YLOG_WARN, "Attempt to block " + "multiple times on bytarget block. Not supported!"); + if (report_error) + { error(rs, PAZPAR2_ALREADY_BLOCKED, "bytarget"); release_session(c, s); return; } - else if (report_status) { + else if (report_status) status_message = "WARNING (Already blocked on bytarget)"; - } else { - yaz_log(YLOG_WARN, "Session %u: Ignoring bytarget block. Return current result.", s->session_id); + session_log(s->psession, YLOG_WARN, "Ignoring bytarget block." + " Return current result."); } } else { - yaz_log(c->http_sessions->log_level, "Session %u: Blocking on command bytarget", s->session_id); + session_log(s->psession, c->http_sessions->log_level, + "Blocking on command bytarget"); release_session(c, s); return; } @@ -988,7 +1020,7 @@ static void show_record(struct http_channel *c, struct http_session *s) if (checksumstr) { - long v = atol(checksumstr); + unsigned v = strtoul(checksumstr, 0, 10); for (i = 0; r; r = r->next) if (v == r->checksum) break; @@ -1056,8 +1088,10 @@ static void cmd_record_ready(void *data) { struct http_channel *c = (struct http_channel *) data; struct http_session *s = locate_session(c); - if (s) { - yaz_log(c->http_sessions->log_level, "Session %u: record watch released", s->session_id); + if (s) + { + session_log(s->psession, c->http_sessions->log_level, + "record watch released"); show_record(c, s); release_session(c,s); } @@ -1114,7 +1148,10 @@ static void show_records(struct http_channel *c, struct http_session *s, int act } - rl = show_range_start(s->psession, sp, startn, &numn, &total, &total_hits, &approx_hits); + rl = show_range_start(s->psession, sp, startn, &numn, &total, + &total_hits, &approx_hits, show_records_ready, c); + if (!rl) + return; response_open(c, "show"); wrbuf_printf(c->wrbuf, "\n%d\n", active); @@ -1165,8 +1202,10 @@ static void show_records_ready(void *data) { struct http_channel *c = (struct http_channel *) data; struct http_session *s = locate_session(c); - if (s) { - yaz_log(c->http_sessions->log_level, "Session %u: show watch released", s->session_id); + if (s) + { + session_log(s->psession, c->http_sessions->log_level, + "show watch released"); show_records(c, s, -1); } else { @@ -1183,6 +1222,8 @@ static void cmd_show(struct http_channel *c) const char *block = http_argbyname(rq, "block"); const char *sort = http_argbyname(rq, "sort"); const char *block_error = http_argbyname(rq, "report"); + const char *mergekey = http_argbyname(rq, "mergekey"); + const char *rank = http_argbyname(rq, "rank"); struct conf_service *service = 0; struct reclist_sortparms *sp; @@ -1205,7 +1246,7 @@ static void cmd_show(struct http_channel *c) release_session(c, s); return; } - session_sort(s->psession, sp); + session_sort(s->psession, sp, mergekey, rank); status = session_active_clients(s->psession); @@ -1217,23 +1258,27 @@ static void cmd_show(struct http_channel *c) if (session_set_watch(s->psession, SESSION_WATCH_SHOW_PREF, show_records_ready, c, c) == 0) { - yaz_log(c->http_sessions->log_level, - "Session %u: Blocking on command show (preferred targets)", s->session_id); + session_log(s->psession, c->http_sessions->log_level, + "Blocking on command show (preferred targets)"); release_session(c, s); return; } else { - yaz_log(YLOG_WARN, "Session %u: Attempt to block multiple times on show (preferred targets) block. Not supported!", - s->session_id); - if (report_error) { - error(rs, PAZPAR2_ALREADY_BLOCKED, "show (preferred targets)"); + session_log(s->psession, YLOG_WARN, "Attempt to block" + " multiple times on show (preferred targets) block." + " Not supported!"); + if (report_error) + { + error(rs, PAZPAR2_ALREADY_BLOCKED, + "show (preferred targets)"); release_session(c, s); return; } - else { - yaz_log(YLOG_WARN, "Session %u: Ignoring show(preferred) block. Returning current result.", s->session_id); - } + else + session_log(s->psession, YLOG_WARN, + "Ignoring show(preferred) block." + " Returning current result"); } } @@ -1243,19 +1288,22 @@ static void cmd_show(struct http_channel *c) if (session_set_watch(s->psession, SESSION_WATCH_SHOW, show_records_ready, c, c) != 0) { - yaz_log(YLOG_WARN, "Session %u: Attempt to block multiple times on show block. Not supported!", s->session_id); - if (report_error) { + session_log(s->psession, YLOG_WARN, "Attempt to block" + " multiple times on show block. Not supported!"); + if (report_error) + { error(rs, PAZPAR2_ALREADY_BLOCKED, "show"); release_session(c, s); return; } - else { - yaz_log(YLOG_WARN, "Session %u: Ignoring show block. Returning current result.", s->session_id); - } + else + session_log(s->psession, YLOG_WARN, "Ignoring show block." + " Returning current result"); } else { - yaz_log(c->http_sessions->log_level, "Session %u: Blocking on command show", s->session_id); + session_log(s->psession, c->http_sessions->log_level, + "Blocking on command show"); release_session(c, s); return; } @@ -1286,6 +1334,8 @@ static void cmd_search(struct http_channel *c) const char *startrecs = http_argbyname(rq, "startrecs"); const char *limit = http_argbyname(rq, "limit"); const char *sort = http_argbyname(rq, "sort"); + const char *mergekey = http_argbyname(rq, "mergekey"); + const char *rank = http_argbyname(rq, "rank"); enum pazpar2_error_code code; const char *addinfo = 0; struct reclist_sortparms *sp; @@ -1318,7 +1368,7 @@ static void cmd_search(struct http_channel *c) } code = session_search(s->psession, query, startrecs, maxrecs, filter, limit, - &addinfo, sp); + &addinfo, sp, mergekey, rank); if (code) { error(rs, code, addinfo); @@ -1351,17 +1401,17 @@ static void cmd_stat(struct http_channel *c) } response_open_no_status(c, "stat"); - wrbuf_printf(c->wrbuf, "%d\n", clients); - wrbuf_printf(c->wrbuf, "" ODR_INT_PRINTF "\n", stat.num_hits); - wrbuf_printf(c->wrbuf, "%d\n", stat.num_records); - wrbuf_printf(c->wrbuf, "%d\n", stat.num_clients); - wrbuf_printf(c->wrbuf, "%d\n", stat.num_no_connection); - wrbuf_printf(c->wrbuf, "%d\n", stat.num_connecting); - wrbuf_printf(c->wrbuf, "%d\n", stat.num_working); - wrbuf_printf(c->wrbuf, "%d\n", stat.num_idle); - wrbuf_printf(c->wrbuf, "%d\n", stat.num_failed); - wrbuf_printf(c->wrbuf, "%d\n", stat.num_error); - wrbuf_printf(c->wrbuf, "%.2f\n", progress); + wrbuf_printf(c->wrbuf, "\n %d\n", clients); + wrbuf_printf(c->wrbuf, " " ODR_INT_PRINTF "\n", stat.num_hits); + wrbuf_printf(c->wrbuf, " %d\n", stat.num_records); + wrbuf_printf(c->wrbuf, " %d\n", stat.num_clients); + wrbuf_printf(c->wrbuf, " %d\n", stat.num_no_connection); + wrbuf_printf(c->wrbuf, " %d\n", stat.num_connecting); + wrbuf_printf(c->wrbuf, " %d\n", stat.num_working); + wrbuf_printf(c->wrbuf, " %d\n", stat.num_idle); + wrbuf_printf(c->wrbuf, " %d\n", stat.num_failed); + wrbuf_printf(c->wrbuf, " %d\n", stat.num_error); + wrbuf_printf(c->wrbuf, " %.2f\n", progress); response_close(c, "stat"); release_session(c, s); } @@ -1369,26 +1419,39 @@ static void cmd_stat(struct http_channel *c) static void cmd_info(struct http_channel *c) { char yaz_version_str[20]; + char yaz_sha1_str[42]; response_open_no_status(c, "info"); - wrbuf_puts(c->wrbuf, " \n"); + wrbuf_puts(c->wrbuf, "\n \n"); wrbuf_puts(c->wrbuf, " wrbuf, " sha1=\"%s\"", PAZPAR2_VERSION_SHA1); #endif wrbuf_puts(c->wrbuf, ">"); wrbuf_xmlputs(c->wrbuf, VERSION); - wrbuf_puts(c->wrbuf, ""); + wrbuf_puts(c->wrbuf, "\n"); - yaz_version(yaz_version_str, 0); + yaz_version(yaz_version_str, yaz_sha1_str); wrbuf_puts(c->wrbuf, " wrbuf, YAZ_VERSION); + wrbuf_puts(c->wrbuf, "\" sha1=\""); + wrbuf_xmlputs(c->wrbuf, yaz_sha1_str); wrbuf_puts(c->wrbuf, "\">"); wrbuf_xmlputs(c->wrbuf, yaz_version_str); wrbuf_puts(c->wrbuf, "\n"); wrbuf_puts(c->wrbuf, " \n"); - +#if HAVE_UNISTD_H + { + char hostname_str[64]; + if (gethostname(hostname_str, sizeof(hostname_str)) == 0) + { + wrbuf_puts(c->wrbuf, " "); + wrbuf_xmlputs(c->wrbuf, hostname_str); + wrbuf_puts(c->wrbuf, "\n"); + } + } +#endif info_services(c->server, c->wrbuf); response_close(c, "info"); @@ -1408,6 +1471,7 @@ struct { { "exit", cmd_exit }, { "session-status", cmd_session_status }, { "server-status", cmd_server_status }, + { "service", cmd_service }, { "ping", cmd_ping }, { "record", cmd_record }, { "info", cmd_info },