YAZ 5.38.1
http.c
Go to the documentation of this file.
1/* This file is part of the YAZ toolkit.
2 * Copyright (C) Index Data
3 * See the file LICENSE for details.
4 */
9#if HAVE_CONFIG_H
10#include <config.h>
11#endif
12
13#include "odr-priv.h"
14#include <yaz/yaz-version.h>
15#include <yaz/yaz-iconv.h>
16#include <yaz/matchstr.h>
17#include <yaz/zgdu.h>
18#include <yaz/base64.h>
19#include <yaz/comstack.h>
20#include <yaz/snprintf.h>
21#include "comstack-p.h"
22
23static int decode_headers_content(ODR o, int off, Z_HTTP_Header **headers,
24 char **content_buf, int *content_len)
25{
26 int i = off;
27 int chunked = 0;
28 const char *buf = o->op->buf;
29 int size = o->op->size;
30
31 *headers = 0;
32 while (i < size-1 && buf[i] == '\n')
33 {
34 int po;
35 i++;
36 if (buf[i] == '\r' && i < size-1 && buf[i+1] == '\n')
37 {
38 i++;
39 break;
40 }
41 if (buf[i] == '\n')
42 break;
43 for (po = i; ; i++)
44 {
45 if (i == size)
46 {
47 o->error = OHTTP;
48 return 0;
49 }
50 else if (buf[i] == ':')
51 break;
52 }
53 *headers = (Z_HTTP_Header *) odr_malloc(o, sizeof(**headers));
54 (*headers)->name = odr_strdupn(o, buf + po, i - po);
55 i++;
56 while (i < size-1 && buf[i] == ' ')
57 i++;
58 for (po = i; i < size-1 && !strchr("\r\n", buf[i]); i++)
59 ;
60
61 (*headers)->value = odr_strdupn(o, buf + po, i - po);
62 if (!yaz_strcasecmp((*headers)->name, "Transfer-Encoding")
63 &&
64 !yaz_strcasecmp((*headers)->value, "chunked"))
65 chunked = 1;
66 headers = &(*headers)->next;
67 if (i < size-1 && buf[i] == '\r')
68 i++;
69 }
70 *headers = 0;
71 if (buf[i] != '\n')
72 {
73 o->error = OHTTP;
74 return 0;
75 }
76 i++;
77
78 if (chunked)
79 {
80 int r;
81
82 /* we know buffer will be smaller than o->size - i*/
83 *content_buf = (char*) odr_malloc(o, size - i);
84 r = yaz_http_parse_chunks(buf + i, size - i, *content_buf,
85 content_len);
86 if (r <= 0)
87 {
88 o->error = OHTTP;
89 return 0;
90 }
91 if (!*content_len)
92 *content_buf = 0;
93 }
94 else
95 {
96 if (i > size)
97 {
98 o->error = OHTTP;
99 return 0;
100 }
101 else if (i == size)
102 {
103 *content_buf = 0;
104 *content_len = 0;
105 }
106 else
107 {
108 *content_len = size - i;
109 *content_buf = odr_strdupn(o, buf + i, *content_len);
110 }
111 }
112 return 1;
113}
114
116 const char *content_type,
117 const char *charset)
118{
119 const char *l = "Content-Type";
120 if (charset)
121 {
122 char *ctype = nmem_printf(odr_getmem(o), "%s; charset=%s",
123 content_type, charset);
124 z_HTTP_header_add(o, hp, l, ctype);
125 }
126 else
127 z_HTTP_header_add(o, hp, l, content_type);
128
129}
130
131/*
132 * HTTP Basic authentication is described at:
133 * http://tools.ietf.org/html/rfc1945#section-11.1
134 */
136 const char *username, const char *password)
137{
138 char *tmp, *buf;
139
140 if (username == 0)
141 return;
142 if (password == 0)
143 password = "";
144
145 tmp = nmem_printf(odr_getmem(o), "%s:%s", username, password);
146 buf = (char *) odr_malloc(o, strlen(tmp) * 8/6 + 12);
147 strcpy(buf, "Basic ");
148 yaz_base64encode(tmp, &buf[strlen(buf)]);
149 z_HTTP_header_set(o, hp, "Authorization", buf);
150}
151
152void z_HTTP_header_add(ODR o, Z_HTTP_Header **hp, const char *n,
153 const char *v)
154{
155 while (*hp)
156 hp = &(*hp)->next;
157 *hp = (Z_HTTP_Header *) odr_malloc(o, sizeof(**hp));
158 (*hp)->name = odr_strdup(o, n);
159 (*hp)->value = odr_strdup(o, v);
160 (*hp)->next = 0;
161}
162
163void z_HTTP_header_set(ODR o, Z_HTTP_Header **hp, const char *n,
164 const char *v)
165{
166 while (*hp)
167 {
168 if (!yaz_strcasecmp((*hp)->name, n))
169 {
170 (*hp)->value = odr_strdup(o, v);
171 return;
172 }
173 hp = &(*hp)->next;
174 }
175 *hp = (Z_HTTP_Header *) odr_malloc(o, sizeof(**hp));
176 (*hp)->name = odr_strdup(o, n);
177 (*hp)->value = odr_strdup(o, v);
178 (*hp)->next = 0;
179}
180
181const char *z_HTTP_header_remove(Z_HTTP_Header **hp, const char *n)
182{
183 while (*hp)
184 {
185 if (!yaz_strcasecmp((*hp)->name, n))
186 {
187 const char *v = (*hp)->value;
188 *hp = (*hp)->next;
189 return v;
190 }
191 hp = &(*hp)->next;
192 }
193 return 0;
194}
195
196const char *z_HTTP_header_lookup(const Z_HTTP_Header *hp, const char *n)
197{
198 for (; hp; hp = hp->next)
199 if (!yaz_strcasecmp(hp->name, n))
200 return hp->value;
201 return 0;
202}
203
204
206{
207 Z_GDU *p = (Z_GDU *) odr_malloc(o, sizeof(*p));
208 Z_HTTP_Request *hreq;
209
211 p->u.HTTP_Request = (Z_HTTP_Request *) odr_malloc(o, sizeof(*hreq));
212 hreq = p->u.HTTP_Request;
213 hreq->headers = 0;
214 hreq->content_len = 0;
215 hreq->content_buf = 0;
216 hreq->version = "1.1";
217 hreq->method = "POST";
218 hreq->path = "/";
219 z_HTTP_header_add(o, &hreq->headers, "User-Agent", "YAZ/" YAZ_VERSION);
220 return p;
221}
222
223
225 const char *host,
226 const char *path)
227{
229
230 p->u.HTTP_Request->path = odr_strdup(odr, path);
231
232 if (host)
233 {
234 const char *cp0 = strstr(host, "://");
235 const char *cp1 = 0;
236 if (cp0)
237 cp0 = cp0+3;
238 else
239 cp0 = host;
240
241 cp1 = strchr(cp0, '/');
242 if (!cp1)
243 cp1 = cp0+strlen(cp0);
244
245 if (cp0 && cp1)
246 {
247 char *h = odr_strdupn(odr, cp0, cp1 - cp0);
248 z_HTTP_header_add(odr, &p->u.HTTP_Request->headers, "Host", h);
249 }
250 }
251 return p;
252}
253
254Z_GDU *z_get_HTTP_Request_uri(ODR odr, const char *uri, const char *args,
255 int use_full_uri)
256{
258 const char *cp0 = strstr(uri, "://");
259 const char *cp1 = 0;
260 if (cp0)
261 cp0 = cp0+3;
262 else
263 cp0 = uri;
264
265 cp1 = strchr(cp0, '/');
266 if (!cp1)
267 cp1 = cp0+strlen(cp0);
268
269 if (cp0 && cp1)
270 {
271 char *h = odr_strdupn(odr, cp0, cp1 - cp0);
272 z_HTTP_header_add(odr, &p->u.HTTP_Request->headers, "Host", h);
273 }
274
275 if (!args)
276 {
277 if (*cp1)
278 args = cp1 + 1;
279 else
280 args = "";
281 }
282 p->u.HTTP_Request->path = odr_malloc(odr, cp1 - uri + strlen(args) + 2);
283 if (use_full_uri)
284 {
285 memcpy(p->u.HTTP_Request->path, uri, cp1 - uri);
286 strcpy(p->u.HTTP_Request->path + (cp1 - uri), "/");
287 }
288 else
289 strcpy(p->u.HTTP_Request->path, "/");
290 strcat(p->u.HTTP_Request->path, args);
291 return p;
292}
293
294Z_GDU *z_get_HTTP_Response_server(ODR o, int code, const char *details,
295 const char *server, const char *server_url)
296{
297 Z_GDU *p = (Z_GDU *) odr_malloc(o, sizeof(*p));
298 Z_HTTP_Response *hres;
299
301 p->u.HTTP_Response = (Z_HTTP_Response *) odr_malloc(o, sizeof(*hres));
302 hres = p->u.HTTP_Response;
303 hres->headers = 0;
304 hres->content_len = 0;
305 hres->content_buf = 0;
306 hres->code = code;
307 hres->version = "1.1";
308 z_HTTP_header_add(o, &hres->headers, "Server", server);
309 if (code != 200)
310 {
311 const char *http_err = z_HTTP_errmsg(code);
312 size_t sz = 400 + strlen(http_err) + (details ?
313 strlen(details) : 0);
314 hres->content_buf = (char*) odr_malloc(o, sz);
315 yaz_snprintf(hres->content_buf, sz,
316 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\""
317 " \"http://www.w3.org/TR/html4/strict.dtd\">\n"
318 "<HTML>\n"
319 " <HEAD>\n"
320 " <TITLE>%s</TITLE>\n"
321 " </HEAD>\n"
322 " <BODY>\n"
323 " <P><A HREF=\"%s\">%s</A></P>\n"
324 " <P>Error: %d</P>\n"
325 " <P>Description: %s</P>\n", server, server_url, server,
326 code, http_err);
327 if (details)
328 {
329 yaz_snprintf(hres->content_buf + strlen(hres->content_buf),
330 sz - strlen(hres->content_buf),
331 "<P>Details: %s</P>\n", details);
332 }
333 yaz_snprintf(hres->content_buf + strlen(hres->content_buf),
334 sz - strlen(hres->content_buf),
335 " </BODY>\n"
336 "</HTML>\n");
337 hres->content_len = strlen(hres->content_buf);
338 z_HTTP_header_add(o, &hres->headers, "Content-Type", "text/html");
339 }
340 return p;
341}
342
343Z_GDU *z_get_HTTP_Response_details(ODR o, int code, const char *details)
344{
345 return z_get_HTTP_Response_server(o, code, details, "YAZ/" YAZ_VERSION,
346 "http://www.indexdata.com/yaz");
347}
348
350{
351 return z_get_HTTP_Response_details(o, code, 0);
352}
353
354const char *z_HTTP_errmsg(int code)
355{
356 switch (code)
357 {
358 case 100:
359 return "Continue";
360 case 101:
361 return "Switching Protocols";
362 case 200:
363 return "OK";
364 case 201:
365 return "Created";
366 case 202:
367 return "Accepted";
368 case 203:
369 return "Non-Authoritative Information";
370 case 204:
371 return "No Content";
372 case 205:
373 return "Reset Content";
374 case 206:
375 return "Partial Content";
376 case 300:
377 return "Multiple Choices";
378 case 301:
379 return "Moved Permenently";
380 case 302:
381 return "Found";
382 case 303:
383 return "See Other";
384 case 304:
385 return "Not Modified";
386 case 305:
387 return "Use Proxy";
388 case 307:
389 return "Temporary Redirect";
390 case 400:
391 return "Bad Request";
392 case 404:
393 return "Not Found";
394 case 405:
395 return "Method Not Allowed";
396 case 406:
397 return "Not Acceptable";
398 case 407:
399 return "Proxy Authentication Required";
400 case 408:
401 return "Request Timeout";
402 case 409:
403 return "Conflict";
404 case 410:
405 return "Gone";
406 case 411:
407 return "Length Required";
408 case 412:
409 return "Precondition Failed";
410 case 413:
411 return "Request Entity Too Large";
412 case 414:
413 return "Request-URI Too Long";
414 case 415:
415 return "Unsupported Media Type";
416 case 416:
417 return "Requested Range Not Satisfiable";
418 case 417:
419 return "Expectation Failed";
420 case 500:
421 return "Internal Error";
422 case 501:
423 return "Not Implemented";
424 case 502:
425 return "Bad Gateway";
426 case 503:
427 return "Service Unavailable";
428 case 504:
429 return "Gateway Timeout";
430 case 505:
431 return "HTTP Version Not Supported";
432 default:
433 return "Unknown Error";
434 }
435}
436
437int yaz_decode_http_response_first(const char *buf, int sz, int *code, const char **version, int *version_len, const char **msg, int *msg_len)
438{
439 int i, j;
440 if (sz < 10 || memcmp(buf, "HTTP/", 5))
441 return 0;
442 for (i = 5; ; i++)
443 if (i >= sz-1)
444 return 0;
445 else if (strchr(" \r\n", buf[i]))
446 break;
447 if (buf[i] != ' ')
448 return 0;
449 if (version)
450 *version = buf + 5;
451 if (version_len)
452 *version_len = i - 5;
453 i++;
454 *code = 0;
455 for (j = i; ; i++)
456 {
457 if (i >= sz-1)
458 return 0;
459 if (i > j+3)
460 return 0;
461 if (buf[i] < '0' || buf[i] > '9')
462 break;
463 *code = *code*10 + (buf[i] - '0');
464 }
465 if (buf[i] != ' ')
466 return 0;
467 i++;
468 for (j = i; ; i++)
469 {
470 if (i >= sz)
471 return 0;
472 if (strchr("\r\n", buf[i]))
473 break;
474 }
475 if (msg)
476 *msg = buf + j;
477 if (msg_len)
478 *msg_len = i - j;
479 if (i < sz - 1 && buf[i] == '\r')
480 i++;
481 if (buf[i] != '\n')
482 return 0;
483 return i;
484}
485
487{
488 const char *version;
489 int version_len;
490 const char *buf = o->op->buf;
491 int size = o->op->size;
492 int code;
493 int i = yaz_decode_http_response_first(buf, size, &code, &version, &version_len, 0, 0);
494 Z_HTTP_Response *hr;
495 *hr_p = 0;
496 if (i == 0)
497 {
498 o->error = OHTTP;
499 return 0;
500 }
501 *hr_p = hr = (Z_HTTP_Response *) odr_malloc(o, sizeof(*hr));
502 hr->version = odr_strdupn(o, version, version_len);
503 hr->code = code;
504 return decode_headers_content(o, i, &hr->headers,
505 &hr->content_buf, &hr->content_len);
506}
507
509{
510 int i, po;
511 Z_HTTP_Request *hr = (Z_HTTP_Request *) odr_malloc(o, sizeof(*hr));
512 const char *buf = o->op->buf;
513 int size = o->op->size;
514 int lspace = 0;
515
516 *hr_p = hr;
517 hr->method = 0;
518 hr->version = 0;
519 hr->path = 0;
520 hr->headers = 0;
521 hr->content_buf = 0;
522 hr->content_len = 0;
523 /* method .. */
524 for (i = 0; buf[i] != ' '; i++)
525 if (i >= size-5 || i > 30)
526 {
527 o->error = OHTTP;
528 return 0;
529 }
530 hr->method = odr_strdupn(o, buf, i);
531 po = ++i;
532 while (i < size && !strchr("\r\n", buf[i]))
533 {
534 if (buf[i] == ' ')
535 lspace = i;
536 i++;
537 }
538 if (!lspace || i >= size || lspace >= size - 5 ||
539 memcmp(buf + lspace + 1, "HTTP/", 5))
540 {
541 o->error = OHTTP;
542 return 0;
543 }
544 hr->path = odr_strdupn(o, buf + po, lspace - po);
545 hr->version = odr_strdupn(o, buf + lspace + 6, i - (lspace + 6));
546 if (i < size-1 && buf[i] == '\r')
547 i++;
548 if (buf[i] != '\n')
549 {
550 o->error = OHTTP;
551 return 0;
552 }
553 /* headers */
554 return decode_headers_content(o, i, &hr->headers,
555 &hr->content_buf, &hr->content_len);
556}
557
558static void dump_http_package(ODR o, const char *buf, size_t len)
559{
560 int i, limit = 8192;
561 for (i = 0; ; i++)
562 {
563 if (i == len)
564 {
565 o->op->stream_write(o, o->op->print, ODR_VISIBLESTRING, buf, i);
566 break;
567 }
568 else if (i >= limit)
569 {
570 o->op->stream_write(o, o->op->print, ODR_VISIBLESTRING, buf, i);
571 odr_printf(o, "(truncated from %ld to %d\n", (long) len, i);
572 break;
573 }
574 else if (buf[i] == 0)
575 {
576 o->op->stream_write(o, o->op->print, ODR_VISIBLESTRING, buf, i);
577 odr_printf(o, "(binary data)\n", (long) len);
578 break;
579 }
580 }
581}
582
584{
585 char sbuf[80];
586 Z_HTTP_Header *h;
587 int top0 = o->op->top;
588
589 yaz_snprintf(sbuf, sizeof(sbuf), "HTTP/%s %d %s\r\n", hr->version,
590 hr->code,
591 z_HTTP_errmsg(hr->code));
592 odr_write(o, sbuf, strlen(sbuf));
593 /* use content_len for Content-Length */
594 yaz_snprintf(sbuf, sizeof(sbuf), "Content-Length: %d\r\n", hr->content_len);
595 odr_write(o, sbuf, strlen(sbuf));
596 for (h = hr->headers; h; h = h->next)
597 {
598 if (yaz_strcasecmp(h->name, "Content-Length")
599 && yaz_strcasecmp(h->name, "Transfer-Encoding"))
600 { /* skip Content-Length if given. content_len rules */
601 odr_write(o, h->name, strlen(h->name));
602 odr_write(o, ": ", 2);
603 odr_write(o, h->value, strlen(h->value));
604 odr_write(o, "\r\n", 2);
605 }
606 }
607 odr_write(o, "\r\n", 2);
608 if (hr->content_buf)
609 odr_write(o, hr->content_buf, hr->content_len);
610 if (o->direction == ODR_PRINT)
611 {
612 odr_printf(o, "-- HTTP response:\n");
613 dump_http_package(o, o->op->buf + top0, o->op->top - top0);
614 odr_printf(o, "--\n");
615 }
616 return 1;
617}
618
620{
621 Z_HTTP_Header *h;
622 char *cp;
623 int top0 = o->op->top;
624
625 if (!hr->method || !hr->path)
626 return 0;
627 odr_write(o, hr->method, strlen(hr->method));
628 odr_write(o, " ", 1);
629 cp = strchr(hr->path, '#');
630 odr_write(o, hr->path, cp ? (cp - hr->path) : strlen(hr->path));
631 odr_write(o, " HTTP/", 6);
632 odr_write(o, hr->version, strlen(hr->version));
633 odr_write(o, "\r\n", 2);
634 if (hr->content_len &&
636 "Content-Length"))
637 {
638 char lstr[60];
639 yaz_snprintf(lstr, sizeof(lstr), "Content-Length: %d\r\n",
640 hr->content_len);
641 odr_write(o, lstr, strlen(lstr));
642 }
643 for (h = hr->headers; h; h = h->next)
644 {
645 if (yaz_strcasecmp(h->name, "Transfer-Encoding") == 0)
646 continue;
647 odr_write(o, h->name, strlen(h->name));
648 odr_write(o, ": ", 2);
649 odr_write(o, h->value, strlen(h->value));
650 odr_write(o, "\r\n", 2);
651 }
652 odr_write(o, "\r\n", 2);
653 if (hr->content_buf)
654 odr_write(o, hr->content_buf, hr->content_len);
655 if (o->direction == ODR_PRINT)
656 {
657 odr_printf(o, "-- HTTP request:\n");
658 dump_http_package(o, o->op->buf + top0, o->op->top - top0);
659 odr_printf(o, "--\n");
660 }
661 return 1;
662}
663
664const char *yaz_check_location(ODR odr, const char *uri, const char *location,
665 int *host_change)
666{
667 if (*location == '/')
668 { /* relative location */
669 char *args = 0;
670 char *nlocation = (char *) odr_malloc(odr, strlen(location)
671 + strlen(uri) + 3);
672 strcpy(nlocation, uri);
673 cs_get_host_args(nlocation, (const char **) &args);
674 if (!args || !*args)
675 args = nlocation + strlen(nlocation);
676 else
677 args--;
678 strcpy(args, location);
679 *host_change = 0;
680 return nlocation;
681 }
682 else
683 {
684 /* we don't check if host is the same as before - yet */
685 *host_change = 1;
686 return location;
687 }
688}
689
690/*
691 * Local variables:
692 * c-basic-offset: 4
693 * c-file-style: "Stroustrup"
694 * indent-tabs-mode: nil
695 * End:
696 * vim: shiftwidth=4 tabstop=8 expandtab
697 */
void yaz_base64encode(const char *in, char *out)
encodes Base64 string
Definition base64.c:16
Header for Base64 utilities.
Private Header for COMSTACK.
int yaz_http_parse_chunks(const char *buf, int len, char *content_buf, int *content_len)
Definition comstack.c:310
void cs_get_host_args(const char *type_and_host, const char **args)
Extracts application arguments from a host or URI specification.
Definition comstack.c:58
Transport-independent communication endpoints for BER and HTTP.
int yaz_decode_http_request(ODR o, Z_HTTP_Request **hr_p)
Definition http.c:508
Z_GDU * z_get_HTTP_Response_details(ODR o, int code, const char *details)
Definition http.c:343
int yaz_encode_http_request(ODR o, Z_HTTP_Request *hr)
Definition http.c:619
void z_HTTP_header_add_basic_auth(ODR o, Z_HTTP_Header **hp, const char *username, const char *password)
Definition http.c:135
int yaz_decode_http_response(ODR o, Z_HTTP_Response **hr_p)
Definition http.c:486
Z_GDU * z_get_HTTP_Request_host_path(ODR odr, const char *host, const char *path)
Definition http.c:224
int yaz_decode_http_response_first(const char *buf, int sz, int *code, const char **version, int *version_len, const char **msg, int *msg_len)
Definition http.c:437
void z_HTTP_header_set(ODR o, Z_HTTP_Header **hp, const char *n, const char *v)
Definition http.c:163
Z_GDU * z_get_HTTP_Response(ODR o, int code)
Definition http.c:349
Z_GDU * z_get_HTTP_Request(ODR o)
Definition http.c:205
Z_GDU * z_get_HTTP_Response_server(ODR o, int code, const char *details, const char *server, const char *server_url)
Definition http.c:294
static int decode_headers_content(ODR o, int off, Z_HTTP_Header **headers, char **content_buf, int *content_len)
Definition http.c:23
int yaz_encode_http_response(ODR o, Z_HTTP_Response *hr)
Definition http.c:583
const char * z_HTTP_errmsg(int code)
Definition http.c:354
const char * yaz_check_location(ODR odr, const char *uri, const char *location, int *host_change)
Definition http.c:664
const char * z_HTTP_header_remove(Z_HTTP_Header **hp, const char *n)
Definition http.c:181
static void dump_http_package(ODR o, const char *buf, size_t len)
Definition http.c:558
const char * z_HTTP_header_lookup(const Z_HTTP_Header *hp, const char *n)
Definition http.c:196
Z_GDU * z_get_HTTP_Request_uri(ODR odr, const char *uri, const char *args, int use_full_uri)
Definition http.c:254
void z_HTTP_header_add(ODR o, Z_HTTP_Header **hp, const char *n, const char *v)
Definition http.c:152
void z_HTTP_header_add_content_type(ODR o, Z_HTTP_Header **hp, const char *content_type, const char *charset)
Definition http.c:115
int yaz_strcasecmp(const char *s1, const char *s2)
ala strcasecmp - no locale
Definition matchstr.c:21
Header for YAZ iconv interface.
char * nmem_printf(NMEM nmem, const char *fmt,...)
formats and prints a string into NMEM allocated memory
Definition nmemsdup.c:145
Internal ODR definitions.
void odr_printf(ODR o, const char *fmt,...)
Definition odr.c:289
#define OHTTP
Definition odr.h:162
#define ODR_VISIBLESTRING
Definition odr.h:89
#define odr_getmem(o)
Definition odr.h:216
struct odr * ODR
Definition odr.h:121
#define ODR_PRINT
Definition odr.h:97
void * odr_malloc(ODR o, size_t size)
Definition odr_mem.c:31
char * odr_strdupn(ODR o, const char *str, size_t n)
Definition odr_mem.c:46
char * odr_strdup(ODR o, const char *str)
Definition odr_mem.c:36
int odr_write(ODR o, const char *buf, int bytes)
Definition odr_mem.c:98
void yaz_snprintf(char *buf, size_t size, const char *fmt,...)
Definition snprintf.c:31
Header for config file reading utilities.
char * buf
Definition odr-priv.h:84
void(*) stream_write(ODR o, void *handle, int type, const char *buf, int len)
Definition odr-priv.h:103
FILE * print
Definition odr-priv.h:114
Definition zgdu.h:68
int which
Definition zgdu.h:69
union Z_GDU::@057307356220171136236350364324260103365227025100 u
char * name
Definition zgdu.h:43
Z_HTTP_Header * next
Definition zgdu.h:45
char * value
Definition zgdu.h:44
Z_HTTP_Header * headers
Definition zgdu.h:52
char * content_buf
Definition zgdu.h:53
char * path
Definition zgdu.h:51
char * version
Definition zgdu.h:50
char * method
Definition zgdu.h:49
int content_len
Definition zgdu.h:54
char * content_buf
Definition zgdu.h:61
Z_HTTP_Header * headers
Definition zgdu.h:60
char * version
Definition zgdu.h:59
int content_len
Definition zgdu.h:62
Definition odr.h:125
struct Odr_private * op
Definition odr.h:132
int error
Definition odr.h:128
int direction
Definition odr.h:126
Header for YAZ iconv interface.
Defines YAZ version.
#define YAZ_VERSION
YAZ version as string.
Definition yaz-version.h:36
Header for the Z_GDU (HTTP or Z39.50 package).
#define Z_GDU_HTTP_Response
Definition zgdu.h:67
#define Z_GDU_HTTP_Request
Definition zgdu.h:66