* curl-shim.h, curl-shim.c (handle_error, curl_easy_setopt,
authorDavid Shaw <dshaw@jabberwocky.com>
Sun, 17 Apr 2005 01:39:24 +0000 (01:39 +0000)
committerDavid Shaw <dshaw@jabberwocky.com>
Sun, 17 Apr 2005 01:39:24 +0000 (01:39 +0000)
curl_easy_perform): Add POST functionality to the curl shim.

keyserver/ChangeLog
keyserver/curl-shim.c
keyserver/curl-shim.h

index 84eec3a..ea3e205 100644 (file)
@@ -1,5 +1,8 @@
 2005-04-16  David Shaw  <dshaw@jabberwocky.com>
 
+       * 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.
 
index f9ef61a..8e0641f 100644 (file)
@@ -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);
+      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;
+       }
       else
-       errstr=g10_errstr(rc);
+       {
+         char content_len[50];
+         unsigned int post_len=strlen(curl->postfields);
 
-      err=CURLE_COULDNT_CONNECT;
+         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;
+      rc=http_open(&curl->hd,HTTP_REQ_GET,curl->url,0,curl->proxy);
+      if(rc!=0)
+       {
+         if(rc==G10ERR_NETWORK)
+           errstr=strerror(errno);
+         else
+           errstr=g10_errstr(rc);
 
-      while((len=iobuf_read_line(curl->hd.fp_read,&line,&buflen,&maxlen)))
+         err=CURLE_COULDNT_CONNECT;
+       }
+      else
        {
-         maxlen=1024;
-         size_t ret;
+         rc=http_wait_response(&curl->hd,&curl->status);
+         if(rc)
+           {
+             http_close(&curl->hd);
+
+             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 if(curl->flags.failonerror && curl->status>=300)
+           err=CURLE_HTTP_RETURNED_ERROR;
+         else
            {
-             err=CURLE_WRITE_ERROR;
-             break;
+             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);
index dc3d959..5053936 100644 (file)
 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;