mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
See ChangeLog: Sat Jan 16 21:25:17 CET 1999 Werner Koch
This commit is contained in:
parent
05af4687a5
commit
38008c1c20
8
TODO
8
TODO
@ -27,7 +27,11 @@ Important
|
||||
> gpg: keyblock resource `/home/jam/.gnupg/pubring.gpg': file open error
|
||||
> gpg: OOPS in close enum_keyblocks - ignored
|
||||
|
||||
|
||||
> Indeed, comparing zero to 0xfe returns 2, not -something, and this is
|
||||
> the problem. This seems to fix it, but I don't know how you want to
|
||||
> handle this.
|
||||
>
|
||||
I'll better write a autoconf test as memcmp is used all over the place.
|
||||
|
||||
Needed
|
||||
------
|
||||
@ -69,4 +73,6 @@ Nice to have
|
||||
* change the fake_data stuff to mpi_set_opaque
|
||||
* How about letting something like 'gpg --version -v', list the
|
||||
effective options.
|
||||
* Stats about used random numbers.
|
||||
|
||||
|
||||
|
@ -62,5 +62,6 @@ lock-once
|
||||
# you will be asked in such a case whether GnuPG should try to
|
||||
# import the key from that server (server do syncronize with each
|
||||
# others and DNS Round-Robin may give you a random server each time).
|
||||
#keyserver keys.pgp.net
|
||||
# Use "host -l pgp.net | grep www" to figure out a keyserver.
|
||||
#keyserver wwwkeys.eu.pgp.net
|
||||
|
||||
|
62
include/http.h
Normal file
62
include/http.h
Normal file
@ -0,0 +1,62 @@
|
||||
/* http.h - HTTP protocol handler
|
||||
* Copyright (C) 1999 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
|
||||
*/
|
||||
#ifndef G10_HTTP_H
|
||||
#define G10_HTTP_H 1
|
||||
|
||||
#include "iobuf.h"
|
||||
|
||||
struct uri_tuple {
|
||||
struct uri_tuple *next;
|
||||
const char *name; /* a pointer into name */
|
||||
char *value; /* a pointer to value (a Nul is always appended) */
|
||||
size_t valuelen; /* and the real length of the value */
|
||||
/* because the value may contain embedded Nuls */
|
||||
};
|
||||
typedef struct uri_tuple *URI_TUPLE;
|
||||
|
||||
struct parsed_uri {
|
||||
/* all these pointers point into buffer; most stuff is not escaped */
|
||||
char *scheme; /* pointer to the scheme string (lowercase) */
|
||||
char *host; /* host (converted to lowercase) */
|
||||
ushort port; /* port (always set if the host is set) */
|
||||
char *path; /* the path */
|
||||
URI_TUPLE params; /* ";xxxxx" */
|
||||
URI_TUPLE query; /* "?xxx=yyy" */
|
||||
char buffer[1]; /* buffer which holds a (modified) copy of the URI */
|
||||
};
|
||||
typedef struct parsed_uri *PARSED_URI;
|
||||
|
||||
struct http_context {
|
||||
int initialized;
|
||||
unsigned int status_code;
|
||||
int socket;
|
||||
IOBUF fp_read;
|
||||
IOBUF fp_write;
|
||||
int is_http_0_9;
|
||||
PARSED_URI uri;
|
||||
byte *buffer; /* line buffer */
|
||||
unsigned buffer_size;
|
||||
};
|
||||
typedef struct http_context *HTTP_HD;
|
||||
|
||||
int open_http_document( HTTP_HD hd, const char *document, unsigned int flags );
|
||||
void close_http_document( HTTP_HD hd );
|
||||
|
||||
#endif /*G10_HTTP_H*/
|
625
util/http.c
Normal file
625
util/http.c
Normal file
@ -0,0 +1,625 @@
|
||||
/* http.c - HTTP protocol handler
|
||||
* Copyright (C) 1999 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>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "iobuf.h"
|
||||
#include "i18n.h"
|
||||
|
||||
#include "http.h"
|
||||
|
||||
#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 socket, const char *data, size_t length );
|
||||
|
||||
|
||||
|
||||
int
|
||||
open_http_document( HTTP_HD hd, const char *document, unsigned int flags )
|
||||
{
|
||||
int rc;
|
||||
|
||||
if( flags )
|
||||
return G10ERR_INV_ARG;
|
||||
|
||||
/* initialize the handle */
|
||||
memset( hd, 0, sizeof *hd );
|
||||
hd->socket = -1;
|
||||
|
||||
rc = parse_uri( &hd->uri, document );
|
||||
if( rc )
|
||||
goto failure;
|
||||
|
||||
rc = send_request( hd );
|
||||
if( rc )
|
||||
goto failure;
|
||||
|
||||
hd->fp_read = iobuf_fdopen( hd->socket , "r" );
|
||||
if( !hd->fp_read )
|
||||
goto failure;
|
||||
|
||||
rc = parse_response( hd );
|
||||
if( rc == -1 ) { /* no response from server */
|
||||
/* Hmmm, should we set some errro variable or map errors */
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if( !rc )
|
||||
hd->is_http_0_9 = 1;
|
||||
else
|
||||
hd->status_code = rc ;
|
||||
|
||||
hd->initialized = 1;
|
||||
return 0;
|
||||
|
||||
failure:
|
||||
if( !hd->fp_read && !hd->fp_write )
|
||||
close( hd->socket );
|
||||
iobuf_close( hd->fp_read );
|
||||
iobuf_close( hd->fp_write);
|
||||
release_parsed_uri( hd->uri );
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void
|
||||
close_http_document( HTTP_HD hd )
|
||||
{
|
||||
if( !hd || !hd->initialized )
|
||||
return;
|
||||
if( !hd->fp_read && !hd->fp_write )
|
||||
close( hd->socket );
|
||||
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;
|
||||
if( !strcmp( uri->scheme, "http" ) )
|
||||
;
|
||||
else if( !strcmp( uri->scheme, "x-hkp" ) ) /* same as HTTP */
|
||||
;
|
||||
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 );
|
||||
}
|
||||
else
|
||||
uri->port = 80;
|
||||
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 */
|
||||
|
||||
/* fixme: 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;
|
||||
|
||||
server = *hd->uri->host? hd->uri->host : "localhost";
|
||||
port = hd->uri->port? hd->uri->port : 80;
|
||||
|
||||
hd->socket = connect_server( server, port );
|
||||
if( hd->socket == -1 )
|
||||
return G10ERR_NETWORK;
|
||||
|
||||
p = build_rel_path( hd->uri );
|
||||
request = m_alloc( strlen(p) + 20 );
|
||||
sprintf( request, "GET %s%s HTTP/1.0\r\n\r\n", *p == '/'? "":"/", p );
|
||||
m_free(p);
|
||||
|
||||
rc = write_server( hd->socket, request, strlen(request) );
|
||||
m_free( request );
|
||||
shutdown( hd->socket, 1 );
|
||||
|
||||
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, "%;?&" );
|
||||
/* fixme: add 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;
|
||||
/* fixme: add params */
|
||||
for( r=uri->query; r; r = r->next ) {
|
||||
*p++ = r == uri->query? '?':'&';
|
||||
n = insert_escapes( p, r->name, "%;?&=" );
|
||||
p += n;
|
||||
*p++ = '=';
|
||||
/* fixme: use valuelen */
|
||||
n = insert_escapes( p, r->value, "%;?&=" );
|
||||
p += n;
|
||||
}
|
||||
*p = 0;
|
||||
return rel_path;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************
|
||||
* Parse the response from a server.
|
||||
* Returns: -1 for no response or error
|
||||
* 0 for a http 0.9 response
|
||||
* nnn http 1.0 status code
|
||||
*/
|
||||
static int
|
||||
parse_response( HTTP_HD hd )
|
||||
{
|
||||
byte *line, *p, *p2;
|
||||
int status;
|
||||
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;
|
||||
/* fixme: 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] )
|
||||
return 0; /* malformed HTTP statuscode - assume HTTP 0.9 */
|
||||
status = 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 status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int
|
||||
connect_server( const char *server, ushort port )
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
struct hostent *host;
|
||||
int sd;
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(port);
|
||||
host = gethostbyname((char*)server);
|
||||
if( !host )
|
||||
return -1;
|
||||
|
||||
addr.sin_addr = *(struct in_addr*)host->h_addr;
|
||||
|
||||
sd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if( sd == -1 )
|
||||
return -1;
|
||||
|
||||
if( connect( sd, (struct sockaddr *)&addr, sizeof addr) == -1 ) {
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sd;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
write_server( int socket, const char *data, size_t length )
|
||||
{
|
||||
int nleft, nwritten;
|
||||
|
||||
nleft = length;
|
||||
while( nleft > 0 ) {
|
||||
nwritten = write( socket, 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;
|
||||
}
|
||||
return G10ERR_NETWORK;
|
||||
}
|
||||
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 != 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 = open_http_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);
|
||||
close_http_document( &hd );
|
||||
return 0;
|
||||
}
|
||||
#endif /*TEST*/
|
Loading…
x
Reference in New Issue
Block a user