利用curl的API进行开发 2011-06-08 12:22:03

分类: LINUX

 

同事做的一个web系统,想让别人来提交数据,具体操作就是访问一个URL地址,提交用户名和主机等信息。
而且在这之余,想记下操作的用户ID,因此建议俺搞一个命令行工具来给他用。
  一开始俺想到用system封装CURL,但是这样比较弱智,而且这样做了哪些操作,系统是能够记录下来的,用官方正式一点的话说就是不太安全,有安全隐患,呵呵。
于是乎,下载了curl的源码,生成命令行工具之后,查看curl源码,结合命令行测试,最终目的,就是怎么把
  • curl --digest -u user:pass url地址
  • 转换成另外一个接口,比如
  • ./auto_http --auth cme:cme -u jigang.djg -n testhost
  • 这样的,这样做的话,就能够在auto_http的源码中提取uid,IP等等相关信息,而且提交人也不知道我怎么实现提交的,不知道我采用了url,不知道我记录下了他的uid,不知道我们web系统的相关信息。

    实现代码如下:

     

  • //---------auto.c----------created by cme
  • #include <stdio.h>
  • #include <stdarg.h>
  • #include <string.h>
  • #include <curl/curl.h>
  • #include <stdlib.h>
  • #include <unistd.h>
  • #include <sys/types.h>
  • #define my_setopt(x,y,z) _my_setopt(x, 0, #y, y, z)
  • #define my_setopt_str(x,y,z) _my_setopt(x, 1, #y, y, z)
  • static CURLcode _my_setopt(CURL *curl, int str,const char *name, CURLoption tag, ...);
  • //#define URL "http://account.tbsite.net:9999/api/websubmits?"
  • #define URL "http://afang.org/cme_digest/?"
  • int main(int argc, char *argv[])
  • {
  •         CURL *curl; 
  •         CURLcode res; 
  •     
  •     char strurl[1024] = {0};
  •     unsigned int uid = getuid();
  •         if(argc != 7)
  •         {
  •             printf("Usage:%s --auth name:pass -u user -n host\n", argv[0]);
  •             exit(1);
  •         }
  •     
  •     if (strncmp(argv[1], "--auth", 6) != 0)
  •     {
  •         printf("Usage:%s --auth name:pass -u user -n host\n", argv[0]);
  •             exit(1);
  •     }
  •     char * str = strchr (argv[2], ':');
  •     if (!str)
  •     {
  •         printf("Usage:%s --auth name:pass -u user -n host\n", argv[0]);
  •             exit(1);
  •     }
  •     if (strncmp(argv[3], "-u", 2) != 0)
  •     {
  •         printf("Usage:%s --auth name:pass -u user -n host\n", argv[0]);
  •             exit(1);
  •     }
  •     if (strncmp(argv[5], "-n", 2) != 0)
  •     {
  •         printf("Usage:%s --auth name:pass -u user -n host\n", argv[0]);
  •             exit(1);
  •     }
  •     curl = curl_easy_init(); 
  •     if(curl!=NULL)
  •     {
  •          my_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
  •         //my_setopt_str(curl, CURLOPT_USERPWD, "cme:cme");
  •         my_setopt_str(curl, CURLOPT_USERPWD, argv[2]);
  •             //my_setopt_str(curl, CURLOPT_PROXYUSERPWD, "cne:cme");
  •         //curl_easy_setopt(curl, CURLOPT_TLSAUTH_USERNAME, "cme");
  •         //curl_easy_setopt(curl, CURLOPT_TLSAUTH_PASSWORD, "cme");
  •         sprintf (strurl, "%suser=%s&host=%s&submitby=%u", URL, argv[4], argv[6], uid);
  •         printf ("get url:%s\n", strurl);
  •             curl_easy_setopt(curl, CURLOPT_URL, strurl); 
  •             res = curl_easy_perform(curl);
  •     }
  •     return 0;
  • }
  • CURLcode _my_setopt(CURL *curl, int str,const char *name, CURLoption tag, ...)
  • {
  •   va_list arg;
  •   CURLcode ret;
  •   char *bufp;
  •   char value[256];
  •   int remark = 0;
  •   int skip = 0;
  •   va_start(arg, tag);
  •   if(tag < CURLOPTTYPE_OBJECTPOINT)
  •   {
  •     long lval = va_arg(arg, long);
  •     snprintf(value, sizeof(value), "%ldL", lval);
  •     ret = curl_easy_setopt(curl, tag, lval);
  •     if(!lval)
  •       skip = 1;
  •   }
  •   else if(tag < CURLOPTTYPE_OFF_T) 
  •   {
  •     void *pval = va_arg(arg, void *);
  •     unsigned char *ptr = (unsigned char *)pval;
  •     // function pointers are never printable 
  •     if(tag >= CURLOPTTYPE_FUNCTIONPOINT) 
  •     {
  •       if(pval) 
  •       {
  •         strcpy(value, "functionpointer"); // 'value' fits 256 bytes 
  •         remark = 1;
  •       }
  •       else
  •         skip = 1;
  •     }
  •     else if(pval && str)
  •       snprintf(value, sizeof(value), "\"%s\"", (char *)ptr);
  •     else if(pval) 
  •     {
  •       strcpy(value, "objectpointer"); // 'value' fits 256 bytes 
  •       remark = 1;
  •     }
  •     else
  •       skip = 1;
  •     ret = curl_easy_setopt(curl, tag, pval);
  •   }
  •   else 
  •   {
  •     curl_off_t oval = va_arg(arg, curl_off_t);
  •     snprintf(value, sizeof(value),
  •              "(curl_off_t)%" CURL_FORMAT_CURL_OFF_T, oval);
  •     ret = curl_easy_setopt(curl, tag, oval);
  •     if(!oval)
  •       skip = 1;
  •   }
  •   va_end(arg);
  •   return ret;
  • }
  • 总结了下,还是curl的代码写得好,一个operate函数中嵌套了通用的set_opt,甚是好用啊。

    简单的几行代码,就实现了。哈哈。

     

    附上makefile

     

  • default:    
  •     gcc --g auto.c
  •     gcc -o auto_http auto.-lcurl
  • clean:
  •     rm -fr auto_http *.o



  • 文章出处:http://blog.chinaunix.net/uid-10163889-id-1641587.html

    相关文章: