2012-04-08 9 views
1

ich ein Problem mit einem HTTP-Klasse habe ich bekommen habe (und modifiziert aus) http://www.zedwood.com/article/125/cpp-libcurl-static-classRückkehr cURL mit Daten von den letzten Anfragen

Http.h

#ifndef HTTP_H 
#define HTTP_H 

#include <curl/curl.h> 
#include <string> 
#include <map> 

using namespace std; 

class Http { 

    public: 
     Http(){}; 
     ~Http(){}; 

     static string get(const string &url); 
     static string get(const string &url, string referer); 

     static string post(const string &url, map<string, string> params); 
     static string post(const string &url, map<string, string> params, string referer); 

     static string get_current_url(); 
     static string get_last_url(); 

     static void set_proxy(string ip, long port); 
     static void clear_proxy(); 

     static void set_remote_port(long port); 

    private: 
     static string request(const string &url, string referer, bool post, const string &params); 

     static int writer(char *data, size_t size, size_t nmemb, string *buffer); 

     static string urlencode(const string &str); 
     static string dechex(char dec); 
     static string build_param_string(map<string, string> params); 

     static string last_url; 
     static string current_url; 

     static bool use_proxy; 
     static string proxy_ip; 
     static long proxy_port; 

     static double total_to_download; 
     static double now_downloaded; 

     static long remote_port; 

     static string buffer; 
}; 

#endif 

Http.cpp

#include "Http.h" 

using namespace std; 

string Http::last_url; 
string Http::current_url; 

bool Http::use_proxy; 
string Http::proxy_ip; 
long Http::proxy_port; 

long Http::remote_port; 

string Http::get(const string &url){ 
    return request(url, "", false, ""); 
} 

string Http::get(const string &url, string referer){ 
    return request(url, referer, false, ""); 
} 

string Http::post(const string &url, map<string, string> params){ 
    string postdata = build_param_string(params); 

    return request(url, "", true, postdata); 
} 

string Http::post(const string &url, map<string, string> params, string referer){ 
    string postdata = build_param_string(params); 

    return request(url, referer, true, postdata); 
} 

string Http::get_current_url(){ 
    return current_url; 
} 

string Http::get_last_url(){ 
    return last_url; 
} 

void Http::set_proxy(string ip, long port){ 
    use_proxy = true; 
    proxy_ip = ip; 
    proxy_port = port; 
} 

void Http::clear_proxy(){ 
    use_proxy = false; 
} 

void Http::set_remote_port(long port){ 
    remote_port = port; 
} 

string Http::request(const string &url, string referer, bool post, const string &params){ 
    static string buffer = ""; 
    static char error_buffer[CURL_ERROR_SIZE]; 
    error_buffer[0] = 0; 

    CURL *curl; 
    CURLcode result; 

    curl = curl_easy_init(); 

    if(curl){ 
     curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error_buffer); 
     curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); 
     curl_easy_setopt(curl, CURLOPT_HEADER, 0); 
     curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); 
     curl_easy_setopt(curl, CURLOPT_AUTOREFERER, 1); 
     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, Http::writer); 
     curl_easy_setopt(curl, CURLOPT_WRITEDATA, &(buffer)); 
     curl_easy_setopt(curl, CURLOPT_COOKIEFILE, ".cookies.cj"); 
     curl_easy_setopt(curl, CURLOPT_COOKIEJAR, ".cookies.cj"); 
     curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2); 
     curl_easy_setopt(curl, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)"); 

     if(post){ 
      curl_easy_setopt(curl, CURLOPT_POST, 1); 
      curl_easy_setopt(curl, CURLOPT_POSTFIELDS, params.c_str()); 
     } 

     if(referer.length()){ 
      curl_easy_setopt(curl, CURLOPT_REFERER, referer.c_str()); 
     } 

     if(use_proxy){ 
      curl_easy_setopt(curl, CURLOPT_PROXY, proxy_ip.c_str()); 

      if(proxy_port){ 
       curl_easy_setopt(curl, CURLOPT_PROXYPORT, proxy_port); 
      } 
     } 

     if(remote_port){ 
      curl_easy_setopt(curl, CURLOPT_PORT, remote_port); 
     } 

     result = curl_easy_perform(curl); 

     curl_easy_cleanup(curl); 

     if(result == CURLE_OK){ 
      return buffer; 
     } 
     else{ 
      return "error"; 
     } 
    } 

    return "error"; 
} 

int Http::writer(char *data, size_t size, size_t nmemb, string *buffer){ 
    int result = 0; 

    if(buffer != NULL){ 
     buffer->append(data, size * nmemb); 
     result = size * nmemb; 
    } 

    return result; 
} 

string Http::urlencode(const string &str){ 
    string encoded = ""; 

    int max = str.length(); 

    for(int i = 0; i < max; i++){ 
     if(
      (48 <= str[i] && str[i] <= 57) || 
      (65 <= str[i] && str[i] <= 90) || 
      (97 <= str[i] && str[i] <= 122) || 
      (str[i] == '~' || str[i] == '!' || str[i] == '*' || str[i] == '(' || str[i] == ')' || str[i] == '\'') 
     ){ 
      encoded.append(&str[i], 1); 
     } 
     else{ 
      encoded.append("%"); 
      encoded.append(dechex(str[i])); 
     } 
    } 

    return encoded; 
} 

string Http::dechex(char dec){ 
    char dig1 = (dec&0xF0)>>4; 
    char dig2 = (dec&0x0F); 
    if (0<= dig1 && dig1<= 9) dig1+=48; //0,48inascii 
    if (10<= dig1 && dig1<=15) dig1+=97-10; //a,97inascii 
    if (0<= dig2 && dig2<= 9) dig2+=48; 
    if (10<= dig2 && dig2<=15) dig2+=97-10; 

    string r; 
    r.append(&dig1, 1); 
    r.append(&dig2, 1); 
    return r; 
} 

string Http::build_param_string(map<string, string> params){ 
    string param_string = ""; 

    for(map<string, string>::iterator it = params.begin(); it != params.end(); it++){ 
     param_string += it->first + "=" + urlencode(it->second) + "&"; 
    } 

    param_string = param_string.substr(0, param_string.length() - 1); 

    return param_string; 
} 

Was passiert, wenn ich mehr als ein einziger Antrag stellen, die Antwort Rückkehr ed von den Anforderungsfunktionen (.get(); oder .post();) wird nur an die Rückgabedaten aller vorherigen Anfragen angehängt.

Ich glaube, das ist etwas einfaches, das ich vermisse, aber ich kann es nicht herausfinden, nachdem ich in den letzten paar Tagen gegoogelt habe.

Danke.

Antwort

1

Wenn Sie den Puffer in der gleichen Zeile initialisieren:

string Http::request(const string &url, string referer, bool post, const string &params){ 
    static string buffer = ""; 

, dass die Initialisierung nur beim ersten Mal passieren Sie die Funktion ausführen, weil der static Modifikator. Und weil die Schreibfunktion nur Daten in den Puffer anhängt ...

Sie müssen trennen, dass auf zwei Linien, die die Puffer für jeden Durchlauf zurück:

static string buffer; 
buffer.clear(); 
+0

, die perfekt war, wusste, es war etwas albern. Vielen Dank! – Mike

Verwandte Themen