2011-10-21 16 views
9

Ho un'applicazione che ha ricevuto dati tramite richieste HTTP POST. Sto cercando di usare libcurl per aprire una richiesta a questa app, inviare i dati e ricevere la risposta dall'app. Questo è il codice che ho finora:libcurl HTTPS invio dati POST?

int main(void) 
{ 
    CURL *curl; 
    CURLcode res; 

    curl = curl_easy_init(); 
    if(curl) 
    { 
     const int timeout = 30000; 
     char outputmessage[]="VGhpcyBpcyBqdXN0IGEgbWVzc2FnZSwgaXQncyBub3QgdGhlIHJlYWwgdGhpbmc="; 

     curl_easy_setopt(curl, CURLOPT_URL, "https://somehost.com/someapp"); 
     curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); 
     curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); 
     curl_easy_setopt(curl, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.5"); 
     curl_easy_setopt(curl, CURLOPT_POSTFIELDS, outputmessage); 
     curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(outputmessage)); 
     curl_easy_setopt(curl, CURLOPT_POST, 1L); 
     curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout/1000); 

     res = curl_easy_perform(curl); 
     if(CURLE_OK != res) 
     { 
      printf("Error: %s\n", strerror(res)); 
      return 1; 
     } 

     // now what? 

     // cleanup when done 
     curl_easy_cleanup(curl); 
    } 
    return 0; 
} 

Questo si collega essenzialmente al server, ottengo un OK sul curl_easy_perform(). Posso vedere la connessione su Wireshark.

due domande:

1) E 'questo il modo corretto di invio di dati tramite un post, e
2) Come faccio ad avere la risposta dall'applicazione.

Ho pensato di dover usare curl_easy_recv() ma non riesco a vedere come. Qualsiasi codice di esempio è benvenuto. Grazie.

risposta

4

penso che si dovrebbe anche prendere in considerazione l'aggiunta di un gestore per le intestazioni di risposta:

cres = curl_easy_setopt(handle, CURLOPT_HEADERFUNCTION, HandleHeader); 

Può essere che se questo è stato progettato un servizio web per essere utilizzato da un'applicazione, la sua risposta è una risposta di sola intestazione, senza dati di risposta. L'intestazione conterrebbe dati quali:

HTTP/1.1 200 OK ... 

Dove la cosa principale che stai cercando è il codice 200 dicendo che la richiesta era OK.

Le funzioni per gestire i dati dall'intestazione o dalla risposta devono prendere un void * e sarà necessario terminarlo in null se lo si utilizza come stringa. Per informazioni questo è come gestire i dati in ingresso (in questo caso io uso solo il codice di ritorno nella mia applicazione - il corpo della risposta va solo a un file di registro):

static size_t CurlHandleResponse(
    void *Ptr, 
    size_t Size, 
    size_t NoElements, 
    void* Data) 
{ 
    memcpy(&(gData[gDataLen]), Ptr, (Size * NoElements)); 
    gDataLen += (Size * NoElements); 
    gData[ gDataLen ] = '\0'; 
    return (Size * NoElements); 
} 

... 
ConvertUnprintable(gData, PrintStr); 
... 

gestione degli errori rimossa per brevità!

+0

I dati restituiti dall'app si trovano subito dopo il 200 OK. Ho bisogno di leggere l'intestazione per vedere se la richiesta è andata bene, ma poi i dati dopo di essa. Qualche idea? E non per file, ma per un char * –

+0

Per informazioni, dovrebbe essere un vuoto * ptr, non un char * ptr, ma modificherai la mia risposta con il codice che sto usando per gestire la risposta. – asc99c

+0

Capito, grazie. Ora ho bisogno di iniziare a analizzare tutte le informazioni. grazie per l'aiuto –

1

Non è necessario chiamare alcuna funzione di ricezione. La risposta ricevuta ti viene restituita quando il controllo passa al callback scritto in scrittura. Impostare il callback in questo modo:

curl_res = curl_easy_setopt (handle, CURLOPT_WRITEFUNCTION, RecvResponseCallback);

prima di chiamare eseguire.

Definire la richiamata in questo modo:

size_t 
RecvResponseCallback (char *ptr, size_t size, size_t nmemb, char *data) { 
    // handle received data 
    return size * nmemb; 
} 

i dati di risposta è puntato dai dati arg (non ARG PTR, che è un'altra cosa che si desidera guardare quando ottieni questo lavoro).

Quando si esce RecvResponseCallback, essere sicuri di tornare (size_t) size * nmemb

+0

tutti gli argomenti devono essere dichiarati su RecvResponseCallback() –

+0

Quando si imposta quello e io eseguo viene visualizzato "Errore: troppi file aperti nel sistema' –

+0

Qual è il sistema in cui si esegue? Penso che libcurl debba aprire un altro file per il socket di ricezione. Quindi quanti file hai aperto nel tuo programma? –