From f50e99ed7b9f55e95daa863e53c1a70da3110c1a Mon Sep 17 00:00:00 2001 From: David Shaw Date: Sun, 17 Apr 2005 01:39:24 +0000 Subject: [PATCH] * curl-shim.h, curl-shim.c (handle_error, curl_easy_setopt, curl_easy_perform): Add POST functionality to the curl shim. --- keyserver/ChangeLog | 3 ++ keyserver/curl-shim.c | 114 ++++++++++++++++++++++++++++++++++-------- keyserver/curl-shim.h | 19 +++++-- 3 files changed, 112 insertions(+), 24 deletions(-) diff --git a/keyserver/ChangeLog b/keyserver/ChangeLog index 84eec3ae5..ea3e20533 100644 --- a/keyserver/ChangeLog +++ b/keyserver/ChangeLog @@ -1,5 +1,8 @@ 2005-04-16 David Shaw + * curl-shim.h, curl-shim.c (handle_error, curl_easy_setopt, + curl_easy_perform): Add POST functionality to the curl shim. + * curl-shim.h, curl-shim.c (curl_escape, curl_free): Emulate curl_escape and curl_free. diff --git a/keyserver/curl-shim.c b/keyserver/curl-shim.c index f9ef61aa0..8e0641f27 100644 --- a/keyserver/curl-shim.c +++ b/keyserver/curl-shim.c @@ -48,6 +48,10 @@ static CURLcode handle_error(CURL *curl,CURLcode err,const char *str) strcpy(curl->errorbuffer,"write error"); break; + case CURLE_HTTP_RETURNED_ERROR: + sprintf(curl->errorbuffer,"url returned error %u",curl->status); + break; + default: strcpy(curl->errorbuffer,"generic error"); break; @@ -103,6 +107,15 @@ CURLcode curl_easy_setopt(CURL *curl,CURLoption option,...) case CURLOPT_PROXY: curl->proxy=va_arg(ap,char *); break; + case CURLOPT_POST: + curl->flags.post=va_arg(ap,unsigned int); + break; + case CURLOPT_POSTFIELDS: + curl->postfields=va_arg(ap,char *); + break; + case CURLOPT_FAILONERROR: + curl->flags.failonerror=va_arg(ap,unsigned int); + break; default: /* We ignore the huge majority of curl options */ break; @@ -117,36 +130,97 @@ CURLcode curl_easy_perform(CURL *curl) CURLcode err=CURLE_OK; const char *errstr=NULL; - rc=http_open_document(&curl->hd,curl->url,0,curl->proxy); - if(rc!=0) + if(curl->flags.post) { - if(rc==G10ERR_NETWORK) - errstr=strerror(errno); - else - errstr=g10_errstr(rc); + rc=http_open(&curl->hd,HTTP_REQ_POST,curl->url,0,curl->proxy); + if(rc!=0) + { + if(rc==G10ERR_NETWORK) + errstr=strerror(errno); + else + errstr=g10_errstr(rc); - err=CURLE_COULDNT_CONNECT; + err=CURLE_COULDNT_CONNECT; + } + else + { + char content_len[50]; + unsigned int post_len=strlen(curl->postfields); + + iobuf_writestr(curl->hd.fp_write, + "Content-Type: application/x-www-form-urlencoded\r\n"); + sprintf(content_len,"Content-Length: %u\r\n",post_len); + + iobuf_writestr(curl->hd.fp_write,content_len); + + http_start_data(&curl->hd); + iobuf_write(curl->hd.fp_write,curl->postfields,post_len); + rc=http_wait_response(&curl->hd,&curl->status); + if(rc!=0) + { + if(rc==G10ERR_NETWORK) + errstr=strerror(errno); + else + errstr=g10_errstr(rc); + + err=CURLE_COULDNT_CONNECT; + } + + if(curl->flags.failonerror && curl->status>=300) + err=CURLE_HTTP_RETURNED_ERROR; + } } else { - unsigned int maxlen=1024,buflen,len; - byte *line=NULL; - - while((len=iobuf_read_line(curl->hd.fp_read,&line,&buflen,&maxlen))) + rc=http_open(&curl->hd,HTTP_REQ_GET,curl->url,0,curl->proxy); + if(rc!=0) { - maxlen=1024; - size_t ret; + if(rc==G10ERR_NETWORK) + errstr=strerror(errno); + else + errstr=g10_errstr(rc); - ret=(curl->writer)(line,len,1,curl->file); - if(ret!=len) + err=CURLE_COULDNT_CONNECT; + } + else + { + rc=http_wait_response(&curl->hd,&curl->status); + if(rc) { - err=CURLE_WRITE_ERROR; - break; + http_close(&curl->hd); + + if(rc==G10ERR_NETWORK) + errstr=strerror(errno); + else + errstr=g10_errstr(rc); + + err=CURLE_COULDNT_CONNECT; + } + else if(curl->flags.failonerror && curl->status>=300) + err=CURLE_HTTP_RETURNED_ERROR; + else + { + unsigned int maxlen=1024,buflen,len; + byte *line=NULL; + + while((len=iobuf_read_line(curl->hd.fp_read, + &line,&buflen,&maxlen))) + { + maxlen=1024; + size_t ret; + + ret=(curl->writer)(line,len,1,curl->file); + if(ret!=len) + { + err=CURLE_WRITE_ERROR; + break; + } + } + + m_free(line); + http_close(&curl->hd); } } - - m_free(line); - http_close(&curl->hd); } return handle_error(curl,err,errstr); diff --git a/keyserver/curl-shim.h b/keyserver/curl-shim.h index dc3d959bd..505393635 100644 --- a/keyserver/curl-shim.h +++ b/keyserver/curl-shim.h @@ -26,9 +26,10 @@ typedef enum { CURLE_OK=0, - CURLE_FTP_COULDNT_RETR_FILE, - CURLE_COULDNT_CONNECT, - CURLE_WRITE_ERROR + CURLE_COULDNT_CONNECT=7, + CURLE_FTP_COULDNT_RETR_FILE=19, + CURLE_HTTP_RETURNED_ERROR=22, + CURLE_WRITE_ERROR=23 } CURLcode; typedef enum @@ -43,7 +44,10 @@ typedef enum CURLOPT_VERBOSE, CURLOPT_SSL_VERIFYPEER, CURLOPT_PROXY, - CURLOPT_CAINFO + CURLOPT_CAINFO, + CURLOPT_POST, + CURLOPT_POSTFIELDS, + CURLOPT_FAILONERROR } CURLoption; typedef size_t (*write_func)(char *buffer,size_t size, @@ -56,6 +60,13 @@ typedef struct char *proxy; write_func writer; void *file; + char *postfields; + unsigned int status; + struct + { + unsigned int post:1; + unsigned int failonerror:1; + } flags; struct http_context hd; } CURL;