1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) 1995-2011 Index Data
3 * See the file LICENSE for details.
7 * \brief URL fetch utility
14 #include <yaz/comstack.h>
23 yaz_url_t yaz_url_create(void)
25 yaz_url_t p = xmalloc(sizeof(*p));
26 p->odr_in = odr_createmem(ODR_DECODE);
27 p->odr_out = odr_createmem(ODR_ENCODE);
32 void yaz_url_destroy(yaz_url_t p)
36 odr_destroy(p->odr_in);
37 odr_destroy(p->odr_out);
43 void yaz_url_set_proxy(yaz_url_t p, const char *proxy)
48 p->proxy = xstrdup(proxy);
51 Z_HTTP_Response *yaz_url_exec(yaz_url_t p, const char *uri,
53 Z_HTTP_Header *headers,
54 const char *buf, size_t len)
56 Z_HTTP_Response *res = 0;
57 int number_of_redirects = 0;
64 struct Z_HTTP_Header **last_header_entry;
65 const char *location = 0;
66 Z_GDU *gdu = z_get_HTTP_Request_uri(p->odr_out, uri, 0,
68 gdu->u.HTTP_Request->method = odr_strdup(p->odr_out, method);
71 last_header_entry = &gdu->u.HTTP_Request->headers;
72 while (*last_header_entry)
73 last_header_entry = &(*last_header_entry)->next;
74 *last_header_entry = headers; /* attach user headers */
78 gdu->u.HTTP_Request->content_buf = (char *) buf;
79 gdu->u.HTTP_Request->content_len = len;
81 if (!z_GDU(p->odr_out, &gdu, 0, 0))
83 yaz_log(YLOG_WARN, "Can not encode HTTP request URL:%s", uri);
86 conn = cs_create_host_proxy(uri, 1, &add, p->proxy);
89 yaz_log(YLOG_WARN, "Bad address for URL:%s", uri);
91 else if (cs_connect(conn, add) < 0)
93 yaz_log(YLOG_WARN, "Can not connect to URL:%s", uri);
98 char *buf = odr_getbuf(p->odr_out, &len, 0);
100 if (cs_put(conn, buf, len) < 0)
101 yaz_log(YLOG_WARN, "cs_put failed URL:%s", uri);
106 int cs_res = cs_get(conn, &netbuffer, &netlen);
109 yaz_log(YLOG_WARN, "cs_get failed URL:%s", uri);
114 odr_setbuf(p->odr_in, netbuffer, cs_res, 0);
115 if (!z_GDU(p->odr_in, &gdu, 0, 0)
116 || gdu->which != Z_GDU_HTTP_Response)
118 yaz_log(YLOG_WARN, "HTTP decoding failed "
123 res = gdu->u.HTTP_Response;
134 location = z_HTTP_header_lookup(res->headers, "Location");
135 if (++number_of_redirects < 10 &&
136 location && (code == 301 || code == 302 || code == 307))
138 odr_reset(p->odr_out);
139 uri = odr_strdup(p->odr_out, location);
140 odr_reset(p->odr_in);
151 * c-file-style: "Stroustrup"
152 * indent-tabs-mode: nil
154 * vim: shiftwidth=4 tabstop=8 expandtab