Simplified http.c.

This commit is contained in:
Werner Koch 2010-08-05 18:47:25 +00:00
parent 5b40b56647
commit be622bd268
4 changed files with 88 additions and 248 deletions

View File

@ -1,3 +1,17 @@
2010-08-05 Werner Koch <wk@g10code.com>
* estream.h (es_asprintf, es_vasprintf): Add lost prototyps.
* http.c: Require estream and make HTTP_USE_ESTREAM obsolete. It
make the code unreadable and we require estream anyway for GnuPG.
(http_wait_response): Get use of cookies right.
(send_request): s/xtryasprintf/es_asprintf/ to allow standalone
use of the code.
(insert_escapes, connect_server): s/sprintf/snprintf/.
(parse_response): s/my_read_line/es_read_line/.
(my_read_line): Remove.
(write_server): Use pth_write.
2010-07-26 Werner Koch <wk@g10code.com> 2010-07-26 Werner Koch <wk@g10code.com>
* estream.c (es_func_fp_write) [W32]: Write smaller chunks. * estream.c (es_func_fp_write) [W32]: Write smaller chunks.

View File

@ -352,6 +352,11 @@ int es_vfprintf_unlocked (estream_t ES__RESTRICT stream,
const char *ES__RESTRICT format, va_list ap) const char *ES__RESTRICT format, va_list ap)
_ESTREAM_GCC_A_PRINTF(2,0); _ESTREAM_GCC_A_PRINTF(2,0);
char *es_asprintf (const char *ES__RESTRICT format, ...)
_ESTREAM_GCC_A_PRINTF(1,2);
char *es_vasprintf (const char *ES__RESTRICT format, va_list ap)
_ESTREAM_GCC_A_PRINTF(1,0);
int es_setvbuf (estream_t ES__RESTRICT stream, int es_setvbuf (estream_t ES__RESTRICT stream,
char *ES__RESTRICT buf, int mode, size_t size); char *ES__RESTRICT buf, int mode, size_t size);
void es_setbuf (estream_t ES__RESTRICT stream, char *ES__RESTRICT buf); void es_setbuf (estream_t ES__RESTRICT stream, char *ES__RESTRICT buf);

View File

@ -21,11 +21,13 @@
/* Simple HTTP client implementation. We try to keep the code as /* Simple HTTP client implementation. We try to keep the code as
self-contained as possible. There are some contraints however: self-contained as possible. There are some contraints however:
- estream is required. We now require estream because it provides a
very useful and portable asprintf implementation and the fopencookie
function.
- stpcpy is required - stpcpy is required
- fixme: list other requirements. - fixme: list other requirements.
- With HTTP_USE_ESTREAM defined, all I/O is done through estream.
- With HTTP_USE_GNUTLS support for https is provided (this also - With HTTP_USE_GNUTLS support for https is provided (this also
requires estream). requires estream).
- With HTTP_NO_WSASTARTUP the socket initialization is not done - With HTTP_NO_WSASTARTUP the socket initialization is not done
@ -129,18 +131,13 @@ typedef unsigned long longcounter_t;
# define counter_strtoul(a) strtoul ((a), NULL, 10) # define counter_strtoul(a) strtoul ((a), NULL, 10)
#endif #endif
/* Define a prefix to map stream functions to the estream library. */ #if defined(HTTP_USE_ESTREAM) && defined (__GNUC__)
#ifdef HTTP_USE_ESTREAM # warning HTTP_USE_ESTREAM is an obsolete macro
#define P_ES(a) es_ ## a
#else
#define P_ES(a) a
#endif #endif
#ifndef HTTP_USE_GNUTLS #ifndef HTTP_USE_GNUTLS
typedef void * gnutls_session_t; typedef void * gnutls_session_t;
#endif #endif
#if defined(HTTP_USE_GNUTLS) && !defined(HTTP_USE_ESTREAM)
#error Use of GNUTLS also requires support for Estream
#endif
static gpg_error_t do_parse_uri (parsed_uri_t uri, int only_local_part); static gpg_error_t do_parse_uri (parsed_uri_t uri, int only_local_part);
static int remove_escapes (char *string); static int remove_escapes (char *string);
@ -156,7 +153,6 @@ static int connect_server (const char *server, unsigned short port,
unsigned int flags, const char *srvtag); unsigned int flags, const char *srvtag);
static gpg_error_t write_server (int sock, const char *data, size_t length); static gpg_error_t write_server (int sock, const char *data, size_t length);
#ifdef HTTP_USE_ESTREAM
static ssize_t cookie_read (void *cookie, void *buffer, size_t size); static ssize_t cookie_read (void *cookie, void *buffer, size_t size);
static ssize_t cookie_write (void *cookie, const void *buffer, size_t size); static ssize_t cookie_write (void *cookie, const void *buffer, size_t size);
static int cookie_close (void *cookie); static int cookie_close (void *cookie);
@ -187,8 +183,6 @@ struct cookie_s
}; };
typedef struct cookie_s *cookie_t; typedef struct cookie_s *cookie_t;
#endif /*HTTP_USE_ESTREAM*/
#ifdef HTTP_USE_GNUTLS #ifdef HTTP_USE_GNUTLS
static gpg_error_t (*tls_callback) (http_t, gnutls_session_t, int); static gpg_error_t (*tls_callback) (http_t, gnutls_session_t, int);
#endif /*HTTP_USE_GNUTLS*/ #endif /*HTTP_USE_GNUTLS*/
@ -211,15 +205,10 @@ struct http_context_s
int sock; int sock;
unsigned int in_data:1; unsigned int in_data:1;
unsigned int is_http_0_9:1; unsigned int is_http_0_9:1;
#ifdef HTTP_USE_ESTREAM
estream_t fp_read; estream_t fp_read;
estream_t fp_write; estream_t fp_write;
void *write_cookie; void *write_cookie;
void *read_cookie; void *read_cookie;
#else /*!HTTP_USE_ESTREAM*/
FILE *fp_read;
FILE *fp_write;
#endif /*!HTTP_USE_ESTREAM*/
void *tls_context; void *tls_context;
parsed_uri_t uri; parsed_uri_t uri;
http_req_t req_type; http_req_t req_type;
@ -375,9 +364,9 @@ http_open (http_t *r_hd, http_req_t reqtype, const char *url,
if (!hd->fp_read && !hd->fp_write && hd->sock != -1) if (!hd->fp_read && !hd->fp_write && hd->sock != -1)
sock_close (hd->sock); sock_close (hd->sock);
if (hd->fp_read) if (hd->fp_read)
P_ES(fclose) (hd->fp_read); es_fclose (hd->fp_read);
if (hd->fp_write) if (hd->fp_write)
P_ES(fclose) (hd->fp_write); es_fclose (hd->fp_write);
http_release_parsed_uri (hd->uri); http_release_parsed_uri (hd->uri);
xfree (hd); xfree (hd);
} }
@ -392,17 +381,12 @@ http_start_data (http_t hd)
{ {
if (!hd->in_data) if (!hd->in_data)
{ {
#ifdef HTTP_USE_ESTREAM
es_fputs ("\r\n", hd->fp_write); es_fputs ("\r\n", hd->fp_write);
es_fflush (hd->fp_write); es_fflush (hd->fp_write);
#else
fflush (hd->fp_write);
write_server (hd->sock, "\r\n", 2);
#endif
hd->in_data = 1; hd->in_data = 1;
} }
else else
P_ES(fflush) (hd->fp_write); es_fflush (hd->fp_write);
} }
@ -410,42 +394,21 @@ gpg_error_t
http_wait_response (http_t hd) http_wait_response (http_t hd)
{ {
gpg_error_t err; gpg_error_t err;
cookie_t cookie;
/* Make sure that we are in the data. */ /* Make sure that we are in the data. */
http_start_data (hd); http_start_data (hd);
/* We dup the socket, to cope with the fact that fclose closes the /* Close the write stream but keep the socket open. */
underlying socket. In TLS mode we don't do that because we can't cookie = hd->write_cookie;
close the socket gnutls is working on; instead we make sure that if (!cookie)
the fclose won't close the socket in this case. */ return gpg_error (GPG_ERR_INTERNAL);
#ifdef HTTP_USE_ESTREAM
if (hd->write_cookie) cookie->keep_socket = 1;
{ es_fclose (hd->fp_write);
/* The write cookie is only set in the TLS case. */
cookie_t cookie = hd->write_cookie;
cookie->keep_socket = 1;
}
else
#endif /*HTTP_USE_ESTREAM*/
{
#ifdef HAVE_W32_SYSTEM
HANDLE handle = (HANDLE)hd->sock;
if (!DuplicateHandle (GetCurrentProcess(), handle,
GetCurrentProcess(), &handle, 0,
TRUE, DUPLICATE_SAME_ACCESS ))
return gpg_error_from_syserror ();
hd->sock = (int)handle;
#else
hd->sock = dup (hd->sock);
#endif
if (hd->sock == -1)
return gpg_error_from_syserror ();
}
P_ES(fclose) (hd->fp_write);
hd->fp_write = NULL; hd->fp_write = NULL;
#ifdef HTTP_USE_ESTREAM /* The close has released the cookie and thus we better set it to NULL. */
hd->write_cookie = NULL; hd->write_cookie = NULL;
#endif
/* Shutdown one end of the socket is desired. As per HTTP/1.0 this /* Shutdown one end of the socket is desired. As per HTTP/1.0 this
is not required but some very old servers (e.g. the original pksd is not required but some very old servers (e.g. the original pksd
@ -454,29 +417,22 @@ http_wait_response (http_t hd)
shutdown (hd->sock, 1); shutdown (hd->sock, 1);
hd->in_data = 0; hd->in_data = 0;
#ifdef HTTP_USE_ESTREAM /* Create a new cookie and a stream for reading. */
{ cookie = xtrycalloc (1, sizeof *cookie);
cookie_t cookie; if (!cookie)
cookie = xtrycalloc (1, sizeof *cookie);
if (!cookie)
return gpg_error_from_syserror ();
cookie->fd = hd->sock;
if (hd->uri->use_tls)
cookie->tls_session = hd->tls_context;
hd->fp_read = es_fopencookie (cookie, "r", cookie_functions);
if (!hd->fp_read)
{
xfree (cookie);
return gpg_error_from_syserror ();
}
}
#else /*!HTTP_USE_ESTREAM*/
hd->fp_read = fdopen (hd->sock, "r");
if (!hd->fp_read)
return gpg_error_from_syserror (); return gpg_error_from_syserror ();
#endif /*!HTTP_USE_ESTREAM*/ cookie->fd = hd->sock;
if (hd->uri->use_tls)
cookie->tls_session = hd->tls_context;
hd->read_cookie = cookie;
hd->fp_read = es_fopencookie (cookie, "r", cookie_functions);
if (!hd->fp_read)
{
xfree (cookie);
hd->read_cookie = NULL;
return gpg_error_from_syserror ();
}
err = parse_response (hd); err = parse_response (hd);
return err; return err;
@ -515,9 +471,9 @@ http_close (http_t hd, int keep_read_stream)
if (!hd->fp_read && !hd->fp_write && hd->sock != -1) if (!hd->fp_read && !hd->fp_write && hd->sock != -1)
sock_close (hd->sock); sock_close (hd->sock);
if (hd->fp_read && !keep_read_stream) if (hd->fp_read && !keep_read_stream)
P_ES(fclose) (hd->fp_read); es_fclose (hd->fp_read);
if (hd->fp_write) if (hd->fp_write)
P_ES(fclose) (hd->fp_write); es_fclose (hd->fp_write);
http_release_parsed_uri (hd->uri); http_release_parsed_uri (hd->uri);
while (hd->headers) while (hd->headers)
{ {
@ -531,29 +487,18 @@ http_close (http_t hd, int keep_read_stream)
} }
#ifdef HTTP_USE_ESTREAM
estream_t estream_t
http_get_read_ptr (http_t hd) http_get_read_ptr (http_t hd)
{ {
return hd?hd->fp_read:NULL; return hd?hd->fp_read:NULL;
} }
estream_t estream_t
http_get_write_ptr (http_t hd) http_get_write_ptr (http_t hd)
{ {
return hd?hd->fp_write:NULL; return hd?hd->fp_write:NULL;
} }
#else /*!HTTP_USE_ESTREAM*/
FILE *
http_get_read_ptr (http_t hd)
{
return hd?hd->fp_read:NULL;
}
FILE *
http_get_write_ptr (http_t hd)
{
return hd?hd->fp_write:NULL;
}
#endif /*!HTTP_USE_ESTREAM*/
unsigned int unsigned int
http_get_status_code (http_t hd) http_get_status_code (http_t hd)
{ {
@ -794,7 +739,7 @@ insert_escapes (char *buffer, const char *string,
{ {
if (buffer) if (buffer)
{ {
sprintf (buffer, "%%%02X", *s); snprintf (buffer, 4, "%%%02X", *s);
buffer += 3; buffer += 3;
} }
n += 3; n += 3;
@ -1017,7 +962,7 @@ send_request (http_t hd, const char *auth,
if (http_proxy && *http_proxy) if (http_proxy && *http_proxy)
{ {
request = xtryasprintf request = es_asprintf
("%s http://%s:%hu%s%s HTTP/1.0\r\n%s%s", ("%s http://%s:%hu%s%s HTTP/1.0\r\n%s%s",
hd->req_type == HTTP_REQ_GET ? "GET" : hd->req_type == HTTP_REQ_GET ? "GET" :
hd->req_type == HTTP_REQ_HEAD ? "HEAD" : hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
@ -1035,7 +980,7 @@ send_request (http_t hd, const char *auth,
else else
snprintf (portstr, sizeof portstr, ":%u", port); snprintf (portstr, sizeof portstr, ":%u", port);
request = xtryasprintf request = es_asprintf
("%s %s%s HTTP/1.0\r\nHost: %s%s\r\n%s", ("%s %s%s HTTP/1.0\r\nHost: %s%s\r\n%s",
hd->req_type == HTTP_REQ_GET ? "GET" : hd->req_type == HTTP_REQ_GET ? "GET" :
hd->req_type == HTTP_REQ_HEAD ? "HEAD" : hd->req_type == HTTP_REQ_HEAD ? "HEAD" :
@ -1053,7 +998,6 @@ send_request (http_t hd, const char *auth,
} }
#ifdef HTTP_USE_ESTREAM
/* First setup estream so that we can write even the first line /* First setup estream so that we can write even the first line
using estream. This is also required for the sake of gnutls. */ using estream. This is also required for the sake of gnutls. */
{ {
@ -1066,16 +1010,15 @@ send_request (http_t hd, const char *auth,
goto leave; goto leave;
} }
cookie->fd = hd->sock; cookie->fd = hd->sock;
hd->write_cookie = cookie;
if (hd->uri->use_tls) if (hd->uri->use_tls)
{ cookie->tls_session = tls_session;
cookie->tls_session = tls_session;
hd->write_cookie = cookie;
}
hd->fp_write = es_fopencookie (cookie, "w", cookie_functions); hd->fp_write = es_fopencookie (cookie, "w", cookie_functions);
if (!hd->fp_write) if (!hd->fp_write)
{ {
xfree (cookie); xfree (cookie);
hd->write_cookie = NULL;
err = gpg_error_from_syserror (); err = gpg_error_from_syserror ();
} }
else if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write)) else if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write))
@ -1083,45 +1026,22 @@ send_request (http_t hd, const char *auth,
else else
err = 0; err = 0;
if(err==0)
for(;headers;headers=headers->next)
{
if ((es_fputs (headers->d, hd->fp_write) || es_fflush (hd->fp_write))
|| (es_fputs("\r\n",hd->fp_write) || es_fflush(hd->fp_write)))
{
err = gpg_error_from_syserror ();
break;
}
}
}
leave:
#else /*!HTTP_USE_ESTREAM*/
/* We send out the start of the request through our own send
function and only then assign a stdio stream. This allows for
better error reporting that through standard stdio means. */
err = write_server (hd->sock, request, strlen (request));
if (!err)
for (;headers;headers=headers->next)
{
err = write_server (hd->sock, headers->d, strlen(headers->d));
if (err)
break;
err = write_server (hd->sock, "\r\n", 2);
if (err)
break;
}
if (!err) if (!err)
{ {
hd->fp_write = fdopen (hd->sock, "w"); for (;headers; headers=headers->next)
if (!hd->fp_write) {
err = gpg_error_from_syserror (); if ((es_fputs (headers->d, hd->fp_write) || es_fflush (hd->fp_write))
|| (es_fputs("\r\n",hd->fp_write) || es_fflush(hd->fp_write)))
{
err = gpg_error_from_syserror ();
break;
}
}
} }
}
#endif /*!HTTP_USE_ESTREAM*/
leave:
xfree (request); es_free (request);
xfree (authstr); xfree (authstr);
xfree (proxy_authstr); xfree (proxy_authstr);
@ -1181,97 +1101,6 @@ build_rel_path (parsed_uri_t uri)
} }
/*
Same as fgets() but if the buffer is too short a larger one will be
allocated up to some limit *MAX_LENGTH. A line is considered a
byte stream ending in a LF. Returns the length of the line. EOF is
indicated by a line of length zero. The last LF may be missing due
to an EOF. If MAX_LENGTH is zero on return, the line has been
truncated. If the returned buffer is NULL, not enough memory was
enable to increase it, the return value will also be 0 and some
bytes might have been lost which should be no problem becuase
out-of-memory is pretty fatal for most applications.
If a line has been truncated, the file pointer is internally moved
forward to the end of the line.
Note: The returned buffer is allocated with enough extra space to
append a CR,LF,Nul
*/
static size_t
my_read_line (
#ifdef HTTP_USE_ESTREAM
estream_t fp,
#else
FILE *fp,
#endif
char **addr_of_buffer,
size_t *length_of_buffer, size_t *max_length)
{
int c;
char *buffer = *addr_of_buffer;
size_t length = *length_of_buffer;
size_t nbytes = 0;
size_t maxlen = *max_length;
char *p;
if (!buffer) /* Must allocate a new buffer. */
{
length = 256;
buffer = xtrymalloc (length);
*addr_of_buffer = buffer;
if (!buffer)
{
*length_of_buffer = *max_length = 0;
return 0;
}
*length_of_buffer = length;
}
length -= 3; /* Reserve 3 bytes (cr,lf,eol). */
p = buffer;
while ((c = P_ES(getc) (fp)) != EOF)
{
if (nbytes == length) /* Increase the buffer. */
{
if (length > maxlen) /* Limit reached. */
{
/* Skip the rest of the line. */
while (c != '\n' && (c = P_ES(getc) (fp)) != EOF)
;
*p++ = '\n'; /* Always append a LF (we reserved some space). */
nbytes++;
*max_length = 0; /* Indicate truncation */
break; /*(the while loop)*/
}
length += 3; /* Adjust for the reserved bytes. */
length += length < 1024 ? 256 : 1024;
*addr_of_buffer = xtryrealloc (buffer, length);
if (!*addr_of_buffer)
{
int save_errno = errno;
xfree (buffer);
*length_of_buffer = *max_length = 0;
gpg_err_set_errno (save_errno);
return 0;
}
buffer = *addr_of_buffer;
*length_of_buffer = length;
length -= 3; /* And re-adjust for the reservation. */
p = buffer + nbytes;
}
*p++ = c;
nbytes++;
if (c == '\n')
break;
}
*p = 0; /* Make sure the line is a string. */
return nbytes;
}
/* Transform a header name into a standard capitalized format; e.g. /* Transform a header name into a standard capitalized format; e.g.
"Content-Type". Conversion stops at the colon. As usual we don't "Content-Type". Conversion stops at the colon. As usual we don't
use the localized versions of ctype.h. */ use the localized versions of ctype.h. */
@ -1418,7 +1247,7 @@ parse_response (http_t hd)
do do
{ {
maxlen = MAX_LINELEN; maxlen = MAX_LINELEN;
len = my_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen); len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
line = hd->buffer; line = hd->buffer;
if (!line) if (!line)
return gpg_error_from_syserror (); /* Out of core. */ return gpg_error_from_syserror (); /* Out of core. */
@ -1462,7 +1291,7 @@ parse_response (http_t hd)
do do
{ {
maxlen = MAX_LINELEN; maxlen = MAX_LINELEN;
len = my_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen); len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen);
line = hd->buffer; line = hd->buffer;
if (!line) if (!line)
return gpg_error_from_syserror (); /* Out of core. */ return gpg_error_from_syserror (); /* Out of core. */
@ -1664,7 +1493,7 @@ connect_server (const char *server, unsigned short port,
struct addrinfo hints, *res, *ai; struct addrinfo hints, *res, *ai;
char portstr[35]; char portstr[35];
sprintf (portstr, "%hu", port); snprintf (portstr, sizeof portstr, "%hu", port);
memset (&hints, 0, sizeof (hints)); memset (&hints, 0, sizeof (hints));
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
if (getaddrinfo (serverlist[srv].target, portstr, &hints, &res)) if (getaddrinfo (serverlist[srv].target, portstr, &hints, &res))
@ -1778,22 +1607,25 @@ static gpg_error_t
write_server (int sock, const char *data, size_t length) write_server (int sock, const char *data, size_t length)
{ {
int nleft; int nleft;
int nwritten;
/* FIXME: We would better use pth I/O functions. */ /* FIXME: We would better use pth I/O functions. */
nleft = length; nleft = length;
while (nleft > 0) while (nleft > 0)
{ {
#ifdef HAVE_W32_SYSTEM #if defined(HAVE_W32_SYSTEM) && !defined(HAVE_PTH)
int nwritten;
nwritten = send (sock, data, nleft, 0); nwritten = send (sock, data, nleft, 0);
if ( nwritten == SOCKET_ERROR ) if ( nwritten == SOCKET_ERROR )
{ {
log_info ("network write failed: ec=%d\n", (int)WSAGetLastError ()); log_info ("network write failed: ec=%d\n", (int)WSAGetLastError ());
return gpg_error (GPG_ERR_NETWORK); return gpg_error (GPG_ERR_NETWORK);
} }
#else /*!HAVE_W32_SYSTEM*/ #else /*!HAVE_W32_SYSTEM || HAVE_PTH*/
int nwritten = write (sock, data, nleft); # ifdef HAVE_PTH
nwritten = pth_write (sock, data, nleft);
# else
nwritten = write (sock, data, nleft);
# endif
if (nwritten == -1) if (nwritten == -1)
{ {
if (errno == EINTR) if (errno == EINTR)
@ -1810,7 +1642,7 @@ write_server (int sock, const char *data, size_t length)
log_info ("network write failed: %s\n", strerror (errno)); log_info ("network write failed: %s\n", strerror (errno));
return gpg_error_from_syserror (); return gpg_error_from_syserror ();
} }
#endif /*!HAVE_W32_SYSTEM*/ #endif /*!HAVE_W32_SYSTEM || HAVE_PTH*/
nleft -= nwritten; nleft -= nwritten;
data += nwritten; data += nwritten;
} }
@ -1820,7 +1652,6 @@ write_server (int sock, const char *data, size_t length)
#ifdef HTTP_USE_ESTREAM
/* Read handler for estream. */ /* Read handler for estream. */
static ssize_t static ssize_t
cookie_read (void *cookie, void *buffer, size_t size) cookie_read (void *cookie, void *buffer, size_t size)
@ -1961,7 +1792,6 @@ cookie_close (void *cookie)
xfree (c); xfree (c);
return 0; return 0;
} }
#endif /*HTTP_USE_ESTREAM*/
@ -1999,9 +1829,7 @@ main (int argc, char **argv)
#endif /*HTTP_USE_GNUTLS*/ #endif /*HTTP_USE_GNUTLS*/
header_t hdr; header_t hdr;
#ifdef HTTP_USE_ESTREAM
es_init (); es_init ();
#endif
log_set_prefix ("http-test", 1 | 4); log_set_prefix ("http-test", 1 | 4);
if (argc == 1) if (argc == 1)
{ {
@ -2100,7 +1928,7 @@ main (int argc, char **argv)
switch (http_get_status_code (hd)) switch (http_get_status_code (hd))
{ {
case 200: case 200:
while ((c = P_ES(getc) (http_get_read_ptr (hd))) != EOF) while ((c = es_getc (http_get_read_ptr (hd))) != EOF)
putchar (c); putchar (c);
break; break;
case 301: case 301:

View File

@ -21,9 +21,7 @@
#define GNUPG_COMMON_HTTP_H #define GNUPG_COMMON_HTTP_H
#include <gpg-error.h> #include <gpg-error.h>
#ifdef HTTP_USE_ESTREAM
#include "../common/estream.h" #include "../common/estream.h"
#endif
struct uri_tuple_s { struct uri_tuple_s {
struct uri_tuple_s *next; struct uri_tuple_s *next;
@ -100,13 +98,8 @@ gpg_error_t http_open_document (http_t *r_hd,
const char *srvtag, const char *srvtag,
strlist_t headers); strlist_t headers);
#ifdef HTTP_USE_ESTREAM
estream_t http_get_read_ptr (http_t hd); estream_t http_get_read_ptr (http_t hd);
estream_t http_get_write_ptr (http_t hd); estream_t http_get_write_ptr (http_t hd);
#else /*!HTTP_USE_ESTREAM*/
FILE *http_get_read_ptr (http_t hd);
FILE *http_get_write_ptr (http_t hd);
#endif /*!HTTP_USE_ESTREAM*/
unsigned int http_get_status_code (http_t hd); unsigned int http_get_status_code (http_t hd);
const char *http_get_header (http_t hd, const char *name); const char *http_get_header (http_t hd, const char *name);