X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=client%2Fclient.c;h=144c0f484750a4be912e42f64977044a989ad6b1;hb=1b814737d1572a6fc4bec2a3d120d6954d12bdb1;hp=09c9a85ce36479404f27caa27e2e4aa137eeaca4;hpb=4e641034b013c43b20922f66258f5daf8ac3ce59;p=yaz-moved-to-github.git diff --git a/client/client.c b/client/client.c index 09c9a85..144c0f4 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 @@ -2783,36 +2846,54 @@ static int cmd_setnames(const char *arg) /* PRESENT SERVICE ----------------------------- */ -static void parse_show_args(const char *arg_c, char *setstring, - Odr_int *start, Odr_int *number) +static int parse_show_args(const char *arg_c, char *setstring, + Odr_int *start, Odr_int *number) { - char arg[40]; - char *p; + char *end_ptr; + Odr_int start_position; - strncpy(arg, arg_c, sizeof(arg)-1); - arg[sizeof(arg)-1] = '\0'; + if (setnumber >= 0) + sprintf(setstring, "%d", setnumber); + else + *setstring = '\0'; - if ((p = strchr(arg, '+'))) + if (!strcmp(arg_c, "all")) { - *number = odr_atoi(p + 1); - *p = '\0'; + *number = last_hit_count; + *start = 1; } - if (*arg) + start_position = odr_strtol(arg_c, &end_ptr, 10); + if (end_ptr == arg_c) + return 1; + *start = start_position; + if (*end_ptr == '\0') + return 1; + while (isspace(*(unsigned char *)end_ptr)) + end_ptr++; + if (*end_ptr != '+') { - if (!strcmp(arg, "all")) - { - *number = last_hit_count; - *start = 1; - } - else - *start = odr_atoi(arg); + printf("Bad show arg: expected +. Got %s\n", end_ptr); + return 0; } - if (p && (p=strchr(p+1, '+'))) - strcpy(setstring, p+1); - else if (setnumber >= 0) - sprintf(setstring, "%d", setnumber); - else - *setstring = '\0'; + end_ptr++; + arg_c = end_ptr; + *number = odr_strtol(arg_c, &end_ptr, 10); + if (end_ptr == arg_c) + { + printf("Bad show arg: expected number after +\n"); + return 0; + } + if (*end_ptr == '\0') + return 1; + while (isspace(*(unsigned char *)end_ptr)) + end_ptr++; + if (*end_ptr != '+') + { + printf("Bad show arg: + expected. Got %s\n", end_ptr); + return 0; + } + strcpy(setstring, end_ptr+1); + return 1; } static int send_presentRequest(const char *arg) @@ -2825,7 +2906,8 @@ static int send_presentRequest(const char *arg) req->referenceId = set_refid(out); - parse_show_args(arg, setstring, &setno, &nos); + if (!parse_show_args(arg, setstring, &setno, &nos)) + return 0; if (*setstring) req->resultSetId = setstring; @@ -2916,7 +2998,8 @@ static int send_SRW_presentRequest(const char *arg) if (!sr) return 0; - parse_show_args(arg, setstring, &setno, &nos); + if (!parse_show_args(arg, setstring, &setno, &nos)) + return 0; sr->u.request->startRecord = odr_intdup(out, setno); sr->u.request->maximumRecords = odr_intdup(out, nos); if (record_schema) @@ -4208,9 +4291,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; @@ -4339,7 +4425,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)