/*
* gaia - opensource 3D interface to the planet
* Copyright (C) 2006 gaia project
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "wwfetch_internal.h"
/**
* Internal function used in curl
*
* Is called when chunk of data is received. Thus, appends it to
* buffer storing curently downloaded file (handle->currentdata)
*
* See libCURL documentation for description.
*/
static size_t wwfetch_curl_writefunction(char *ptr, size_t size, size_t nmemb, void *stream) {
wwfetch *handle = (wwfetch *)stream;
size_t newsize = handle->currentsize + size*nmemb;
unsigned char *newdata = (unsigned char*)realloc((void*)handle->currentdata, newsize);
if (newdata == 0)
return 0;
handle->currentdata = newdata;
memcpy(&handle->currentdata[handle->currentsize], ptr, size*nmemb);
handle->currentsize = newsize;
return size * nmemb;
}
/**
* Internal function to form and execute single HTTP request
*
* @param method request method (METHOD_POST | METHOD_GET)
* @param url full URL for request
* @param postdata (POST only) pointer to data to send to server
* @param postsize (POST only) length of postdata
* @param code address of long to store HTTP response code to
*/
wwfetch_error wwfetch_do_http_request(wwfetch *handle, int method, const char *url, void *postdata, size_t postsize, long *code) {
/* free last downloaded file, if any */
if (handle->currentdata)
free(handle->currentdata);
handle->currentdata = 0;
handle->currentsize = 0;
/* drop all curl headers */
if (handle->curlheaders) {
curl_slist_free_all(handle->curlheaders);
handle->curlheaders = 0;
}
/* reset curl */
curl_easy_reset(handle->curl);
/* init request */
if (method == METHOD_POST) {
if ((handle->lastcurlerror = curl_easy_setopt(handle->curl, CURLOPT_POSTFIELDS, postdata)) != CURLE_OK)
return WWFETCH_CURL_ERROR;
if ((handle->lastcurlerror = curl_easy_setopt(handle->curl, CURLOPT_POSTFIELDSIZE, postsize)) != CURLE_OK)
return WWFETCH_CURL_ERROR;
} else {
if ((handle->lastcurlerror = curl_easy_setopt(handle->curl, CURLOPT_HTTPGET, 1)) != CURLE_OK)
return WWFETCH_CURL_ERROR;
}
/* init headers */
struct curl_slist *tmplist;
/* Connection: */
if ((tmplist = curl_slist_append(handle->curlheaders, "Connection: Keep-Alive")) == 0)
return WWFETCH_MALLOC_FAILED;
handle->curlheaders = tmplist;
/* options */
if ((handle->lastcurlerror = curl_easy_setopt(handle->curl, CURLOPT_HTTPHEADER, handle->curlheaders)) != CURLE_OK)
return WWFETCH_CURL_ERROR;
if ((handle->lastcurlerror = curl_easy_setopt(handle->curl, CURLOPT_USERAGENT, "gaia/%s", GAIA_VERSION)) != CURLE_OK)
return WWFETCH_CURL_ERROR;
if ((handle->lastcurlerror = curl_easy_setopt(handle->curl, CURLOPT_URL, url)) != CURLE_OK)
return WWFETCH_CURL_ERROR;
if ((handle->lastcurlerror = curl_easy_setopt(handle->curl, CURLOPT_TIMEOUT, 30)) != CURLE_OK)
return WWFETCH_CURL_ERROR;
if ((handle->lastcurlerror = curl_easy_setopt(handle->curl, CURLOPT_NOSIGNAL, 1)) != CURLE_OK)
return WWFETCH_CURL_ERROR;
if ((handle->lastcurlerror = curl_easy_setopt(handle->curl, CURLOPT_WRITEFUNCTION, wwfetch_curl_writefunction)) != CURLE_OK)
return WWFETCH_CURL_ERROR;
if ((handle->lastcurlerror = curl_easy_setopt(handle->curl, CURLOPT_WRITEDATA, handle)) != CURLE_OK)
return WWFETCH_CURL_ERROR;
if ((handle->lastcurlerror = curl_easy_perform(handle->curl)) != CURLE_OK)
return WWFETCH_CURL_ERROR;
if ((handle->lastcurlerror = curl_easy_getinfo(handle->curl, CURLINFO_RESPONSE_CODE, code)) != CURLE_OK)
return WWFETCH_CURL_ERROR;
return WWFETCH_OK;
}
syntax highlighted by Code2HTML, v. 0.9.1