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 }