X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Fzoom-c.c;h=3e5d64742e6dd99728a3c759b40b6532a770ad52;hp=b1874eac46ead33cc14090fd2d153cca52463c98;hb=1426a3da9b0390bb0d928a6ee56ebf5fa0ceb0ef;hpb=c65e569219f8a60e2cba17ddc648a48a7b8b5096 diff --git a/src/zoom-c.c b/src/zoom-c.c index b1874ea..3e5d647 100644 --- a/src/zoom-c.c +++ b/src/zoom-c.c @@ -49,7 +49,7 @@ static void initlog(void) } } -void ZOOM_connection_remove_tasks(ZOOM_connection c); +static zoom_ret send_HTTP_redirect(ZOOM_connection c, const char *uri); void ZOOM_set_dset_error(ZOOM_connection c, int error, const char *dset, @@ -83,7 +83,6 @@ void ZOOM_set_dset_error(ZOOM_connection c, int error, c, c->host_port ? c->host_port : "<>", dset, error, addinfo ? addinfo : "", addinfo2 ? addinfo2 : ""); - ZOOM_connection_remove_tasks(c); } } @@ -265,6 +264,7 @@ ZOOM_API(ZOOM_connection) c->host_port = 0; c->proxy = 0; c->tproxy = 0; + c->proxy_mode = 0; c->charset = c->lang = 0; @@ -296,11 +296,10 @@ ZOOM_API(ZOOM_connection) c->sru_version = 0; c->no_redirects = 0; c->cookies = 0; + c->location = 0; c->saveAPDU_wrbuf = 0; -#if HAVE_LIBMEMCACHED_MEMCACHED_H - c->mc_st = 0; -#endif + ZOOM_memcached_init(c); return c; } @@ -363,7 +362,6 @@ ZOOM_API(void) const char *host, int portnum) { const char *val; - const char *http_lead; initlog(); @@ -373,19 +371,6 @@ ZOOM_API(void) ZOOM_set_error(c, ZOOM_ERROR_NONE, 0); ZOOM_connection_remove_tasks(c); - if (c->odr_print) - { - odr_setprint(c->odr_print, 0); /* prevent destroy from fclose'ing */ - odr_destroy(c->odr_print); - } - if (ZOOM_options_get_bool(c->options, "apdulog", 0)) - { - c->odr_print = odr_createmem(ODR_PRINT); - odr_setprint(c->odr_print, yaz_log_file()); - } - else - c->odr_print = 0; - if (c->cs) { yaz_log(c->log_details, "%p ZOOM_connection_connect reconnect ok", c); @@ -430,16 +415,18 @@ ZOOM_API(void) else c->lang = 0; - val = ZOOM_options_get(c->options, "sru"); - if (val && *val && !strstr(host, "://")) - http_lead = "http://"; - else - http_lead = ""; - c->sru_mode = get_sru_mode_from_string(val); - if (host) { char hostn[128]; + const char *http_lead; + + val = ZOOM_options_get(c->options, "sru"); + if (val && *val && !strstr(host, "://")) + http_lead = "http://"; + else + http_lead = ""; + c->sru_mode = get_sru_mode_from_string(val); + xfree(c->host_port); if (portnum) { @@ -545,29 +532,11 @@ ZOOM_API(void) yaz_cookies_destroy(c->cookies); c->cookies = yaz_cookies_create(); -#if HAVE_LIBMEMCACHED_MEMCACHED_H - if (c->mc_st) - { - memcached_free(c->mc_st); - c->mc_st = 0; - } -#endif - val = ZOOM_options_get(c->options, "memcached"); - if (val && *val) + if (ZOOM_memcached_configure(c)) { -#if HAVE_LIBMEMCACHED_MEMCACHED_H - c->mc_st = memcached(val, strlen(val)); - if (!c->mc_st) - { - ZOOM_set_error(c, ZOOM_ERROR_MEMCACHED, val); - return; - } -#else - ZOOM_set_error(c, ZOOM_ERROR_MEMCACHED, "not enabled"); + ZOOM_connection_remove_tasks(c); return; -#endif } - if (c->sru_mode == zoom_sru_error) { ZOOM_set_error(c, ZOOM_ERROR_UNSUPPORTED_PROTOCOL, val); @@ -575,6 +544,33 @@ ZOOM_API(void) return; } + if (c->odr_print) + odr_destroy(c->odr_print); + c->odr_print = 0; + val = ZOOM_options_get(c->options, "apdufile"); + if (val) + { + c->odr_print = odr_createmem(ODR_PRINT); + if (strcmp(val, "-")) + { + FILE *f = fopen(val, "a"); + if (!f) + { + WRBUF w = wrbuf_alloc(); + wrbuf_printf(w, "fopen: %s", val); + ZOOM_set_error(c, ZOOM_ERROR_INTERNAL, wrbuf_cstr(w)); + wrbuf_destroy(w); + return; + } + odr_setprint(c->odr_print, f); + } + } + else if (ZOOM_options_get_bool(c->options, "apdulog", 0)) + { + c->odr_print = odr_createmem(ODR_PRINT); + odr_setprint_noclose(c->odr_print, yaz_log_file()); + } + yaz_log(c->log_details, "%p ZOOM_connection_connect async=%d", c, c->async); ZOOM_connection_add_task(c, ZOOM_TASK_CONNECT); @@ -613,10 +609,7 @@ ZOOM_API(void) return; yaz_log(c->log_api, "%p ZOOM_connection_destroy", c); -#if HAVE_LIBMEMCACHED_MEMCACHED_H - if (c->mc_st) - memcached_free(c->mc_st); -#endif + ZOOM_memcached_destroy(c); if (c->cs) cs_close(c->cs); @@ -631,10 +624,7 @@ ZOOM_API(void) if (c->odr_save) odr_destroy(c->odr_save); if (c->odr_print) - { - odr_setprint(c->odr_print, 0); /* prevent destroy from fclose'ing */ odr_destroy(c->odr_print); - } ZOOM_options_destroy(c->options); ZOOM_connection_remove_tasks(c); ZOOM_connection_remove_events(c); @@ -650,6 +640,7 @@ ZOOM_API(void) xfree(c->group); xfree(c->password); xfree(c->sru_version); + xfree(c->location); yaz_cookies_destroy(c->cookies); wrbuf_destroy(c->saveAPDU_wrbuf); xfree(c); @@ -709,8 +700,9 @@ ZOOM_resultset ZOOM_resultset_create(void) r->connection = 0; r->databaseNames = 0; r->num_databaseNames = 0; - r->facets = 0; - r->num_facets = 0; + r->req_facets = 0; + r->res_facets = 0; + r->num_res_facets = 0; r->facets_names = 0; r->mutex = 0; yaz_mutex_create(&r->mutex); @@ -743,7 +735,6 @@ ZOOM_API(ZOOM_resultset) ZOOM_connection_search(ZOOM_connection c, ZOOM_query q) { ZOOM_resultset r = ZOOM_resultset_create(); - const char *cp; ZOOM_task task; int start, count; const char *syntax, *elementSetName, *schema; @@ -754,6 +745,8 @@ ZOOM_API(ZOOM_resultset) r->options = ZOOM_options_create_with_parent(c->options); + r->req_facets = odr_strdup_null(r->odr, + ZOOM_options_get(r->options, "facets")); start = ZOOM_options_get_int(r->options, "start", 0); count = ZOOM_options_get_int(r->options, "count", 0); { @@ -763,34 +756,16 @@ ZOOM_API(ZOOM_resultset) (cp != 0 ? "presentChunk": "step"), 0); } r->piggyback = ZOOM_options_get_bool(r->options, "piggyback", 1); - cp = ZOOM_options_get(r->options, "setname"); - if (cp) - r->setname = xstrdup(cp); - - r->databaseNames = ZOOM_connection_get_databases(c, c->options, &r->num_databaseNames, - r->odr); - + r->setname = odr_strdup_null(r->odr, + ZOOM_options_get(r->options, "setname")); + r->databaseNames = ZOOM_connection_get_databases(c, c->options, + &r->num_databaseNames, + r->odr); r->connection = c; r->next = c->resultsets; c->resultsets = r; -#if HAVE_LIBMEMCACHED_MEMCACHED_H - r->mc_key = wrbuf_alloc(); - wrbuf_puts(r->mc_key, "0;"); - wrbuf_puts(r->mc_key, c->host_port); - wrbuf_puts(r->mc_key, ";"); - if (c->user) - wrbuf_puts(r->mc_key, c->user); - wrbuf_puts(r->mc_key, ";"); - if (c->group) - wrbuf_puts(r->mc_key, c->group); - wrbuf_puts(r->mc_key, ";"); - if (c->password) - wrbuf_sha1_puts(r->mc_key, c->password, 1); - wrbuf_puts(r->mc_key, ";"); - wrbuf_sha1_puts(r->mc_key, ZOOM_query_get_query_string(q), 1); - wrbuf_puts(r->mc_key, ";"); -#endif + ZOOM_memcached_resultset(r, q); if (c->host_port && c->proto == PROTO_HTTP) { @@ -908,7 +883,6 @@ static void resultset_destroy(ZOOM_resultset r) ZOOM_query_destroy(r->query); ZOOM_options_destroy(r->options); odr_destroy(r->odr); - xfree(r->setname); yaz_mutex_destroy(&r->mutex); #if SHPTR YAZ_SHPTR_DEC(r->record_wrbuf, wrbuf_destroy); @@ -1019,14 +993,14 @@ ZOOM_API(void) ZOOM_API(size_t) ZOOM_resultset_facets_size(ZOOM_resultset r) { - return r->num_facets; + return r->num_res_facets; } ZOOM_API(ZOOM_facet_field) ZOOM_resultset_get_facet_field(ZOOM_resultset r, const char *name) { - int num = r->num_facets; - ZOOM_facet_field *facets = r->facets; + int num = r->num_res_facets; + ZOOM_facet_field *facets = r->res_facets; int i; for (i = 0; i < num; i++) if (!strcmp(facets[i]->facet_name, name)) @@ -1037,8 +1011,8 @@ ZOOM_API(ZOOM_facet_field) ZOOM_API(ZOOM_facet_field) ZOOM_resultset_get_facet_field_by_index(ZOOM_resultset r, int idx) { - int num = r->num_facets; - ZOOM_facet_field *facets = r->facets; + int num = r->num_res_facets; + ZOOM_facet_field *facets = r->res_facets; if (idx >= 0 && idx < num) return facets[idx]; return 0; @@ -1047,7 +1021,7 @@ ZOOM_API(ZOOM_facet_field) ZOOM_API(ZOOM_facet_field *) ZOOM_resultset_facets(ZOOM_resultset r) { - return r->facets; + return r->res_facets; } ZOOM_API(const char**) @@ -1103,8 +1077,11 @@ static zoom_ret do_connect_host(ZOOM_connection c, const char *logical_url) if (c->cs) cs_close(c->cs); - c->cs = cs_create_host_proxy(logical_url, 0, &add, - c->tproxy ? c->tproxy : c->proxy); + c->cs = cs_create_host2(logical_url, CS_FLAGS_DNS_NO_BLOCK, &add, + c->tproxy ? c->tproxy : c->proxy, + &c->proxy_mode); + if (!c->proxy) + c->proxy_mode = 0; if (c->cs && c->cs->protocol == PROTO_HTTP) { @@ -1132,7 +1109,11 @@ static zoom_ret do_connect_host(ZOOM_connection c, const char *logical_url) assert(c->tasks->which == ZOOM_TASK_CONNECT); ZOOM_connection_remove_task(c); ZOOM_connection_set_mask(c, 0); - ZOOM_connection_exec_task(c); + + if (c->cs && c->location) + send_HTTP_redirect(c, c->location); + else + ZOOM_connection_exec_task(c); } c->state = STATE_ESTABLISHED; return zoom_pending; @@ -1168,7 +1149,7 @@ ZOOM_API(ZOOM_record) const char *schema = ZOOM_options_get(s->options, "schema"); - return ZOOM_record_cache_lookup(s, pos, syntax, elementSetName, schema); + return ZOOM_record_cache_lookup_i(s, pos, syntax, elementSetName, schema); } ZOOM_API(ZOOM_record) @@ -1522,7 +1503,6 @@ ZOOM_API(int) return 1; } -#if YAZ_HAVE_XML2 static zoom_ret send_HTTP_redirect(ZOOM_connection c, const char *uri) { @@ -1537,9 +1517,12 @@ static zoom_ret send_HTTP_redirect(ZOOM_connection c, const char *uri) z_HTTP_header_add_basic_auth(c->odr_out, &gdu->u.HTTP_Request->headers, c->user, c->password); } + xfree(c->location); + c->location = 0; return ZOOM_send_GDU(c, gdu); } + zoom_ret ZOOM_send_GDU(ZOOM_connection c, Z_GDU *gdu) { ZOOM_Event event; @@ -1560,15 +1543,13 @@ zoom_ret ZOOM_send_GDU(ZOOM_connection c, Z_GDU *gdu) return ZOOM_send_buf(c); } -#if YAZ_HAVE_XML2 void ZOOM_set_HTTP_error(ZOOM_connection c, int error, const char *addinfo, const char *addinfo2) { ZOOM_set_dset_error(c, error, "HTTP", addinfo, addinfo2); } -#endif - +#if YAZ_HAVE_XML2 static void handle_http(ZOOM_connection c, Z_HTTP_Response *hres) { zoom_ret cret = zoom_complete; @@ -1576,11 +1557,23 @@ static void handle_http(ZOOM_connection c, Z_HTTP_Response *hres) char *addinfo = 0; const char *connection_head = z_HTTP_header_lookup(hres->headers, "Connection"); + int must_close = 0; const char *location; ZOOM_connection_set_mask(c, 0); yaz_log(c->log_details, "%p handle_http", c); - + if (!strcmp(hres->version, "1.0")) + { + /* HTTP 1.0: only if Keep-Alive we stay alive.. */ + if (!connection_head || strcmp(connection_head, "Keep-Alive")) + must_close = 1; + } + else + { + /* HTTP 1.1: only if no close we stay alive.. */ + if (connection_head && !strcmp(connection_head, "close")) + must_close = 1; + } yaz_cookies_response(c->cookies, hres); if ((hres->code == 301 || hres->code == 302) && c->sru_mode == zoom_sru_get && (location = z_HTTP_header_lookup(hres->headers, "Location"))) @@ -1600,9 +1593,9 @@ static void handle_http(ZOOM_connection c, Z_HTTP_Response *hres) int host_change = 0; location = yaz_check_location(c->odr_in, c->host_port, location, &host_change); - if (do_connect_host(c, location) == zoom_complete) - return; /* connect failed.. */ - send_HTTP_redirect(c, location); + xfree(c->location); + c->location = xstrdup(location); + do_connect_host(c, location); return; } } @@ -1633,33 +1626,18 @@ static void handle_http(ZOOM_connection c, Z_HTTP_Response *hres) yaz_log(c->log_details, "removing tasks in handle_http"); ZOOM_connection_remove_task(c); } + if (must_close) { - int must_close = 0; - if (!strcmp(hres->version, "1.0")) - { - /* HTTP 1.0: only if Keep-Alive we stay alive.. */ - if (!connection_head || strcmp(connection_head, "Keep-Alive")) - must_close = 1; - } - else - { - /* HTTP 1.1: only if no close we stay alive.. */ - if (connection_head && !strcmp(connection_head, "close")) - must_close = 1; - } - if (must_close) + ZOOM_connection_close(c); + if (c->tasks) { - ZOOM_connection_close(c); - if (c->tasks) - { - c->tasks->running = 0; - ZOOM_connection_insert_task(c, ZOOM_TASK_CONNECT); - c->reconnect_ok = 0; - } + c->tasks->running = 0; + ZOOM_connection_insert_task(c, ZOOM_TASK_CONNECT); + c->reconnect_ok = 0; } - else - c->reconnect_ok = 1; /* if the server closes anyway */ } + else + c->reconnect_ok = 1; /* if the server closes anyway */ } #endif @@ -1696,22 +1674,26 @@ static int do_read(ZOOM_connection c) if (!z_GDU(c->odr_in, &gdu, 0, 0)) { - int x; - int err = odr_geterrorx(c->odr_in, &x); - char msg[100]; - const char *element = odr_getelement(c->odr_in); - yaz_snprintf(msg, sizeof(msg), - "ODR code %d:%d element=%s offset=%d", - err, x, element ? element : "", - odr_offset(c->odr_in)); - ZOOM_set_error(c, ZOOM_ERROR_DECODE, msg); - if (c->log_api) + /* even on failures we try to re-connect (HTTP) */ + if (!ZOOM_test_reconnect(c)) { - FILE *ber_file = yaz_log_file(); - if (ber_file) - odr_dumpBER(ber_file, c->buf_in, r); + int x; + int err = odr_geterrorx(c->odr_in, &x); + char msg[100]; + const char *element = odr_getelement(c->odr_in); + yaz_snprintf(msg, sizeof(msg), + "ODR code %d:%d element=%s offset=%d", + err, x, element ? element : "", + odr_offset(c->odr_in)); + ZOOM_set_error(c, ZOOM_ERROR_DECODE, msg); + if (c->log_api) + { + FILE *ber_file = yaz_log_file(); + if (ber_file) + odr_dumpBER(ber_file, c->buf_in, r); + } + ZOOM_connection_close(c); } - ZOOM_connection_close(c); } else { @@ -1999,7 +1981,7 @@ static void ZOOM_connection_do_io(ZOOM_connection c, int mask) if (c->cs->io_pending & CS_WANT_READ) mask += ZOOM_SELECT_READ; ZOOM_connection_set_mask(c, mask); - event = ZOOM_Event_create(ZOOM_EVENT_NONE); + event = ZOOM_Event_create(ZOOM_EVENT_CONNECT); ZOOM_connection_put_event(c, event); } else if (ret == 0) @@ -2012,10 +1994,15 @@ static void ZOOM_connection_do_io(ZOOM_connection c, int mask) else { /* no init request for SRW .. */ - assert(c->tasks->which == ZOOM_TASK_CONNECT); - ZOOM_connection_remove_task(c); - ZOOM_connection_set_mask(c, 0); - ZOOM_connection_exec_task(c); + if (c->tasks->which == ZOOM_TASK_CONNECT) + { + ZOOM_connection_remove_task(c); + ZOOM_connection_set_mask(c, 0); + } + if (c->cs && c->location) + send_HTTP_redirect(c, c->location); + else + ZOOM_connection_exec_task(c); } c->state = STATE_ESTABLISHED; }