1
/* curl-shim.c - Implement a small subset of the curl API in terms of
4
* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
6
* This file is part of GnuPG.
8
* GnuPG is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 2 of the License, or
11
* (at your option) any later version.
13
* GnuPG is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with this program; if not, write to the Free Software
20
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
34
#include "curl-shim.h"
37
handle_error(CURL *curl,CURLcode err,const char *str)
41
/* Make sure you never exceed CURL_ERROR_SIZE, currently set to
46
strcpy(curl->errorbuffer,"okay");
49
case CURLE_UNSUPPORTED_PROTOCOL:
50
strcpy(curl->errorbuffer,"unsupported protocol");
53
case CURLE_COULDNT_CONNECT:
54
strcpy(curl->errorbuffer,"couldn't connect");
57
case CURLE_WRITE_ERROR:
58
strcpy(curl->errorbuffer,"write error");
61
case CURLE_HTTP_RETURNED_ERROR:
62
sprintf(curl->errorbuffer,"url returned error %u",curl->status);
66
strcpy(curl->errorbuffer,"generic error");
70
if(str && (strlen(curl->errorbuffer)+2+strlen(str)+1)<=CURL_ERROR_SIZE)
72
strcat(curl->errorbuffer,": ");
73
strcat(curl->errorbuffer,str);
81
curl_global_init(long flags)
87
curl_global_cleanup(void) {}
94
handle=calloc(1,sizeof(CURL));
96
handle->errors=stderr;
102
curl_easy_cleanup(CURL *curl)
106
http_close (curl->hd, 0);
112
curl_easy_setopt(CURL *curl,CURLoption option,...)
121
curl->url=va_arg(ap,char *);
123
case CURLOPT_USERPWD:
124
curl->auth=va_arg(ap,char *);
126
case CURLOPT_WRITEFUNCTION:
127
curl->writer=va_arg(ap,write_func);
130
curl->file=va_arg(ap,void *);
132
case CURLOPT_ERRORBUFFER:
133
curl->errorbuffer=va_arg(ap,char *);
136
curl->proxy=va_arg(ap,char *);
139
curl->flags.post=va_arg(ap,unsigned int);
141
case CURLOPT_POSTFIELDS:
142
curl->postfields=va_arg(ap,char *);
144
case CURLOPT_FAILONERROR:
145
curl->flags.failonerror=va_arg(ap,unsigned int);
147
case CURLOPT_VERBOSE:
148
curl->flags.verbose=va_arg(ap,unsigned int);
151
curl->errors=va_arg(ap,FILE *);
154
/* We ignore the huge majority of curl options */
158
return handle_error(curl,CURLE_OK,NULL);
162
curl_easy_perform(CURL *curl)
165
CURLcode err=CURLE_OK;
166
const char *errstr=NULL;
169
/* Emulate the libcurl proxy behavior. If the calling program set a
170
proxy, use it. If it didn't set a proxy or set it to NULL, check
171
for one in the environment. If the calling program explicitly
172
set a null-string proxy the http code doesn't use a proxy at
178
proxy=getenv(HTTP_PROXY_ENV);
180
if(curl->flags.verbose)
181
fprintf(curl->errors,"* HTTP proxy is \"%s\"\n",proxy?proxy:"null");
185
rc = http_open (&curl->hd, HTTP_REQ_POST, curl->url, curl->auth,
189
unsigned int post_len = strlen(curl->postfields);
191
es_fprintf (http_get_write_ptr (curl->hd),
192
"Content-Type: application/x-www-form-urlencoded\r\n"
193
"Content-Length: %u\r\n", post_len);
194
http_start_data (curl->hd);
195
es_write (http_get_write_ptr (curl->hd),
196
curl->postfields, post_len, NULL);
198
rc = http_wait_response (curl->hd);
199
curl->status = http_get_status_code (curl->hd);
200
if (!rc && curl->flags.failonerror && curl->status>=300)
201
err = CURLE_HTTP_RETURNED_ERROR;
202
http_close (curl->hd, 0);
208
rc = http_open (&curl->hd, HTTP_REQ_GET, curl->url, curl->auth,
212
rc = http_wait_response (curl->hd);
213
curl->status = http_get_status_code (curl->hd);
216
if (curl->flags.failonerror && curl->status>=300)
217
err = CURLE_HTTP_RETURNED_ERROR;
220
unsigned int maxlen = 1024, buflen, len;
223
while ((len = es_read_line (http_get_read_ptr (curl->hd),
224
&line, &buflen, &maxlen)))
230
ret=(curl->writer)(line,len,1,curl->file);
233
err=CURLE_WRITE_ERROR;
239
http_close(curl->hd, 0);
245
http_close (curl->hd, 0);
251
switch(gpg_err_code (rc))
256
case GPG_ERR_INV_URI:
257
err=CURLE_UNSUPPORTED_PROTOCOL;
261
errstr=gpg_strerror (rc);
262
err=CURLE_COULDNT_CONNECT;
266
return handle_error(curl,err,errstr);
269
/* This is not the same exact set that is allowed according to
270
RFC-2396, but it is what the real curl uses. */
271
#define VALID_URI_CHARS "abcdefghijklmnopqrstuvwxyz" \
272
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
276
curl_escape(char *str,int length)
278
int len,max,idx,enc_idx=0;
292
for(idx=0;idx<len;idx++)
300
tmp=realloc(enc,max+1);
310
if(strchr(VALID_URI_CHARS,str[idx]))
311
enc[enc_idx++]=str[idx];
315
sprintf(numbuf,"%%%02X",str[idx]);
316
strcpy(&enc[enc_idx],numbuf);