工作中需要对接调试http接口,之前都是写代码测试,发现直接用curl这个工具更简单高效。
举例如下:
想要post一包数据给这个接口https://XXXXXXXXX
http报文头规定如下:
POST / HTTP/1.1 Host: XXXXXXXXXX:XXXX Accept: */* User-Agent: Donjin Http 0.1 Content-Type: x-ISO-TPDU/x-auth Cache-Control: no-cache Content-Length: 93 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(hex data)
用curl测试:其中需要提交的二进制数据,为了方便,写到aaa.bin文件中了。
curl https://XXXXXXXXX -v --cacert ./UP.pem -k -H 'User-Agent: Donjin Http 0.1' -H 'Content-Type: x-ISO-TPDU/x-auth' -H 'Cache-Control: no-cache' -H 'Content-Length: 93' --data-binary @aaa.bin
相比之前,用php写了个测试demo来说,这个工具更简单高效。
之前的php demo如下:
<?php echo "hello test 111!"; echo "<br>"; /* PHP CURL HTTPS POST */ function curl_post_https($url,$data){ // 模拟提交数据函数 $curl = curl_init(); // 启动一个CURL会话 curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检查 //curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1); // 从证书中检查SSL加密算法是否存在 curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览器 curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转 curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer curl_setopt($curl, CURLOPT_POST, 1); // 发送一个常规的Post请求 curl_setopt($curl, CURLOPT_POSTFIELDS, $data); // Post提交的数据包 curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环 curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回 $tmpInfo = curl_exec($curl); // 执行操作 if (curl_errno($curl)) { echo 'Errno'.curl_error($curl);//捕抓异常 } curl_close($curl); // 关闭CURL会话 return $tmpInfo; // 返回数据,json格式 } //echo getcwd(); /** * @name ssl Curl Post数据 * @param string $url 接收数据的api * @param string $vars 提交的数据 * @param int $second 要求程序必须在$second秒内完成,负责到$second秒后放到后台执行 * @return string or boolean 成功且对方有返回值则返回 */ function curl_post_ssl($url, $data, $second=30,$aHeader=array()) { $ch = curl_init(); curl_setopt($ch,CURLOPT_VERBOSE,'1'); curl_setopt($ch,CURLOPT_TIMEOUT,$second); //curl_setopt($ch,CURLOPT_VERBOSE, '1'); //debug模式,方便出错调试 curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch,CURLOPT_URL,$url); curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false); curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false); //curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM'); //curl_setopt($ch,CURLOPT_SSLCERT,getcwd().'/cert/CUP_cacert.pem'); // curl_setopt($ch,CURLOPT_SSLCERTPASSWD,''); curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM'); curl_setopt($ch,CURLOPT_SSLKEY,getcwd().'/cert/CUP_cacert.pem'); //设置header信息 curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'User-Agent: Donjin Http 0.1', 'Content-Type: x-ISO-TPDU/x-auth', 'Cache-Control: no-cache', 'Content-Length: ' . strlen($data)) ); if( count($aHeader) >= 1 ){ curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader); } curl_setopt($ch,CURLOPT_POST, 1); curl_setopt($ch,CURLOPT_POSTFIELDS,$data); $data = curl_exec($ch); //$curlInfo = curl_getinfo($ch); //echo $curlInfo; if (curl_errno($ch)) { echo 'Errno'.curl_error($ch);//捕抓异常 } curl_close($ch); if($data) return $data; else return false; } /* $data = [0,1]; $aHeader =[]; $rcode = curl_post_ssl($url,$data,10,$aHeader); if($rcode) { echo "ok"! } else { echo "error"! } */ function hex2bin($h){ if (!is_string($h)) return null; $r=''; for ($a=0; $a<strlen($h); $a+=2) { $r.=chr(hexdec($h{$a}.$h{($a+1)})); } return $r; } function Hex2String($hex){ $string=''; for ($i=0; $i < strlen($hex)-1; $i+=2){ $string .= chr(hexdec($hex[$i].$hex[$i+1])); } return $string; } function hextostr($hex) { return preg_replace_callback('/\\\x([0-9a-fA-F]{2})/', function($matches) { return chr(hexdec($matches[1])); }, $hex); } $string = "005BXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX0303135393838303231303031303231303136300011000000010030002953657175656e6365204e6f3136333135305358582d34433330343131390003303120"; $data = hex2bin($string); #var_dump($data); $url = 'https://XXXXXXXXXXXXXXXXX'; $aHeader = array(); $rcode = curl_post_ssl($url,$data,10,$aHeader); //$rcode = curl_post_https($url,$data); if($rcode) { echo "ok"; echo "<br>"; echo $rcode; //$myStr=""; //for($i=0;isset($rcode[$i]);$i++) //{ // $myStr.= chr($rcode[$i]); //} //var_dump($myStr); //$res=json_decode($rcode,true); echo "<br>"; echo 'respond hex data:'; echo "<br>"; $arr1 = str_split($rcode, 1); foreach($arr1 as $akey=>$aval){ $arr1[$akey]=" ".bin2hex($aval); echo $arr1[$akey]; } //var_dump($arr1); //echo hextostr($rcode); //var_dump($rcode); //echo Hex2String($rcode); //implode('!', $rcode); } else { echo "error"; echo "<br>"; }
使用c语言的测试如下:
/* <DESC> * Simple HTTPS GET * </DESC> */ #include <stdio.h> #include <pthread.h> #include "curl/curl.h" //#define POSTFIELDS "\x00XXXXXXXXXXXXXXXX13\x12\x08\x00\x00\x20\x00\x00\x00\xc0\x00\x16\x00\x00\x01\x31\x30\x30\x30\x30\x31\x35\x39\x38\x38\x30\x32\x31\x30\x30\x31\x30\x32\x31\x30\x31\x36\x30\x00\x11\x00\x00\x00\x01\x00\x30\x00\x29\x53\x65\x71\x75\x65\x6e\x63\x65\x20\x4e\x6f\x31\x36\x33\x31\x35\x30\x53\x58\x58\x2d\x34\x43\x33\x30\x34\x31\x31\x39\x00\x03\x30\x31\x20" //#define POSTFIELDS "005B6XXXXXXXXXXXXXXXXXXX208000020000000c0001600000131303030303135393838303231303031303231303136300011000000010030002953657175656e6365204e6f3136333135305358582d34433330343131390003303120" //struct curl_slist *headers=NULL; unsigned char postdata[93] = {0x00,XXXXXXXXXXXXXXXXXX,0,0x00,0x20,0x00,0x00,0x00,0xc0,0x00,0x16,0x00,0x00,0x01,0x31,0x30,0x30,0x30,0x30,0x31,0x35,0x39,0x38,0x38,0x30,0x32,0x31,0x30,0x30,0x31,0x30,0x32,0x31,0x30,0x31,0x36,0x30,0x00,0x11,0x00,0x00,0x00,0x01,0x00,0x30,0x00,0x29,0x53,0x65,0x71,0x75,0x65,0x6e,0x63,0x65,0x20,0x4e,0x6f,0x31,0x36,0x33,0x31,0x35,0x30,0x53,0x58,0x58,0x2d,0x34,0x43,0x33,0x30,0x34,0x31,0x31,0x39,0x00,0x03,0x30,0x31,0x20}; //CURL *curl; typedef struct post_args{ char* url; char* postdata; int postlen; }postargs; postargs args; pthread_t tid[10]; size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp) { int i = 0; //FILE *fptr = (FILE*)userp; //fwrite(buffer, size, nmemb, fptr); printf("rcv size:%d\n",nmemb); for(i =0;i <nmemb;i++) { printf("%02x ",((unsigned char*)buffer)[i]); } printf("\nrcv ok!\n"); return nmemb; } static void* Https_Post(void* args ) { postargs* margs; CURL *curl; CURLcode res; struct curl_slist *headers=NULL; char headerbuf[50]; int ret = 0; long res_code = 0; printf("=================================>>thread tid = %u start...\n", pthread_self()); margs = (postargs*)args; printf("thread begin post:\n"); //curl_global_init(CURL_GLOBAL_DEFAULT); curl = curl_easy_init(); if(curl) { curl_easy_setopt(curl, CURLOPT_URL, margs->url); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); //curl_easy_setopt(curl, CURLOPT_TIMEOUT,8); curl_easy_setopt(curl, CURLOPT_NOSIGNAL, (long)1); curl_easy_setopt(curl, CURLOPT_POST, 1); curl_easy_setopt(curl, CURLOPT_POSTFIELDS,margs->postdata); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, margs->postlen); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); //curl_easy_setopt(curl, CURLOPT_WRITEDATA, fptr); //curl_easy_setopt(curl, CURLOPT_CAINFO, "/etc/UP.pem"); //curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE,"PEM"); //curl_easy_setopt(curl, CURLOPT_SSLKEY,"UP.pem"); curl_easy_setopt(curl, CURLOPT_CAINFO, "/etc/UP.pem"); headers = curl_slist_append(headers, "User-Agent: Donjin Http 0.1"); headers = curl_slist_append(headers, "Content-Type: x-ISO-TPDU/x-auth"); headers = curl_slist_append(headers, "Cache-Control: no-cache"); printf("data:%02x,%02x postlen:%d\n",margs->postdata[0],margs->postdata[1],margs->postlen); sprintf(headerbuf,"Content-Length: %d",margs->postlen); headers = curl_slist_append(headers, headerbuf); //set headers curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); printf("->begin send:\n"); /* Perform the request, res will get the return code */ //pthread_mutex_lock(&gHTTPMutex); res = curl_easy_perform(curl); //pthread_mutex_unlock(&gHTTPMutex); /* Check for errors */ if(res != CURLE_OK) { fprintf(stderr, "curl_easy_perform() failed: %s\n",curl_easy_strerror(res)); ret = 1; goto END; } printf("->send ok\n"); res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &res_code); printf("res:%d,res_code:%ld\n",res,res_code); if(( res == CURLE_OK ) && (res_code == 200 || res_code == 201)) { ret = 0; goto END; } ret = 2; goto END; } else { printf("Init CURL failed...\n"); //curl_global_cleanup(); return NULL; } END: //last free the header list curl_slist_free_all(headers); /* always cleanup */ curl_easy_cleanup(curl); //curl_global_cleanup(); printf("=====================================>>thread tid = %u end!\n", pthread_self()); return NULL; } unsigned int Com_Dev_TxData( unsigned char *buf, unsigned int len, unsigned int timeout,unsigned int channel ) { int i = 0; int rcode = 0; args.url = "https://XXXXXXX:XXXXX"; args.postdata = buf; args.postlen = len; for(i = 0;i < 1;i++ ) { rcode = pthread_create(&tid[i], NULL, Https_Post, (void*)&args); } for(i=0; i< 1; i++) { rcode = pthread_join(tid[i], NULL); fprintf(stderr, "Thread %d terminated\n", i); } } void* task1(void* url ) { //int i = 0; int rcode = 0; printf("task1 run...\n"); rcode = Com_Dev_TxData(postdata,0x93,0,0); while(1) { ; } } int main(void) { int rcode = 0; char * url = "https://XXXXXXXX.xx"; curl_global_init(CURL_GLOBAL_DEFAULT); rcode = pthread_create(&tid[9], NULL, task1, (void*)url); while(1) { ; } curl_global_cleanup(); return 0; }
######################################## #makefile ######################################## #编译主程序 BINARY := test OBJ_DIR := ./ #CC= gcc #LD= ld CFLAGS= -g -pthread LDSCRIPT= -g LDFLAGS= -L ./LIBS SRC = $(wildcard *.c) DIR = $(notdir $(SRC)) OBJS = $(patsubst %.c,$(OBJ_DIR)%.o,$(DIR)) .PHONY: clean all: prebuild $(BINARY) prebuild: @echo Building app... $(BINARY) : $(OBJS) @echo Generating ... $(CC) -o $(BINARY) $(OBJS) $(LDFLAGS) $(LDSCRIPT) @echo OK! $(OBJ_DIR)%.o : %.c $(CC) -c $(CFLAGS) $< -o $@ clean: rm -f $(OBJ_DIR)*.o @echo Removed!