/*
 * Copyright (C) 2009 - 2010 Funambol, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 as published by
 * the Free Software Foundation with the addition of the following permission
 * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
 * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
 * WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
 *
 * 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 Affero General Public License
 * along with this program; if not, see http://www.gnu.org/licenses or write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301 USA.
 *
 * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
 * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
 *
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License version 3.
 *
 * In accordance with Section 7(b) of the GNU Affero General Public License
 * version 3, these Appropriate Legal Notices must retain the display of the
 * "Powered by Funambol" logo. If the display of the logo is not reasonably
 * feasible for technical reasons, the Appropriate Legal Notices must display
 * the words "Powered by Funambol".
 */

#pragma once

#include "http/CurlTransportAgent.h"

namespace Funambol
{

class CurlTransportAgentEx : public CurlTransportAgent
{
public:
    CurlTransportAgentEx (URL& url, Proxy& proxy, unsigned int timeout)
    : Funambol::CurlTransportAgent(url, proxy, timeout)
    {}

    char* query(ArrayList& httpHeaders, long* protocolResponseCode);

};

char* Funambol::CurlTransportAgentEx::query(ArrayList& httpHeaders, long* protocolResponseCode)
{
    if (!easyhandle) {
        setError(ERR_NETWORK_INIT, "libcurl error init error");
        return NULL;
    }

    curl_slist *slist=NULL;
    char *response = NULL;
    CURLcode code;

    if (!httpHeaders.isEmpty())
    {
    	StringBuffer* el = (StringBuffer*)httpHeaders.front();
		while (el)
		{
			slist = curl_slist_append(slist, el->c_str());
			el = (StringBuffer*)httpHeaders.next();
		}
    }
    responsebuffersize = 64 * 1024;
    responsebuffer = new char[responsebuffersize];
    received = 0;
    responsebuffer[0] = 0;
    // todo? url.resource
    const char *certificates = getSSLServerCertificates();
    if ((code = curl_easy_setopt(easyhandle, CURLOPT_HTTPGET, true)) ||
        (code = curl_easy_setopt(easyhandle, CURLOPT_URL, url.fullURL)) ||
        (code = curl_easy_setopt(easyhandle, CURLOPT_HTTPHEADER, slist)) ||
        /*
         * slightly cheating here: when CURLOPT_CAINFO was set before, we don't unset it because
         * we don't know what the default is
         */
        (certificates[0] && (code = curl_easy_setopt(easyhandle, CURLOPT_CAINFO, certificates))) ||
        (code = curl_easy_setopt(easyhandle, CURLOPT_SSL_VERIFYPEER, (long)SSLVerifyServer)) ||
        (code = curl_easy_setopt(easyhandle, CURLOPT_SSL_VERIFYHOST, (long)(SSLVerifyHost ? 2 : 0))) ||
        (code = curl_easy_perform(easyhandle))) {
        delete [] responsebuffer;
        setErrorF(ERR_HTTP, "libcurl error %d, %.250s", code, curlerrortxt);
    } else {
        response = responsebuffer;

    }
    responseSize = received;

    long res_code = 0;
    if (protocolResponseCode)
    {
        *protocolResponseCode = (curl_easy_getinfo(easyhandle, CURLINFO_RESPONSE_CODE, &res_code) == CURLE_OK)
			? res_code : 0;
    }

    responsebuffer = NULL;
    responsebuffersize = 0;

    if (slist) {
        curl_slist_free_all(slist);
    }

    return response;
}

}


