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