X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Fzoom-c.c;h=8a9b344271e41f9ab9be5379358b9438a735f3fd;hp=c23e631bbdf76799746454c47888bc4e82dc7a7f;hb=a741500ee64cc5009f82d94585ea389e1c5e6613;hpb=473824797f568578dc17d7242551cb2f7ccef46c diff --git a/src/zoom-c.c b/src/zoom-c.c index c23e631..8a9b344 100644 --- a/src/zoom-c.c +++ b/src/zoom-c.c @@ -306,7 +306,12 @@ ZOOM_API(ZOOM_connection) c->sru_version = 0; c->no_redirects = 0; + c->cookies = 0; c->saveAPDU_wrbuf = 0; + +#if HAVE_LIBMEMCACHED_MEMCACHED_H + c->mc_st = 0; +#endif return c; } @@ -369,6 +374,7 @@ ZOOM_API(void) const char *host, int portnum) { const char *val; + const char *http_lead; initlog(); @@ -435,17 +441,25 @@ 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]; xfree(c->host_port); if (portnum) { - char hostn[128]; sprintf(hostn, "%.80s:%d", host, portnum); - c->host_port = xstrdup(hostn); + host = hostn; } - else - c->host_port = xstrdup(host); + c->host_port = xmalloc(strlen(host) + strlen(http_lead) + 1); + strcpy(c->host_port, http_lead); + strcat(c->host_port, host); } { @@ -481,9 +495,6 @@ ZOOM_API(void) } } - val = ZOOM_options_get(c->options, "sru"); - c->sru_mode = get_sru_mode_from_string(val); - xfree(c->sru_version); val = ZOOM_options_get(c->options, "sru_version"); c->sru_version = xstrdup(val ? val : "1.2"); @@ -542,6 +553,32 @@ ZOOM_API(void) c->async = ZOOM_options_get_bool(c->options, "async", 0); + 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 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"); + return; +#endif + } + if (c->sru_mode == zoom_sru_error) { ZOOM_set_error(c, ZOOM_ERROR_UNSUPPORTED_PROTOCOL, val); @@ -586,6 +623,11 @@ ZOOM_API(void) if (!c) 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 if (c->cs) cs_close(c->cs); @@ -619,6 +661,7 @@ ZOOM_API(void) xfree(c->group); xfree(c->password); xfree(c->sru_version); + yaz_cookies_destroy(c->cookies); wrbuf_destroy(c->saveAPDU_wrbuf); xfree(c); } @@ -689,6 +732,7 @@ ZOOM_resultset ZOOM_resultset_create(void) } #endif resultset_use(1); + r->mc_key = 0; return r; } @@ -709,11 +753,10 @@ ZOOM_API(ZOOM_resultset) ZOOM_connection_search(ZOOM_connection c, ZOOM_query q) { ZOOM_resultset r = ZOOM_resultset_create(); - ZOOM_task task; const char *cp; + ZOOM_task task; int start, count; const char *syntax, *elementSetName, *schema; - yaz_log(c->log_api, "%p ZOOM_connection_search set %p query %p", c, r, q); r->r_sort_spec = ZOOM_query_get_sortspec(q); r->query = q; @@ -739,6 +782,31 @@ ZOOM_API(ZOOM_resultset) 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, c->host_port); + wrbuf_puts(r->mc_key, ";"); + wrbuf_puts(r->mc_key, ZOOM_query_get_query_string(q)); + if (c->mc_st) + { + size_t v_len; + uint32_t flags; + memcached_return_t rc; + char *v = memcached_get(c->mc_st, wrbuf_buf(r->mc_key), + wrbuf_len(r->mc_key), &v_len, &flags, &rc); + if (v) + { + yaz_log(YLOG_LOG, "For key %s got value %.*s", + wrbuf_cstr(r->mc_key), (int) v_len, v); + } + else + { + yaz_log(YLOG_LOG, "For key %s got NO value", wrbuf_cstr(r->mc_key)); + } + } +#endif + if (c->host_port && c->proto == PROTO_HTTP) { if (!c->cs) @@ -863,6 +931,7 @@ static void resultset_destroy(ZOOM_resultset r) #if SHPTR YAZ_SHPTR_DEC(r->record_wrbuf, wrbuf_destroy); #endif + wrbuf_destroy(r->mc_key); resultset_use(-1); xfree(r); } @@ -1478,43 +1547,14 @@ ZOOM_API(int) #if YAZ_HAVE_XML2 -static zoom_ret send_HTTP_redirect(ZOOM_connection c, const char *uri, - Z_HTTP_Response *cookie_hres) +static zoom_ret send_HTTP_redirect(ZOOM_connection c, const char *uri) { - struct Z_HTTP_Header *h; - char *combined_cookies = 0; - int combined_cookies_len = 0; Z_GDU *gdu = z_get_HTTP_Request_uri(c->odr_out, uri, 0, c->proxy ? 1 : 0); gdu->u.HTTP_Request->method = odr_strdup(c->odr_out, "GET"); z_HTTP_header_add(c->odr_out, &gdu->u.HTTP_Request->headers, "Accept", "text/xml"); - - for (h = cookie_hres->headers; h; h = h->next) - { - if (!strcmp(h->name, "Set-Cookie")) - { - char *cp; - - if (!(cp = strchr(h->value, ';'))) - cp = h->value + strlen(h->value); - if (cp - h->value >= 1) { - combined_cookies = xrealloc(combined_cookies, combined_cookies_len + cp - h->value + 3); - memcpy(combined_cookies+combined_cookies_len, h->value, cp - h->value); - combined_cookies[combined_cookies_len + cp - h->value] = '\0'; - strcat(combined_cookies,"; "); - combined_cookies_len = strlen(combined_cookies); - } - } - } - - if (combined_cookies_len) - { - z_HTTP_header_add(c->odr_out, &gdu->u.HTTP_Request->headers, - "Cookie", combined_cookies); - xfree(combined_cookies); - } - + yaz_cookies_request(c->cookies, c->odr_out, gdu->u.HTTP_Request); if (c->user && c->password) { z_HTTP_header_add_basic_auth(c->odr_out, &gdu->u.HTTP_Request->headers, @@ -1564,6 +1604,7 @@ static void handle_http(ZOOM_connection c, Z_HTTP_Response *hres) ZOOM_connection_set_mask(c, 0); yaz_log(c->log_details, "%p handle_http", c); + 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"))) { @@ -1578,9 +1619,13 @@ static void handle_http(ZOOM_connection c, Z_HTTP_Response *hres) { /* since redirect may change host we just reconnect. A smarter implementation might check whether it's the same server */ - do_connect_host(c, location); - send_HTTP_redirect(c, location, hres); - /* we're OK for now. Operation is not really complete */ + + 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); return; } } @@ -1911,6 +1956,8 @@ ZOOM_API(const char *) return "Extended Service. invalid version"; case ZOOM_ERROR_ES_INVALID_SYNTAX: return "Extended Service. invalid syntax"; + case ZOOM_ERROR_MEMCACHED: + return "Memcached"; default: return diagbib1_str(error); }