aboutsummaryrefslogtreecommitdiffstats
path: root/util/http.c
diff options
context:
space:
mode:
authorRepo Admin <[email protected]>2002-10-19 07:55:27 +0000
committerRepo Admin <[email protected]>2002-10-19 07:55:27 +0000
commit82a17c9fb3d64ccdd474c3bedf564368f77e84a4 (patch)
tree0c01ee8cea5f6f77e830955c6b97024752740a2b /util/http.c
parentBumped version number for cvs version (diff)
downloadgnupg-82a17c9fb3d64ccdd474c3bedf564368f77e84a4.tar.gz
gnupg-82a17c9fb3d64ccdd474c3bedf564368f77e84a4.zip
This commit was manufactured by cvs2svn to create branch
'GNUPG-1-9-BRANCH'.
Diffstat (limited to '')
-rw-r--r--util/http.c903
1 files changed, 0 insertions, 903 deletions
diff --git a/util/http.c b/util/http.c
deleted file mode 100644
index fa3d512e9..000000000
--- a/util/http.c
+++ /dev/null
@@ -1,903 +0,0 @@
-/* http.c - HTTP protocol handler
- * Copyright (C) 1999, 2001 Free Software Foundation, Inc.
- *
- * This file is part of GnuPG.
- *
- * GnuPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * GnuPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-
-#ifdef __MINGW32__
- #include <windows.h>
-#else
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/time.h>
- #include <time.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <netdb.h>
-#endif
-
-#include "util.h"
-#include "iobuf.h"
-#include "i18n.h"
-
-#include "http.h"
-
-#ifdef __riscos__
- #define HTTP_PROXY_ENV "GnuPG$HttpProxy"
- #define HTTP_PROXY_ENV_PRINTABLE "<GnuPG$HttpProxy>"
-#else
- #define HTTP_PROXY_ENV "http_proxy"
- #define HTTP_PROXY_ENV_PRINTABLE "$http_proxy"
-#endif
-
-#ifdef __MINGW32__
-#define sock_close(a) closesocket(a)
-#else
-#define sock_close(a) close(a)
-#endif
-
-#define MAX_LINELEN 20000 /* max. length of a HTTP line */
-#define VALID_URI_CHARS "abcdefghijklmnopqrstuvwxyz" \
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
- "01234567890@" \
- "!\"#$%&'()*+,-./:;<=>?[\\]^_{|}~"
-
-#ifndef EAGAIN
- #define EAGAIN EWOULDBLOCK
-#endif
-
-static int parse_uri( PARSED_URI *ret_uri, const char *uri );
-static void release_parsed_uri( PARSED_URI uri );
-static int do_parse_uri( PARSED_URI uri, int only_local_part );
-static int remove_escapes( byte *string );
-static int insert_escapes( byte *buffer, const byte *string,
- const byte *special );
-static URI_TUPLE parse_tuple( byte *string );
-static int send_request( HTTP_HD hd );
-static byte *build_rel_path( PARSED_URI uri );
-static int parse_response( HTTP_HD hd );
-
-static int connect_server( const char *server, ushort port );
-static int write_server( int sock, const char *data, size_t length );
-
-#ifdef __MINGW32__
-static void
-deinit_sockets (void)
-{
- WSACleanup();
-}
-
-static void
-init_sockets (void)
-{
- static int initialized;
- static WSADATA wsdata;
-
- if (initialized)
- return;
-
- if( WSAStartup( 0x0101, &wsdata ) ) {
- log_error ("error initializing socket library: ec=%d\n",
- (int)WSAGetLastError () );
- return;
- }
- if( wsdata.wVersion < 0x0001 ) {
- log_error ("socket library version is %x.%x - but 1.1 needed\n",
- LOBYTE(wsdata.wVersion), HIBYTE(wsdata.wVersion));
- WSACleanup();
- return;
- }
- atexit ( deinit_sockets );
- initialized = 1;
-}
-#endif /*__MINGW32__*/
-
-
-int
-http_open( HTTP_HD hd, HTTP_REQ_TYPE reqtype, const char *url,
- unsigned int flags )
-{
- int rc;
-
- if( !(reqtype == HTTP_REQ_GET || reqtype == HTTP_REQ_POST) )
- return G10ERR_INV_ARG;
-
- /* initialize the handle */
- memset( hd, 0, sizeof *hd );
- hd->sock = -1;
- hd->initialized = 1;
- hd->req_type = reqtype;
- hd->flags = flags;
-
- rc = parse_uri( &hd->uri, url );
- if( !rc ) {
- rc = send_request( hd );
- if( !rc ) {
- hd->fp_write = iobuf_sockopen( hd->sock , "w" );
- if( hd->fp_write )
- return 0;
- rc = G10ERR_GENERAL;
- }
- }
-
- if( !hd->fp_read && !hd->fp_write && hd->sock != -1 )
- sock_close( hd->sock );
- iobuf_close( hd->fp_read );
- iobuf_close( hd->fp_write);
- release_parsed_uri( hd->uri );
- hd->initialized = 0;
-
- return rc;
-}
-
-
-void
-http_start_data( HTTP_HD hd )
-{
- iobuf_flush ( hd->fp_write );
- if( !hd->in_data ) {
- write_server (hd->sock, "\r\n", 2);
- hd->in_data = 1;
- }
-}
-
-
-int
-http_wait_response( HTTP_HD hd, unsigned int *ret_status )
-{
- int rc;
-
- http_start_data( hd ); /* make sure that we are in the data */
-
- #if 0
- hd->sock = dup( hd->sock );
- if( hd->sock == -1 )
- return G10ERR_GENERAL;
- #endif
- iobuf_ioctl (hd->fp_write, 1, 1, NULL); /* keep the socket open */
- iobuf_close (hd->fp_write);
- hd->fp_write = NULL;
- if ( !(hd->flags & HTTP_FLAG_NO_SHUTDOWN) )
- shutdown( hd->sock, 1 );
- hd->in_data = 0;
-
- hd->fp_read = iobuf_sockopen( hd->sock , "r" );
- if( !hd->fp_read )
- return G10ERR_GENERAL;
-
- rc = parse_response( hd );
- if( !rc && ret_status )
- *ret_status = hd->status_code;
-
- return rc;
-}
-
-
-int
-http_open_document( HTTP_HD hd, const char *document, unsigned int flags )
-{
- int rc;
-
- rc = http_open( hd, HTTP_REQ_GET, document, flags );
- if( rc )
- return rc;
-
- rc = http_wait_response( hd, NULL );
- if( rc )
- http_close( hd );
-
- return rc;
-}
-
-
-
-
-void
-http_close( HTTP_HD hd )
-{
- if( !hd || !hd->initialized )
- return;
- if( !hd->fp_read && !hd->fp_write && hd->sock != -1 )
- sock_close( hd->sock );
- iobuf_close( hd->fp_read );
- iobuf_close( hd->fp_write );
- release_parsed_uri( hd->uri );
- m_free( hd->buffer );
- hd->initialized = 0;
-}
-
-
-
-/****************
- * Parse an URI and put the result into the newly allocated ret_uri.
- * The caller must always use release_parsed_uri to releases the
- * resources (even on an error).
- */
-static int
-parse_uri( PARSED_URI *ret_uri, const char *uri )
-{
- *ret_uri = m_alloc_clear( sizeof(**ret_uri) + strlen(uri) );
- strcpy( (*ret_uri)->buffer, uri );
- return do_parse_uri( *ret_uri, 0 );
-}
-
-static void
-release_parsed_uri( PARSED_URI uri )
-{
- if( uri )
- {
- URI_TUPLE r, r2;
-
- for( r = uri->query; r; r = r2 ) {
- r2 = r->next;
- m_free( r );
- }
- m_free( uri );
- }
-}
-
-static int
-do_parse_uri( PARSED_URI uri, int only_local_part )
-{
- URI_TUPLE *tail;
- char *p, *p2, *p3;
- int n;
-
- p = uri->buffer;
- n = strlen( uri->buffer );
- /* initialize all fields to an empty string or an empty list */
- uri->scheme = uri->host = uri->path = p + n;
- uri->port = 0;
- uri->params = uri->query = NULL;
-
- /* a quick validity check */
- if( strspn( p, VALID_URI_CHARS) != n )
- return G10ERR_BAD_URI; /* invalid characters found */
-
- if( !only_local_part ) {
- /* find the scheme */
- if( !(p2 = strchr( p, ':' ) ) || p2 == p )
- return G10ERR_BAD_URI; /* No scheme */
- *p2++ = 0;
- strlwr( p );
- uri->scheme = p;
- uri->port = 80;
- if( !strcmp( uri->scheme, "http" ) )
- ;
- else if( !strcmp( uri->scheme, "x-hkp" ) ) /* same as HTTP */
- uri->port = 11371;
- else
- return G10ERR_INVALID_URI; /* Unsupported scheme */
-
- p = p2;
-
- /* find the hostname */
- if( *p != '/' )
- return G10ERR_INVALID_URI; /* does not start with a slash */
-
- p++;
- if( *p == '/' ) { /* there seems to be a hostname */
- p++;
- if( (p2 = strchr(p, '/')) )
- *p2++ = 0;
- strlwr( p );
- uri->host = p;
- if( (p3=strchr( p, ':' )) ) {
- *p3++ = 0;
- uri->port = atoi( p3 );
- }
-
- uri->host = p;
- if( (n = remove_escapes( uri->host )) < 0 )
- return G10ERR_BAD_URI;
- if( n != strlen( p ) )
- return G10ERR_BAD_URI; /* hostname with a Nul in it */
- p = p2 ? p2 : NULL;
- }
- } /* end global URI part */
-
- /* parse the pathname part */
- if( !p || !*p ) /* we don't have a path */
- return 0; /* and this is okay */
-
- /* todo: here we have to check params */
-
- /* do we have a query part */
- if( (p2 = strchr( p, '?' )) )
- *p2++ = 0;
-
- uri->path = p;
- if( (n = remove_escapes( p )) < 0 )
- return G10ERR_BAD_URI;
- if( n != strlen( p ) )
- return G10ERR_BAD_URI; /* path with a Nul in it */
- p = p2 ? p2 : NULL;
-
- if( !p || !*p ) /* we don't have a query string */
- return 0; /* okay */
-
- /* now parse the query string */
- tail = &uri->query;
- for(;;) {
- URI_TUPLE elem;
-
- if( (p2 = strchr( p, '&' )) )
- *p2++ = 0;
- if( !(elem = parse_tuple( p )) )
- return G10ERR_BAD_URI;
- *tail = elem;
- tail = &elem->next;
-
- if( !p2 )
- break; /* ready */
- p = p2;
- }
-
- return 0;
-}
-
-
-
-/****************
- * Remove all %xx escapes; this is done inplace.
- * Returns: new length of the string.
- */
-static int
-remove_escapes( byte *string )
-{
- int n = 0;
- byte *p, *s;
-
- for(p=s=string; *s ; s++ ) {
- if( *s == '%' ) {
- if( s[1] && s[2] && isxdigit(s[1]) && isxdigit(s[2]) ) {
- s++;
- *p = *s >= '0' && *s <= '9' ? *s - '0' :
- *s >= 'A' && *s <= 'F' ? *s - 'A' + 10 : *s - 'a' + 10 ;
- *p <<= 4;
- s++;
- *p |= *s >= '0' && *s <= '9' ? *s - '0' :
- *s >= 'A' && *s <= 'F' ? *s - 'A' + 10 : *s - 'a' + 10 ;
- p++;
- n++;
- }
- else {
- *p++ = *s++;
- if( *s )
- *p++ = *s++;
- if( *s )
- *p++ = *s++;
- if( *s )
- *p = 0;
- return -1; /* bad URI */
- }
- }
- else
- {
- *p++ = *s;
- n++;
- }
- }
- *p = 0; /* always keep a string terminator */
- return n;
-}
-
-
-static int
-insert_escapes( byte *buffer, const byte *string, const byte *special )
-{
- int n = 0;
-
- for( ; *string; string++ ) {
- if( strchr( VALID_URI_CHARS, *string )
- && !strchr( special, *string ) ) {
- if( buffer )
- *buffer++ = *string;
- n++;
- }
- else {
- if( buffer ) {
- sprintf( buffer, "%02X", *string );
- buffer += 3;
- }
- n += 3;
- }
- }
- return n;
-}
-
-
-
-
-
-static URI_TUPLE
-parse_tuple( byte *string )
-{
- byte *p = string;
- byte *p2;
- int n;
- URI_TUPLE tuple;
-
- if( (p2 = strchr( p, '=' )) )
- *p2++ = 0;
- if( (n = remove_escapes( p )) < 0 )
- return NULL; /* bad URI */
- if( n != strlen( p ) )
- return NULL; /* name with a Nul in it */
- tuple = m_alloc_clear( sizeof *tuple );
- tuple->name = p;
- if( !p2 ) {
- /* we have only the name, so we assume an empty value string */
- tuple->value = p + strlen(p);
- tuple->valuelen = 0;
- }
- else { /* name and value */
- if( (n = remove_escapes( p2 )) < 0 ) {
- m_free( tuple );
- return NULL; /* bad URI */
- }
- tuple->value = p2;
- tuple->valuelen = n;
- }
- return tuple;
-}
-
-
-/****************
- * Send a HTTP request to the server
- * Returns 0 if the request was successful
- */
-static int
-send_request( HTTP_HD hd )
-{
- const byte *server;
- byte *request, *p;
- ushort port;
- int rc;
- const char *http_proxy = NULL;
-
- server = *hd->uri->host? hd->uri->host : "localhost";
- port = hd->uri->port? hd->uri->port : 80;
-
- if( (hd->flags & HTTP_FLAG_TRY_PROXY)
- && (http_proxy = getenv( HTTP_PROXY_ENV )) ) {
- PARSED_URI uri;
-
- rc = parse_uri( &uri, http_proxy );
- if (rc) {
- log_error("invalid " HTTP_PROXY_ENV_PRINTABLE ": %s\n",
- g10_errstr(rc));
- release_parsed_uri( uri );
- return G10ERR_NETWORK;
- }
- hd->sock = connect_server( *uri->host? uri->host : "localhost",
- uri->port? uri->port : 80 );
- release_parsed_uri( uri );
- }
- else
- hd->sock = connect_server( server, port );
-
- if( hd->sock == -1 )
- return G10ERR_NETWORK;
-
- p = build_rel_path( hd->uri );
- request = m_alloc( strlen(server) + strlen(p) + 50 );
- if( http_proxy ) {
- sprintf( request, "%s http://%s:%hu%s%s HTTP/1.0\r\n",
- hd->req_type == HTTP_REQ_GET ? "GET" :
- hd->req_type == HTTP_REQ_HEAD? "HEAD":
- hd->req_type == HTTP_REQ_POST? "POST": "OOPS",
- server, port, *p == '/'? "":"/", p );
- }
- else {
- sprintf( request, "%s %s%s HTTP/1.0\r\n",
- hd->req_type == HTTP_REQ_GET ? "GET" :
- hd->req_type == HTTP_REQ_HEAD? "HEAD":
- hd->req_type == HTTP_REQ_POST? "POST": "OOPS",
- *p == '/'? "":"/", p );
- }
- m_free(p);
-
- rc = write_server( hd->sock, request, strlen(request) );
- m_free( request );
-
- return rc;
-}
-
-
-
-
-/****************
- * Build the relative path from the parsed URI.
- * Minimal implementation.
- */
-static byte*
-build_rel_path( PARSED_URI uri )
-{
- URI_TUPLE r;
- byte *rel_path, *p;
- int n;
-
- /* count the needed space */
- n = insert_escapes( NULL, uri->path, "%;?&" );
- /* todo: build params */
- for( r=uri->query; r; r = r->next ) {
- n++; /* '?'/'&' */
- n += insert_escapes( NULL, r->name, "%;?&=" );
- n++; /* '='*/
- n += insert_escapes( NULL, r->value, "%;?&=" );
- }
- n++;
-
- /* now allocate and copy */
- p = rel_path = m_alloc( n );
- n = insert_escapes( p, uri->path, "%;?&" );
- p += n;
- /* todo: add params */
- for( r=uri->query; r; r = r->next ) {
- *p++ = r == uri->query? '?':'&';
- n = insert_escapes( p, r->name, "%;?&=" );
- p += n;
- *p++ = '=';
- /* todo: use valuelen */
- n = insert_escapes( p, r->value, "%;?&=" );
- p += n;
- }
- *p = 0;
- return rel_path;
-}
-
-
-
-/***********************
- * Parse the response from a server.
- * Returns: errorcode and sets some fileds in the handle
- */
-static int
-parse_response( HTTP_HD hd )
-{
- byte *line, *p, *p2;
- unsigned maxlen, len;
-
- /* Wait for the status line */
- do {
- maxlen = MAX_LINELEN;
- len = iobuf_read_line( hd->fp_read, &hd->buffer,
- &hd->buffer_size, &maxlen );
- line = hd->buffer;
- if( !maxlen )
- return -1; /* line has been truncated */
- if( !len )
- return -1; /* eof */
- } while( !*line );
-
- if( (p = strchr( line, '/')) )
- *p++ = 0;
- if( !p || strcmp( line, "HTTP" ) )
- return 0; /* assume http 0.9 */
-
- if( (p2 = strpbrk( p, " \t" ) ) ) {
- *p2++ = 0;
- p2 += strspn( p2, " \t" );
- }
- if( !p2 )
- return 0; /* assume http 0.9 */
- p = p2;
- /* todo: add HTTP version number check here */
- if( (p2 = strpbrk( p, " \t" ) ) )
- *p2++ = 0;
- if( !isdigit(p[0]) || !isdigit(p[1]) || !isdigit(p[2]) || p[3] ) {
- /* malformed HTTP statuscode - assume HTTP 0.9 */
- hd->is_http_0_9 = 1;
- hd->status_code = 200;
- return 0;
- }
- hd->status_code = atoi( p );
-
- /* skip all the header lines and wait for the empty line */
- do {
- maxlen = MAX_LINELEN;
- len = iobuf_read_line( hd->fp_read, &hd->buffer,
- &hd->buffer_size, &maxlen );
- line = hd->buffer;
- /* we ignore truncated lines */
- if( !len )
- return -1; /* eof */
- /* time lineendings */
- if( (*line == '\r' && line[1] == '\n') || *line == '\n' )
- *line = 0;
- } while( len && *line );
-
- return 0;
-}
-
-#if 0
-static int
-start_server()
-{
- struct sockaddr_in mya;
- struct sockaddr_in peer;
- int fd, client;
- fd_set rfds;
- int addrlen;
- int i;
-
- if( (fd=socket(AF_INET,SOCK_STREAM, 0)) == -1 ) {
- log_error("socket() failed: %s\n", strerror(errno));
- return -1;
- }
- i = 1;
- if( setsockopt( fd, SOL_SOCKET, SO_REUSEADDR, (byte*)&i, sizeof(i) ) )
- log_info("setsockopt(SO_REUSEADDR) failed: %s\n", strerror(errno) );
-
- mya.sin_family=AF_INET;
- memset(&mya.sin_addr, 0, sizeof(mya.sin_addr));
- mya.sin_port=htons(11371);
-
- if( bind( fd, (struct sockaddr *)&mya, sizeof(mya)) ) {
- log_error("bind to port 11371 failed: %s\n", strerror(errno) );
- sock_close( fd );
- return -1;
- }
-
- if( listen( fd, 5 ) ) {
- log_error("listen failed: %s\n", strerror(errno) );
- sock_close( fd );
- return -1;
- }
-
- for(;;) {
- FD_ZERO(&rfds);
- FD_SET( fd, &rfds );
-
- if( select( fd+1, &rfds, NULL, NULL, NULL) <= 0 )
- continue; /* ignore any errors */
-
- if( !FD_ISSET( fd, &rfds ) )
- continue;
-
- addrlen = sizeof peer;
- client = accept( fd, (struct sockaddr *)&peer, &addrlen);
- if( client == -1 )
- continue; /* oops */
-
- log_info("connect from %s\n", inet_ntoa( peer.sin_addr ) );
-
- fflush(stdout);
- fflush(stderr);
- if( !fork() ) {
- int c;
- FILE *fp;
-
- fp = fdopen( client , "r" );
- while( (c=getc(fp)) != EOF )
- putchar(c);
- fclose(fp);
- exit(0);
- }
- sock_close( client );
- }
-
-
- return 0;
-}
-#endif
-
-
-
-static int
-connect_server( const char *server, ushort port )
-{
- int sock,i=0;
- struct sockaddr_in addr;
- struct hostent *host=NULL;
- unsigned long l;
-
- memset(&addr,0,sizeof(addr));
-
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
-
-#ifdef __MINGW32__
- init_sockets ();
-
- if((sock=socket(AF_INET,SOCK_STREAM,0))==INVALID_SOCKET)
- {
- log_error("error creating socket: ec=%d\n",(int)WSAGetLastError());
- return -1;
- }
-#else
- if((sock=socket(AF_INET,SOCK_STREAM,0))==-1)
- {
- log_error("error creating socket\n");
- return -1;
- }
-#endif
-
-#ifdef __MINGW32__
- /* Win32 gethostbyname doesn't handle IP addresses internally, so we
- try inet_addr first on that platform only. */
- if((l=inet_addr(server))==SOCKET_ERROR)
-#endif
- if((host=gethostbyname(server))==NULL)
- {
-#ifdef __MINGW32__
- log_error("%s: host not found: ec=%d\n",server,(int)WSAGetLastError());
-#else
- log_error("%s: host not found\n",server);
-#endif
- sock_close(sock);
- return -1;
- }
-
- if(host)
- {
- if(host->h_addrtype != AF_INET)
- {
- log_error ("%s: unknown address family\n", server);
- sock_close(sock);
- return -1;
- }
-
- if(host->h_length != 4 )
- {
- log_error ("%s: illegal address length\n", server);
- sock_close(sock);
- return -1;
- }
-
- /* Try all A records until one responds. */
- while(host->h_addr_list[i])
- {
- memcpy(&addr.sin_addr,host->h_addr_list[i],host->h_length);
-
- if(connect(sock,(struct sockaddr *)&addr,sizeof(addr))==0)
- break;
-
- i++;
- }
-
- if(host->h_addr_list[i]==0)
- {
- sock_close(sock);
- return -1;
- }
- }
- else
- {
- memcpy(&addr.sin_addr,&l,sizeof(l));
-
- if(connect(sock,(struct sockaddr *)&addr,sizeof(addr))!=0)
- {
- sock_close(sock);
- return -1;
- }
- }
-
- return sock;
-}
-
-
-static int
-write_server( int sock, const char *data, size_t length )
-{
- int nleft;
-
- nleft = length;
- while( nleft > 0 ) {
- #ifdef __MINGW32__
- int nwritten;
-
- nwritten = send (sock, data, nleft, 0);
- if ( nwritten == SOCKET_ERROR ) {
- log_info ("write failed: ec=%d\n", (int)WSAGetLastError ());
- return G10ERR_NETWORK;
- }
- #else
- int nwritten = write( sock, data, nleft );
- if( nwritten == -1 ) {
- if( errno == EINTR )
- continue;
- if( errno == EAGAIN ) {
- struct timeval tv;
-
- tv.tv_sec = 0;
- tv.tv_usec = 50000;
- select(0, NULL, NULL, NULL, &tv);
- continue;
- }
- log_info("write failed: %s\n", strerror(errno));
- return G10ERR_NETWORK;
- }
- #endif
- nleft -=nwritten;
- data += nwritten;
- }
-
- return 0;
-}
-
-/**** Test code ****/
-#ifdef TEST
-
-int
-main(int argc, char **argv)
-{
- int rc;
- PARSED_URI uri;
- URI_TUPLE r;
- struct http_context hd;
- int c;
-
- log_set_name("http-test");
- if( argc == 1 ) {
- start_server();
- return 0;
- }
-
- if( argc != 2 ) {
- fprintf(stderr,"usage: http-test uri\n");
- return 1;
- }
- argc--; argv++;
-
- rc = parse_uri( &uri, *argv );
- if( rc ) {
- log_error("`%s': %s\n", *argv, g10_errstr(rc));
- release_parsed_uri( uri );
- return 1;
- }
-
- printf("Scheme: %s\n", uri->scheme );
- printf("Host : %s\n", uri->host );
- printf("Port : %u\n", uri->port );
- printf("Path : %s\n", uri->path );
- for( r=uri->params; r; r = r->next ) {
- printf("Params: %s=%s", r->name, r->value );
- if( strlen( r->value ) != r->valuelen )
- printf(" [real length=%d]", (int)r->valuelen );
- putchar('\n');
- }
- for( r=uri->query; r; r = r->next ) {
- printf("Query : %s=%s", r->name, r->value );
- if( strlen( r->value ) != r->valuelen )
- printf(" [real length=%d]", (int)r->valuelen );
- putchar('\n');
- }
- release_parsed_uri( uri ); uri = NULL;
-
- rc = http_open_document( &hd, *argv, 0 );
- if( rc ) {
- log_error("can't get `%s': %s\n", *argv, g10_errstr(rc));
- return 1;
- }
- log_info("open_http_document succeeded; status=%u\n", hd.status_code );
- while( (c=iobuf_get( hd.fp_read)) != -1 )
- putchar(c);
- http_close( &hd );
- return 0;
-}
-#endif /*TEST*/