X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=client%2Fclient.c;h=3c68c585ef7e1cf01399c24c232a9f9d5af01907;hb=b0180cb3c16e1c9e4de0697dba03337204a27a51;hp=1230cdb8bc41e77a8c3227dd664b22a29fc45b08;hpb=46f5205bdb8e837ab305644839451949916e40cb;p=yaz-moved-to-github.git diff --git a/client/client.c b/client/client.c index 1230cdb..3c68c58 100644 --- a/client/client.c +++ b/client/client.c @@ -182,6 +182,7 @@ static void close_session(void); static void marc_file_write(const char *buf, size_t sz); static void wait_and_handle_response(int one_response_only); +static Z_GDU *get_HTTP_Request_url(ODR odr, const char *url); ODR getODROutputStream(void) { @@ -665,11 +666,10 @@ static int cmd_base(const char *arg) return set_base(arg); } -int session_connect(const char *arg) +static int session_connect_base(const char *arg, const char **basep) { void *add; char type_and_host[101]; - const char *basep = 0; if (conn) { cs_close(conn); @@ -681,7 +681,7 @@ int session_connect(const char *arg) session_mem = NULL; session_initResponse = 0; } - cs_get_host_args(arg, &basep); + cs_get_host_args(arg, basep); strncpy(type_and_host, arg, sizeof(type_and_host)-1); type_and_host[sizeof(type_and_host)-1] = '\0'; @@ -717,11 +717,6 @@ int session_connect(const char *arg) } printf("OK.\n"); cs_print_session_info(conn); - if (basep && *basep) - set_base(basep); - else if (protocol == PROTO_Z3950) - set_base("Default"); - if (protocol == PROTO_Z3950) { send_initRequest(type_and_host); @@ -730,6 +725,19 @@ int session_connect(const char *arg) return 0; } +static int session_connect(const char *arg) +{ + int r; + const char *basep = 0; + + r = session_connect_base(arg, &basep); + if (basep && *basep) + set_base(basep); + else if (protocol == PROTO_Z3950) + set_base("Default"); + return r; +} + int cmd_open(const char *arg) { int r; @@ -1191,12 +1199,39 @@ static int send_deleteResultSetRequest(const char *arg) } #if YAZ_HAVE_XML2 -static int send_srw(Z_SRW_PDU *sr) +static int send_gdu(Z_GDU *gdu) +{ + if (z_GDU(out, &gdu, 0, 0)) + { + /* encode OK */ + char *buf_out; + int len_out; + int r; + if (apdu_file) + { + if (!z_GDU(print, &gdu, 0, 0)) + printf("Failed to print outgoing SRU package\n"); + odr_reset(print); + } + buf_out = odr_getbuf(out, &len_out, 0); + + /* we don't odr_reset(out), since we may need the buffer again */ + + do_hex_dump(buf_out, len_out); + + r = cs_put(conn, buf_out, len_out); + + if (r >= 0) + return 2; + } + return 0; +} + +static int send_srw_host_path(Z_SRW_PDU *sr, const char *host_port, + char *path) { const char *charset = negotiationCharset; - const char *host_port = cur_host; Z_GDU *gdu; - char *path = yaz_encode_sru_dbpath_odr(out, databaseNames[0]); gdu = z_get_HTTP_Request_host_path(out, host_port, path); @@ -1231,31 +1266,59 @@ static int send_srw(Z_SRW_PDU *sr) { yaz_sru_soap_encode(gdu->u.HTTP_Request, sr, out, charset); } + return send_gdu(gdu); +} - if (z_GDU(out, &gdu, 0, 0)) - { - /* encode OK */ - char *buf_out; - int len_out; - int r; - if (apdu_file) - { - if (!z_GDU(print, &gdu, 0, 0)) - printf("Failed to print outgoing SRU package\n"); - odr_reset(print); - } - buf_out = odr_getbuf(out, &len_out, 0); +static int send_srw(Z_SRW_PDU *sr) +{ + char *path = yaz_encode_sru_dbpath_odr(out, databaseNames[0]); + return send_srw_host_path(sr, cur_host, path); +} - /* we don't odr_reset(out), since we may need the buffer again */ +static int send_SRW_redirect(const char *uri, Z_HTTP_Response *cookie_hres) +{ + const char *username = 0; + const char *password = 0; + struct Z_HTTP_Header *h; + Z_GDU *gdu = get_HTTP_Request_url(out, uri); - do_hex_dump(buf_out, len_out); + gdu->u.HTTP_Request->method = odr_strdup(out, "GET"); + z_HTTP_header_add(out, &gdu->u.HTTP_Request->headers, "Accept", + "text/xml"); + + for (h = cookie_hres->headers; h; h = h->next) + { + if (!strcmp(h->name, "Set-Cookie")) + z_HTTP_header_add(out, &gdu->u.HTTP_Request->headers, + "Cookie", h->value); + } - r = cs_put(conn, buf_out, len_out); + if (auth) + { + if (auth->which == Z_IdAuthentication_open) + { + char **darray; + int num; + nmem_strsplit(out->mem, "/", auth->u.open, &darray, &num); + if (num >= 1) + username = darray[0]; + if (num >= 2) + password = darray[1]; + } + else if (auth->which == Z_IdAuthentication_idPass) + { + username = auth->u.idPass->userId; + password = auth->u.idPass->password; + } + } - if (r >= 0) - return 2; + if (username && password) + { + z_HTTP_header_add_basic_auth(out, &gdu->u.HTTP_Request->headers, + username, password); } - return 0; + + return send_gdu(gdu); } #endif @@ -4224,9 +4287,12 @@ static void http_response(Z_HTTP_Response *hres) } #endif +#define max_HTTP_redirects 2 + static void wait_and_handle_response(int one_response_only) { int reconnect_ok = 1; + int no_redirects = 0; int res; char *netbuffer= 0; int netbufferlen = 0; @@ -4355,7 +4421,26 @@ static void wait_and_handle_response(int one_response_only) #if YAZ_HAVE_XML2 else if (gdu->which == Z_GDU_HTTP_Response) { - http_response(gdu->u.HTTP_Response); + Z_HTTP_Response *hres = gdu->u.HTTP_Response; + int code = hres->code; + const char *location = 0; + if ((code == 301 || code == 302) + && no_redirects < max_HTTP_redirects + && !yaz_matchstr(sru_method, "get") + && (location = z_HTTP_header_lookup(hres->headers, "Location"))) + { + const char *base_tmp; + session_connect_base(location, &base_tmp); + no_redirects++; + if (conn) + { + if (send_SRW_redirect(location, hres) == 2) + continue; + } + printf("Redirect failed\n"); + } + else + http_response(gdu->u.HTTP_Response); } #endif if (one_response_only)