00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 #include <boost/lexical_cast.hpp>
00021 #include <algorithm>
00022 #include "weHelper.h"
00023 #include "weHTTP.h"
00024 #include "weOptions.h"
00025 
00032 WeHttpResponse::WeHttpResponse() :
00033 headers(": ", "[\\n\\r]+"), cookies("=", "; ")
00034 {
00035     curlHandle = NULL;
00036     baseUrl = "";
00037     realUrl = "";
00038     relocCount = 0;
00039     processed = false;
00040     httpCode = 0;
00041     data.clear();
00042     headData.clear();
00043     if (!CurlInit()) {
00044         throw WeError("curl_easy_init failed!");
00045     }
00046 }
00047 
00053 WeHttpResponse::~WeHttpResponse()
00054 {
00055     if (curlHandle != NULL) {
00056         curl_easy_cleanup(curlHandle);
00057     }
00058     headers.Clear();
00059     cookies.Clear();
00060 }
00061 
00069 bool WeHttpResponse::CurlInit( void )
00070 {
00072     if (curlHandle != NULL) {
00073         curl_easy_cleanup(curlHandle);
00074     }
00075 
00076     curlHandle = curl_easy_init();
00077     memset(errorBuff, 0, CURL_ERROR_SIZE);
00078     if (curlHandle == NULL) {
00079         return false;
00080     }
00081     curl_easy_reset(curlHandle);
00082     curl_easy_setopt(curlHandle, CURLOPT_ERRORBUFFER, errorBuff);
00083     curl_easy_setopt(curlHandle, CURLOPT_HTTP_TRANSFER_DECODING, 1);
00084     curl_easy_setopt(curlHandle, CURLOPT_PROXY, "");
00085     curl_easy_setopt(curlHandle, CURLOPT_WRITEFUNCTION, &WeHttpResponse::Receiver);
00086     curl_easy_setopt(curlHandle, CURLOPT_WRITEDATA, this);
00087     curl_easy_setopt(curlHandle, CURLOPT_HEADERFUNCTION, &WeHttpResponse::HeadersRecv);
00088     curl_easy_setopt(curlHandle, CURLOPT_WRITEHEADER, this);
00089     return true;
00090 }
00091 
00092 void WeHttpResponse::CurlSetOpts(WeHttpRequest* req )
00093 {
00094     if (req != NULL) {
00096         curl_easy_setopt(curlHandle, CURLOPT_URL, req->RequestUrl().ToString().c_str());
00097         if (req->Method() == WeHttpRequest::wemGet) {
00098             curl_easy_setopt(curlHandle, CURLOPT_HTTPGET, 1);
00099         }
00100         if (req->Method() == WeHttpRequest::wemPost) {
00101             curl_easy_setopt(curlHandle, CURLOPT_POST, 1);
00102             curl_easy_setopt(curlHandle, CURLOPT_POSTFIELDS, &(req->Data()[0]));
00103             curl_easy_setopt(curlHandle, CURLOPT_POSTFIELDSIZE, req->Data().size());
00104         }
00105         if (req->Method() == WeHttpRequest::wemPut) {
00106             curl_easy_setopt(curlHandle, CURLOPT_UPLOAD, 1);
00107             curl_easy_setopt(curlHandle, CURLOPT_READDATA, &(req->Data()[0]));
00108             curl_easy_setopt(curlHandle, CURLOPT_INFILESIZE, req->Data().size());
00109         }
00110         WeProxy* prx = req->Proxy();
00111         if (prx && prx->proxyAddr.IsValid()) {
00112             curl_easy_setopt(curlHandle, CURLOPT_PROXYTYPE, prx->type);
00113             curl_easy_setopt(curlHandle, CURLOPT_PROXY, prx->proxyAddr.ToString().c_str());
00114         }
00115     }
00116 }
00117 
00118 void WeHttpResponse::Process(iweTransport* proc)
00119 {
00120     char *st;
00121 
00122     if (curlHandle) {
00123         lastError = curl_easy_getinfo(curlHandle, CURLINFO_RESPONSE_CODE, &httpCode);
00124         lastError = curl_easy_getinfo(curlHandle, CURLINFO_EFFECTIVE_URL, &st);
00125         if (lastError == CURLE_OK) {
00126             realUrl = st;
00127             
00128         }
00130         processed = true;
00131     }
00132     data.push_back(0);
00133     headData.push_back(0);
00134     headers.Parse((char*)&headData[0]);
00135     if (proc != NULL) {
00137         if (httpCode >= 300 && httpCode < 400 && proc->IsSet(weoFollowLinks) && relocCount < proc->RelocationCount()) {
00138             
00139             relocCount++;
00140             string url = headers.FindFirst("Location");
00141             if (!url.empty()) {
00143                 headData.clear();
00144                 data.clear();
00145                 proc->Request(url, this);
00146             }
00147         }
00148     }
00149 }
00150 
00164 size_t WeHttpResponse::Receiver( void *ptr, size_t size, size_t nmemb, void *ourpointer )
00165 {
00166     if (ourpointer == NULL)
00167         return 0;
00168 
00169     WeHttpResponse* object = (WeHttpResponse*)ourpointer;
00170     size_t last = object->data.size();
00171     object->data.insert(object->data.end(), (unsigned char*)ptr, (unsigned char*)ptr + (size * nmemb));
00172     return (object->data.size() - last);
00173 }
00174 
00188 size_t WeHttpResponse::HeadersRecv( void *ptr, size_t size, size_t nmemb, void *ourpointer )
00189 {
00190     if (ourpointer == NULL)
00191         return 0;
00192 
00193     WeHttpResponse* object = (WeHttpResponse*)ourpointer;
00194     size_t last = object->headData.size();
00195     object->headData.resize(last + (size * nmemb));
00196     memcpy(&(object->headData[last]), (unsigned char*)ptr, (size * nmemb));
00197     return (object->headData.size() - last);
00198 }