コード例 #1
0
ファイル: bitcoind_RPC.c プロジェクト: roshangn88/SuperNET
char *bitcoind_RPC(char **retstrp,char *debugstr,char *url,char *userpass,char *command,char *params)
{
    static int didinit,count,count2; static double elapsedsum,elapsedsum2; extern int32_t USE_JAY;
    struct curl_slist *headers = NULL; struct return_string s; CURLcode res; CURL *curl_handle;
    char *bracket0,*bracket1,*databuf = 0; long len; int32_t specialcase,numretries; double starttime;
    if ( didinit == 0 )
    {
        didinit = 1;
        curl_global_init(CURL_GLOBAL_ALL); //init the curl session
    }
    if ( USE_JAY != 0 && (strncmp(url,"http://127.0.0.1:7876/nxt",strlen("http://127.0.0.1:7876/nxt")) == 0 || strncmp(url,"https://127.0.0.1:7876/nxt",strlen("https://127.0.0.1:7876/nxt")) == 0) )
    {
        if ( (databuf= Jay_NXTrequest(command,params)) != 0 )
            return(databuf);
    }
    numretries = 0;
    if ( debugstr != 0 && strcmp(debugstr,"BTCD") == 0 && command != 0 && strcmp(command,"SuperNET") ==  0 )
        specialcase = 1;
    else specialcase = 0;
    if ( url[0] == 0 )
        strcpy(url,"http://127.0.0.1:7876/nxt");
    if ( specialcase != 0 && 0 )
        printf("<<<<<<<<<<< bitcoind_RPC: debug.(%s) url.(%s) command.(%s) params.(%s)\n",debugstr,url,command,params);
try_again:
    if ( retstrp != 0 )
        *retstrp = 0;
    starttime = OS_milliseconds();
    curl_handle = curl_easy_init();
    init_string(&s);
    headers = curl_slist_append(0,"Expect:");
    
  	curl_easy_setopt(curl_handle,CURLOPT_USERAGENT,"mozilla/4.0");//"Mozilla/4.0 (compatible; )");
    curl_easy_setopt(curl_handle,CURLOPT_HTTPHEADER,	headers);
    curl_easy_setopt(curl_handle,CURLOPT_URL,		url);
    curl_easy_setopt(curl_handle,CURLOPT_WRITEFUNCTION,	(void *)accumulate); 		// send all data to this function
    curl_easy_setopt(curl_handle,CURLOPT_WRITEDATA,		&s); 			// we pass our 's' struct to the callback
    curl_easy_setopt(curl_handle,CURLOPT_NOSIGNAL,		1L);   			// supposed to fix "Alarm clock" and long jump crash
	curl_easy_setopt(curl_handle,CURLOPT_NOPROGRESS,	1L);			// no progress callback
    if ( strncmp(url,"https",5) == 0 )
    {
        curl_easy_setopt(curl_handle,CURLOPT_SSL_VERIFYPEER,0);
        curl_easy_setopt(curl_handle,CURLOPT_SSL_VERIFYHOST,0);
    }
    if ( userpass != 0 )
        curl_easy_setopt(curl_handle,CURLOPT_USERPWD,	userpass);
    databuf = 0;
    if ( params != 0 )
    {
        if ( command != 0 && specialcase == 0 )
        {
            len = strlen(params);
            if ( len > 0 && params[0] == '[' && params[len-1] == ']' ) {
                bracket0 = bracket1 = (char *)"";
            }
            else
            {
                bracket0 = (char *)"[";
                bracket1 = (char *)"]";
            }
            
            databuf = (char *)malloc(256 + strlen(command) + strlen(params));
            sprintf(databuf,"{\"id\":\"jl777\",\"method\":\"%s\",\"params\":%s%s%s}",command,bracket0,params,bracket1);
            printf("url.(%s) userpass.(%s) databuf.(%s)\n",url,userpass,databuf);
            //
        } //else if ( specialcase != 0 ) fprintf(stderr,"databuf.(%s)\n",params);
        curl_easy_setopt(curl_handle,CURLOPT_POST,1L);
        if ( databuf != 0 )
            curl_easy_setopt(curl_handle,CURLOPT_POSTFIELDS,databuf);
        else curl_easy_setopt(curl_handle,CURLOPT_POSTFIELDS,params);
    }
    //laststart = milliseconds();
    res = curl_easy_perform(curl_handle);
    curl_slist_free_all(headers);
    curl_easy_cleanup(curl_handle);
    if ( databuf != 0 ) // clean up temporary buffer
    {
        free(databuf);
        databuf = 0;
    }
    if ( res != CURLE_OK )
    {
        numretries++;
        if ( specialcase != 0 )
        {
            printf("<<<<<<<<<<< bitcoind_RPC.(%s): BTCD.%s timeout params.(%s) s.ptr.(%s) err.%d\n",url,command,params,s.ptr,res);
            free(s.ptr);
            return(0);
        }
        else if ( numretries >= 2 )
        {
            printf("Maximum number of retries exceeded!\n");
            free(s.ptr);
            return(0);
        }
        printf( "curl_easy_perform() failed: %s %s.(%s %s), retries: %d\n",curl_easy_strerror(res),debugstr,url,command,numretries);
        free(s.ptr);
        sleep((1<<numretries));
        goto try_again;
        
    }
    else
    {
        if ( command != 0 && specialcase == 0 )
        {
            count++;
            elapsedsum += (OS_milliseconds() - starttime);
            if ( (count % 10000) == 0)
                printf("%d: ave %9.6f | elapsed %.3f millis | bitcoind_RPC.(%s) url.(%s)\n",count,elapsedsum/count,(OS_milliseconds() - starttime),command,url);
            if ( retstrp != 0 )
            {
                *retstrp = s.ptr;
                return(s.ptr);
            }
            return(post_process_bitcoind_RPC(debugstr,command,s.ptr,params));
        }
        else
        {
            if ( 0 && specialcase != 0 )
                fprintf(stderr,"<<<<<<<<<<< bitcoind_RPC: BTCD.(%s) -> (%s)\n",params,s.ptr);
            count2++;
            elapsedsum2 += (OS_milliseconds() - starttime);
            if ( (count2 % 10000) == 0)
                printf("%d: ave %9.6f | elapsed %.3f millis | NXT calls.(%s) cmd.(%s)\n",count2,elapsedsum2/count2,(double)(OS_milliseconds() - starttime),url,command);
            return(s.ptr);
        }
    }
    printf("bitcoind_RPC: impossible case\n");
    free(s.ptr);
    return(0);
}
コード例 #2
0
char *bitcoind_RPC(char *debugstr,int32_t numretries,char *url,char *userpass,char *command,char *params)
{
    static int32_t count,didinit;
    static double elapsedsum,elapsedsum2,laststart;
    char *retstr,*bracket0,*bracket1,*databuf=0,len_hdr[10240];
    CURL *curl_handle;
    CURLcode res;
    long len;
    int32_t delay = MAGIC_BITCOINC_RPCDELAY;
    double starttime;
    struct curl_slist *headers = NULL;
    struct upload_buffer upload_data;
    struct MemoryStruct chunk;
    double milliseconds();
    //static pthread_mutex_t mutex;
    //pthread_mutex_lock(&mutex);
    if ( didinit == 0 )
    {
        didinit = 1;
        curl_global_init(CURL_GLOBAL_ALL); //init the curl session
    }
    //printf("start bitcoind_RPC %s\n",command!=0?command:"");
    starttime = milliseconds();
    if ( 1 && laststart+1 > starttime ) // horrible hack for bitcoind "Couldn't connect to server"
    {
        usleep(2000);
        starttime = milliseconds();
    }
    laststart = starttime;
    if ( params == 0 )
        params = "";
retry:
    chunk.memory = malloc(1);     // will be grown as needed by the realloc above
    chunk.size = 0;                 // no data at this point
    curl_handle = curl_easy_init();
    curl_easy_setopt(curl_handle,CURLOPT_CONNECTTIMEOUT,2); // chanc3r: limit any *real* timeouts to 2s
    curl_easy_setopt(curl_handle,CURLOPT_FRESH_CONNECT,1);  // chanc3r: force a new connection for each request - i'm     curl_easy_setopt(curl_handle,CURLOPT_SSL_VERIFYHOST,0);
    curl_easy_setopt(curl_handle,CURLOPT_SSL_VERIFYPEER,0);
    curl_easy_setopt(curl_handle,CURLOPT_URL,url);
    curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);        // supposed to fix "Alarm clock" and long jump crash
    curl_easy_setopt(curl_handle,CURLOPT_WRITEFUNCTION,WriteMemoryCallback); // send all data to this function
    curl_easy_setopt(curl_handle,CURLOPT_WRITEDATA,(void *)&chunk); // we pass our 'chunk' struct to the callback function
    curl_easy_setopt(curl_handle,CURLOPT_USERAGENT,"libcurl-agent/1.0"); // some servers don't like requests that are made without a user-agent field, so we provide one
    if ( userpass != 0 )
        curl_easy_setopt(curl_handle,CURLOPT_USERPWD,userpass);
    if ( command != 0 )
    {
        curl_easy_setopt(curl_handle,CURLOPT_READFUNCTION,upload_data_cb);
        curl_easy_setopt(curl_handle,CURLOPT_READDATA,&upload_data);
        curl_easy_setopt(curl_handle,CURLOPT_POST,1);
        len = strlen(params);
        if ( len > 0 && params[0] == '[' && params[len-1] == ']' )
            bracket0 = bracket1 = "";
        else bracket0 = "[", bracket1 = "]";
        databuf = malloc(4096 + strlen(command) + strlen(params));
        sprintf(databuf,"{\"id\":\"jl777\",\"method\":\"%s\",\"params\":%s%s%s}",command,bracket0,params,bracket1);
       // printf(">>>>(%s)<<<<< args.(%s)\n",databuf,params);
        upload_data.buf = (unsigned char *)databuf;
        upload_data.len = strlen(databuf);
        sprintf(len_hdr, "Content-Length: %lu",(unsigned long)upload_data.len);
        headers = curl_slist_append(NULL,"Expect:");
        headers = curl_slist_append(headers,"Content-type: application/json");
        headers = curl_slist_append(headers,len_hdr);
        curl_easy_setopt(curl_handle,CURLOPT_HTTPHEADER,headers);
    }
    res = curl_easy_perform(curl_handle);
    if ( headers != 0 )
        curl_slist_free_all(headers);
    if ( databuf != 0 )
        free(databuf), databuf = 0;
    if ( res != CURLE_OK )
    {
        fprintf(stderr, "curl_easy_perform() failed: %s %s.(%s %s %s %s)\n",curl_easy_strerror(res),debugstr,url,userpass,command,params);
        if ( command != 0 && params != 0 )
            sleep(delay);
        else sleep(1);
        //delay *= 3;
        if ( numretries-- > 0 )
        {
            free(chunk.memory);
            curl_easy_cleanup(curl_handle);
            //curl_global_cleanup();
            //curl_global_init(CURL_GLOBAL_ALL); //init the curl session
            goto retry;
        }
    }
    else
    {
        // printf("%lu bytes retrieved [%s]\n", (int64_t )chunk.size,chunk.memory);
    }
    elapsedsum += (milliseconds() - starttime);
    curl_easy_cleanup(curl_handle);
    retstr = malloc(strlen(chunk.memory)+1);
    strcpy(retstr,chunk.memory);
    free(chunk.memory);

    count++;
    elapsedsum2 += (milliseconds() - starttime);
#ifndef __APPLE__
    if ( elapsedsum2/count > 1000 && (milliseconds() - starttime) > 1000 )
        fprintf(stderr,"%d: %9.6f %9.6f | elapsed %.3f millis | bitcoind_RPC.(%s)\n",count,elapsedsum/count,elapsedsum2/count,(milliseconds() - starttime),url);
#endif
   // pthread_mutex_unlock(&mutex);
    return(post_process_bitcoind_RPC(debugstr,command,params,retstr));
}