<?php
//
// @author: Philippe JAUSIONS/11abacus.com (Philippe.Jausions@11abacus.com)
//
// Copyright © 2003 by Philippe JAUSIONS/11abacus.com -- All Rights Reserved
// No use, copy, resale of this code, in parts or in whole, is allowed
// without prior written authorization from the author of this package.
//

// *********************************************************** //
// *********************************************************** //
// **                                                       ** //
// **                                                       ** //
// **                     jd_Curl Class                     ** //
// **                                                       ** //
// **                                                       ** //
// *********************************************************** //
// *********************************************************** //
//
// Methods:
//   - boolean   init(string URL)
//   - array     getError()
//   - void      clearError()
//   - boolean   setopt(constant OPTION_NAME, mixed value)
//   - boolean   setOption(constant OPTION_NAME, mixed value, [mixed 2nd_value])
//   - boolean   init(string URL, constant CURL_type, [string path])
//   - boolean   setType(constant CURL_type, [string path])
//   - string    exec()
//   - void      close()
//   - string    getVersion()
//   - array     getInfo()
//   - string    getResponse()
//   - string    getBody()
//   - array     getHeaders()
//   - array     info()
//   - string    error()
//   - integer   errno()
//
define('CURLTYPE_PHPMODULE''MODULE');
define('CURLTYPE_EXTERNAL',  'COMMAND');
define('CURLTYPE_EMULATE',   'EMULATE');

if (
defined('JD_LIB_DIR')) {
   require_once(
JD_LIB_DIR 'class/jd_page.class.php');
} else {
   require_once(
dirname(__FILE__) . '/jd_page.class.php');
}


// Define CURL option constants if not already defined
// (this could be the case when using an external command
//  for CURL, instead of the PHP extension module)
if (!defined('CURLOPT_BINARYTRANSFER'))  define('CURLOPT_BINARYTRANSFER''CURLOPT_BINARYTRANSFER');
if (!
defined('CURLOPT_CAINFO'))          define('CURLOPT_CAINFO''CURLOPT_CAINFO');
if (!
defined('CURLOPT_CLOSEPOLICY'))     define('CURLOPT_CLOSEPOLICY''CURLOPT_CLOSEPOLICY');
if (!
defined('CURLOPT_CONNECTTIMEOUT'))  define('CURLOPT_CONNECTTIMEOUT''CURLOPT_CONNECTTIMEOUT');
if (!
defined('CURLOPT_COOKIE'))          define('CURLOPT_COOKIE''CURLOPT_COOKIE');
if (!
defined('CURLOPT_COOKIEFILE'))      define('CURLOPT_COOKIEFILE''CURLOPT_COOKIEFILE');
if (!
defined('CURLOPT_COOKIEJAR'))       define('CURLOPT_COOKIEJAR''CURLOPT_COOKIEJAR');
if (!
defined('CURLOPT_CUSTOMREQUEST'))   define('CURLOPT_CUSTOMREQUEST''CURLOPT_CUSTOMREQUEST');
if (!
defined('CURLOPT_EGDSOCKET'))       define('CURLOPT_EGDSOCKET''CURLOPT_EGDSOCKET');
if (!
defined('CURLOPT_FAILONERROR'))     define('CURLOPT_FAILONERROR''CURLOPT_FAILONERROR');
if (!
defined('CURLOPT_FILE'))            define('CURLOPT_FILE''CURLOPT_FILE');
if (!
defined('CURLOPT_FILETIME'))        define('CURLOPT_FILETIME''CURLOPT_FILETIME');
if (!
defined('CURLOPT_FTPAPPEND'))       define('CURLOPT_FTPAPPEND''CURLOPT_FTPAPPEND');
if (!
defined('CURLOPT_FTPASCII'))        define('CURLOPT_FTPASCII''CURLOPT_FTPASCII');
if (!
defined('CURLOPT_FTPLISTONLY'))     define('CURLOPT_FTPLISTONLY''CURLOPT_FTPLISTONLY');
if (!
defined('CURLOPT_FOLLOWLOCATION'))  define('CURLOPT_FOLLOWLOCATION''CURLOPT_FOLLOWLOCATION');
if (!
defined('CURLOPT_FORBID_REUSE'))    define('CURLOPT_FORBID_REUSE''CURLOPT_FORBID_REUSE');
if (!
defined('CURLOPT_FTPPORT'))         define('CURLOPT_FTPPORT''CURLOPT_FTPPORT');
if (!
defined('CURLOPT_FRESH_CONNECT'))   define('CURLOPT_FRESH_CONNECT''CURLOPT_FRESH_CONNECT');
if (!
defined('CURLOPT_HEADER'))          define('CURLOPT_HEADER''CURLOPT_HEADER');
if (!
defined('CURLOPT_HEADERFUNCTION'))  define('CURLOPT_HEADERFUNCTION''CURLOPT_HEADERFUNCTION');
if (!
defined('CURLOPT_HTTPHEADER'))      define('CURLOPT_HTTPHEADER''CURLOPT_HTTPHEADER');
if (!
defined('CURLOPT_HTTPPROXYTUNNEL')) define('CURLOPT_HTTPPROXYTUNNEL''CURLOPT_HTTPPROXYTUNNEL');
if (!
defined('CURLOPT_INFILE'))          define('CURLOPT_INFILE''CURLOPT_INFILE');
if (!
defined('CURLOPT_INFILESIZE'))      define('CURLOPT_INFILESIZE''CURLOPT_INFILESIZE');
if (!
defined('CURLOPT_INTERFACE'))       define('CURLOPT_INTERFACE''CURLOPT_INTERFACE');
if (!
defined('CURLOPT_KRB4LEVEL'))       define('CURLOPT_KRB4LEVEL''CURLOPT_KRB4LEVEL');
if (!
defined('CURLOPT_LOW_SPEED_LIMIT')) define('CURLOPT_LOW_SPEED_LIMIT''CURLOPT_LOW_SPEED_LIMIT');
if (!
defined('CURLOPT_LOW_SPEED_TIME'))  define('CURLOPT_LOW_SPEED_TIME''CURLOPT_LOW_SPEED_TIME');
if (!
defined('CURLOPT_MAXCONNECTS'))     define('CURLOPT_MAXCONNECTS''CURLOPT_MAXCONNECTS');
if (!
defined('CURLOPT_MAXREDIRS'))       define('CURLOPT_MAXREDIRS''CURLOPT_MAXREDIRS');
if (!
defined('CURLOPT_MUTE'))            define('CURLOPT_MUTE''CURLOPT_MUTE');
if (!
defined('CURLOPT_NETRC'))           define('CURLOPT_NETRC''CURLOPT_NETRC');
if (!
defined('CURLOPT_NOBODY'))          define('CURLOPT_NOBODY''CURLOPT_NOBODY');
if (!
defined('CURLOPT_NOPROGRESS'))      define('CURLOPT_NOPROGRESS''CURLOPT_NOPROGRESS');
if (!
defined('CURLOPT_PASSWDFUNCTION'))  define('CURLOPT_PASSWDFUNCTION''CURLOPT_PASSWDFUNCTION');
if (!
defined('CURLOPT_PORT'))            define('CURLOPT_PORT''CURLOPT_PORT');
if (!
defined('CURLOPT_POST'))            define('CURLOPT_POST''CURLOPT_POST');
if (!
defined('CURLOPT_POSTFIELDS'))      define('CURLOPT_POSTFIELDS''CURLOPT_POSTFIELDS');
if (!
defined('CURLOPT_POSTQUOTE'))       define('CURLOPT_POSTQUOTE''CURLOPT_POSTQUOTE');
if (!
defined('CURLOPT_PROXY'))           define('CURLOPT_PROXY''CURLOPT_PROXY');
if (!
defined('CURLOPT_PROXYUSERPWD'))    define('CURLOPT_PROXYUSERPWD''CURLOPT_PROXYUSERPWD');
if (!
defined('CURLOPT_PUT'))             define('CURLOPT_PUT''CURLOPT_PUT');
if (!
defined('CURLOPT_QUOTE'))           define('CURLOPT_QUOTE''CURLOPT_QUOTE');
if (!
defined('CURLOPT_RANDOM_FILE'))     define('CURLOPT_RANDOM_FILE''CURLOPT_RANDOM_FILE');
if (!
defined('CURLOPT_RANGE'))           define('CURLOPT_RANGE''CURLOPT_RANGE');
if (!
defined('CURLOPT_REFERER'))         define('CURLOPT_REFERER''CURLOPT_REFERER');
if (!
defined('CURLOPT_RESUME_FROM'))     define('CURLOPT_RESUME_FROM''CURLOPT_RESUME_FROM');
if (!
defined('CURLOPT_RETURNTRANSFER'))  define('CURLOPT_RETURNTRANSFER''CURLOPT_RETURNTRANSFER');
if (!
defined('CURLOPT_READFUNCTION'))    define('CURLOPT_READFUNCTION''CURLOPT_READFUNCTION');
if (!
defined('CURLOPT_SSLCERT'))         define('CURLOPT_SSLCERT''CURLOPT_SSLCERT');
if (!
defined('CURLOPT_SSLCERTPASSWD'))   define('CURLOPT_SSLCERTPASSWD''CURLOPT_SSLCERTPASSWD');
if (!
defined('CURLOPT_SSL_CIPHER_LIST')) define('CURLOPT_SSL_CIPHER_LIST''CURLOPT_SSL_CIPHER_LIST');
if (!
defined('CURLOPT_SSL_VERIFYHOST'))  define('CURLOPT_SSL_VERIFYHOST''CURLOPT_SSL_VERIFYHOST');
if (!
defined('CURLOPT_SSL_VERIFYPEER'))  define('CURLOPT_SSL_VERIFYPEER''CURLOPT_SSL_VERIFYPEER');
if (!
defined('CURLOPT_SSLVERSION'))      define('CURLOPT_SSLVERSION''CURLOPT_SSLVERSION');
if (!
defined('CURLOPT_STDERR'))          define('CURLOPT_STDERR''CURLOPT_STDERR');
if (!
defined('CURLOPT_TIMECONDITION'))   define('CURLOPT_TIMECONDITION''CURLOPT_TIMECONDITION');
if (!
defined('CURLOPT_TIMEOUT'))         define('CURLOPT_TIMEOUT''CURLOPT_TIMEOUT');
if (!
defined('CURLOPT_TIMEVALUE'))       define('CURLOPT_TIMEVALUE''CURLOPT_TIMEVALUE');
if (!
defined('CURLOPT_TRANSFERTEXT'))    define('CURLOPT_TRANSFERTEXT''CURLOPT_TRANSFERTEXT');
if (!
defined('CURLOPT_UPLOAD'))          define('CURLOPT_UPLOAD''CURLOPT_UPLOAD');
if (!
defined('CURLOPT_URL'))             define('CURLOPT_URL''CURLOPT_URL');
if (!
defined('CURLOPT_USERAGENT'))       define('CURLOPT_USERAGENT''CURLOPT_USERAGENT');
if (!
defined('CURLOPT_USERPWD'))         define('CURLOPT_USERPWD''CURLOPT_USERPWD');
if (!
defined('CURLOPT_VERBOSE'))         define('CURLOPT_VERBOSE''CURLOPT_VERBOSE');
if (!
defined('CURLOPT_WRITEFUNCTION'))   define('CURLOPT_WRITEFUNCTION''CURLOPT_WRITEFUNCTION');
if (!
defined('CURLOPT_WRITEHEADER'))     define('CURLOPT_WRITEHEADER''CURLOPT_WRITEHEADER');

// CURL close policies
if (!defined('CURLCLOSEPOLICY_CALLBACK'))            define('CURLCLOSEPOLICY_CALLBACK''CURLCLOSEPOLICY_CALLBACK');
if (!
defined('CURLCLOSEPOLICY_LEAST_RECENTLY_USED')) define('CURLCLOSEPOLICY_LEAST_RECENTLY_USED''CURLCLOSEPOLICY_LEAST_RECENTLY_USED');
if (!
defined('CURLCLOSEPOLICY_LEAST_TRAFFIC'))       define('CURLCLOSEPOLICY_LEAST_TRAFFIC''CURLCLOSEPOLICY_LEAST_TRAFFIC');
if (!
defined('CURLCLOSEPOLICY_SLOWEST'))             define('CURLCLOSEPOLICY_SLOWEST''CURLCLOSEPOLICY_SLOWEST');
if (!
defined('CURLCLOSEPOLICY_OLDEST'))              define('CURLCLOSEPOLICY_OLDEST''CURLCLOSEPOLICY_OLDEST');

// CURL Info flag (for getinfo function)
if (!defined('CURLINFO_CONNECT_TIME'))            define('CURLINFO_CONNECT_TIME''CURLINFO_CONNECT_TIME');
if (!
defined('CURLINFO_CONTENT_LENGTH_DOWNLOAD')) define('CURLINFO_CONTENT_LENGTH_DOWNLOAD''CURLINFO_CONTENT_LENGTH_DOWNLOAD');
if (!
defined('CURLINFO_CONTENT_LENGTH_UPLOAD'))   define('CURLINFO_CONTENT_LENGTH_UPLOAD''CURLINFO_CONTENT_LENGTH_UPLOAD');
if (!
defined('CURLINFO_EFFECTIVE_URL'))           define('CURLINFO_EFFECTIVE_URL''CURLINFO_EFFECTIVE_URL');
if (!
defined('CURLINFO_FILETIME'))                define('CURLINFO_FILETIME''CURLINFO_FILETIME');
if (!
defined('CURLINFO_HEADER_SIZE'))             define('CURLINFO_HEADER_SIZE''CURLINFO_HEADER_SIZE');
if (!
defined('CURLINFO_HTTP_CODE'))               define('CURLINFO_HTTP_CODE''CURLINFO_HTTP_CODE');
if (!
defined('CURLINFO_NAMELOOKUP_TIME'))         define('CURLINFO_NAMELOOKUP_TIME''CURLINFO_NAMELOOKUP_TIME');
if (!
defined('CURLINFO_PRETRANSFER_TIME'))        define('CURLINFO_PRETRANSFER_TIME''CURLINFO_PRETRANSFER_TIME');
if (!
defined('CURLINFO_REQUEST_SIZE'))            define('CURLINFO_REQUEST_SIZE''CURLINFO_REQUEST_SIZE');
if (!
defined('CURLINFO_SIZE_DOWNLOAD'))           define('CURLINFO_SIZE_DOWNLOAD''CURLINFO_SIZE_DOWNLOAD');
if (!
defined('CURLINFO_SIZE_UPLOAD'))             define('CURLINFO_SIZE_UPLOAD''CURLINFO_SIZE_UPLOAD');
if (!
defined('CURLINFO_SPEED_DOWNLOAD'))          define('CURLINFO_SPEED_DOWNLOAD''CURLINFO_SPEED_DOWNLOAD');
if (!
defined('CURLINFO_SPEED_UPLOAD'))            define('CURLINFO_SPEED_UPLOAD''CURLINFO_SPEED_UPLOAD');
if (!
defined('CURLINFO_SSL_VERIFYRESULT'))        define('CURLINFO_SSL_VERIFYRESULT''CURLINFO_SSL_VERIFYRESULT');
if (!
defined('CURLINFO_TOTAL_TIME'))              define('CURLINFO_TOTAL_TIME''CURLINFO_TOTAL_TIME');

// CURL error codes
if (!defined('CURLE_ABORTED_BY_CALLBACK'))    define('CURLE_ABORTED_BY_CALLBACK',    42);
if (!
defined('CURLE_BAD_CALLING_ORDER'))      define('CURLE_BAD_CALLING_ORDER',      44);
if (!
defined('CURLE_BAD_CONTENT_ENCODING'))   define('CURLE_BAD_CONTENT_ENCODING',   61);
if (!
defined('CURLE_BAD_DOWNLOAD_RESUME'))    define('CURLE_BAD_DOWNLOAD_RESUME',    36);
if (!
defined('CURLE_BAD_FUNCTION_ARGUMENT'))  define('CURLE_BAD_FUNCTION_ARGUMENT',  43);
if (!
defined('CURLE_BAD_PASSWORD_ENTERED'))   define('CURLE_BAD_PASSWORD_ENTERED',   46);
if (!
defined('CURLE_COULDNT_CONNECT'))        define('CURLE_COULDNT_CONNECT',         7);
if (!
defined('CURLE_COULDNT_RESOLVE_HOST'))   define('CURLE_COULDNT_RESOLVE_HOST',    6);
if (!
defined('CURLE_COULDNT_RESOLVE_PROXY'))  define('CURLE_COULDNT_RESOLVE_PROXY',   5);
if (!
defined('CURLE_FAILED_INIT'))            define('CURLE_FAILED_INIT',             2);
if (!
defined('CURLE_FILE_COULDNT_READ_FILE')) define('CURLE_FILE_COULDNT_READ_FILE'37);
if (!
defined('CURLE_FTP_ACCESS_DENIED'))      define('CURLE_FTP_ACCESS_DENIED',       9);
if (!
defined('CURLE_FTP_CANT_GET_HOST'))      define('CURLE_FTP_CANT_GET_HOST',      15);
if (!
defined('CURLE_FTP_CANT_RECONNECT'))     define('CURLE_FTP_CANT_RECONNECT',     16);
if (!
defined('CURLE_FTP_COULDNT_RETR_FILE'))  define('CURLE_FTP_COULDNT_RETR_FILE',  19);
if (!
defined('CURLE_FTP_COULDNT_SET_BINARY')) define('CURLE_FTP_COULDNT_SET_BINARY'17);
if (!
defined('CURLE_FTP_PORT_FAILED'))        define('CURLE_FTP_PORT_FAILED',        30);
if (!
defined('CURLE_FTP_QUOTE_ERROR'))        define('CURLE_FTP_QUOTE_ERROR',        21);
if (!
defined('CURLE_FTP_COULDNT_GET_SIZE'))   define('CURLE_FTP_COULDNT_GET_SIZE',   32);
if (!
defined('CURLE_FTP_COULDNT_SET_ASCII'))  define('CURLE_FTP_COULDNT_SET_ASCII',  29);
if (!
defined('CURLE_FTP_COULDNT_STOR_FILE'))  define('CURLE_FTP_COULDNT_STOR_FILE',  25);
if (!
defined('CURLE_FTP_COULDNT_USE_REST'))   define('CURLE_FTP_COULDNT_USE_REST',   31);
if (!
defined('CURLE_FTP_USER_PASSWORD_INCORRECT'))
                                             
define('CURLE_FTP_USER_PASSWORD_INCORRECT'10);
if (!
defined('CURLE_FTP_WEIRD_227_FORMAT'))   define('CURLE_FTP_WEIRD_227_FORMAT',   14);
if (!
defined('CURLE_FTP_WEIRD_PASS_REPLY'))   define('CURLE_FTP_WEIRD_PASS_REPLY',   11);
if (!
defined('CURLE_FTP_WEIRD_PASV_REPLY'))   define('CURLE_FTP_WEIRD_PASV_REPLY',   13);
if (!
defined('CURLE_FTP_WEIRD_SERVER_REPLY')) define('CURLE_FTP_WEIRD_SERVER_REPLY',  8);
if (!
defined('CURLE_FTP_WEIRD_USER_REPLY'))   define('CURLE_FTP_WEIRD_USER_REPLY',   12);
if (!
defined('CURLE_FTP_WRITE_ERROR'))        define('CURLE_FTP_WRITE_ERROR',        20);
if (!
defined('CURLE_FUNCTION_NOT_FOUND'))     define('CURLE_FUNCTION_NOT_FOUND',     41);
if (!
defined('CURLE_GOT_NOTHING'))            define('CURLE_GOT_NOTHING',            52);
if (!
defined('CURLE_HTTP_RANGE_ERROR'))       define('CURLE_HTTP_RANGE_ERROR',       33);
if (!
defined('CURLE_HTTP_RETURNED_ERROR'))    define('CURLE_HTTP_RETURNED_ERROR',    22);
if (!
defined('CURLE_HTTP_POST_ERROR'))        define('CURLE_HTTP_POST_ERROR',        34);
if (!
defined('CURLE_HTTP_PORT_FAILED'))       define('CURLE_HTTP_PORT_FAILED',       45);
if (!
defined('CURLE_LDAP_CANNOT_BIND'))       define('CURLE_LDAP_CANNOT_BIND',       38);
if (!
defined('CURLE_LDAP_SEARCH_FAILED'))     define('CURLE_LDAP_SEARCH_FAILED',     39);
if (!
defined('CURLE_LIBRARY_NOT_FOUND'))      define('CURLE_LIBRARY_NOT_FOUND',      40);
if (!
defined('CURLE_MALFORMAT_USER'))         define('CURLE_MALFORMAT_USER',         24);
if (!
defined('CURLE_OBSOLETE'))               define('CURLE_OBSOLETE',               50);
if (!
defined('CURLE_OK'))                     define('CURLE_OK'0);
if (!
defined('CURLE_OPERATION_TIMEOUTED'))    define('CURLE_OPERATION_TIMEOUTED',    28);
if (!
defined('CURLE_OUT_OF_MEMORY'))          define('CURLE_OUT_OF_MEMORY',          27);
if (!
defined('CURLE_PARTIAL_FILE'))           define('CURLE_PARTIAL_FILE',           18);
if (!
defined('CURLE_READ_ERROR'))             define('CURLE_READ_ERROR',             26);
if (!
defined('CURLE_RECV_ERROR'))             define('CURLE_RECV_ERROR',             56);
if (!
defined('CURLE_SHARE_IN_USE'))           define('CURLE_SHARE_IN_USE',           57);
if (!
defined('CURLE_SSL_CONNECT_ERROR'))      define('CURLE_SSL_CONNECT_ERROR',      35);
if (!
defined('CURLE_SSL_PEER_CERTIFICATE'))   define('CURLE_SSL_PEER_CERTIFICATE',   51);
if (!
defined('CURLE_SSL_ENGINE_NOTFOUND'))    define('CURLE_SSL_ENGINE_NOTFOUND',    53);
if (!
defined('CURLE_SSL_CERTPROBLEM'))        define('CURLE_SSL_CERTPROBLEM',        58);
if (!
defined('CURLE_SSL_CIPHER'))             define('CURLE_SSL_CIPHER',             59);
if (!
defined('CURLE_SSL_CACERT'))             define('CURLE_SSL_CACERT',             60);
if (!
defined('CURLE_SSL_ENGINE_SETFAILED'))   define('CURLE_SSL_ENGINE_SETFAILED',   54);
if (!
defined('CURLE_SEND_ERROR'))             define('CURLE_SEND_ERROR',             55);
if (!
defined('CURLE_TELNET_OPTION_SYNTAX'))   define('CURLE_TELNET_OPTION_SYNTAX',   49);
if (!
defined('CURLE_TOO_MANY_REDIRECTS'))     define('CURLE_TOO_MANY_REDIRECTS',     47);
if (!
defined('CURLE_UNKNOWN_TELNET_OPTION'))  define('CURLE_UNKNOWN_TELNET_OPTION',  48);
if (!
defined('CURLE_UNSUPPORTED_PROTOCOL'))   define('CURLE_UNSUPPORTED_PROTOCOL',    1);
if (!
defined('CURLE_URL_MALFORMAT'))          define('CURLE_URL_MALFORMAT',           3);
if (!
defined('CURLE_URL_MALFORMAT_USER'))     define('CURLE_URL_MALFORMAT_USER',      4);
if (!
defined('CURLE_WRITE_ERROR'))            define('CURLE_WRITE_ERROR',            23);

if (!
defined('TIMECOND_IFMODSINCE'))          define('TIMECOND_IFMODSINCE''TIMECOND_IFMODSINCE');
if (!
defined('TIMECOND_IFUNMODSINCE'))        define('TIMECOND_IFUNMODSINCE''TIMECOND_IFUNMODSINCE');


/**
 * CURL class wrapper for extension or external command, with CURL simulator
 **/
class jd_Curl extends jd_Page {

    
// CURL properties
    
var $_resource;
    var 
$_path// PHP module or system command
    
var $_pathOk;
    var 
$_url;
    var 
$_options;

    
// Processing result
    
var $_response;
    var 
$_info;
    var 
$_headers;
    var 
$_body;

    
// Processing tracking
    
var $_ranAt;


    
// Type of CURL (module, external or emulate)
    
var $_type;


    
// For CURL emulator we need to keep extra info
    /**
     * Information on operation
     **/
    
var $_info;

    
/**
     * Connection information
     **/
    
var $_connect;

    
/**
     * Class constructor (for compatibility with PHP 4)
     *
     * See __construct()
     *
     * @param 2-letter language code
     **/
    
function jd_Curl($sLang 'en') {
        
$this->__construct($sLang);

    } 
// End [FUNCTION] jd_Curl Constructor class
    // ------------------------------------------------------


    /**
     * Class constructor
     *
     * @param 2-letter language code
     **/
    
function __construct($sLang 'en') {
        
$this->_url '';

        
parent::__construct($sLang);

        
// PHP module, external command or emulate?
        
$this->_path '';
        
$this->_type null;

        
// Path to CURL bin or PHP module not verified
        
$this->_pathOk false;

        
// Initialize other variables
        
$this->_options = array();

        
$this->_response '';
        
$this->_info = array();
        
$this->_headers = array();
        
$this->_ranAt 0;

        
$this->_connect = array();

        
// Keep various piece of information (mostly for CURL emulator)
        
$this->_info = array();

    } 
// End [FUNCTION] jd_Curl Constructor class
    // ------------------------------------------------------


    // ------------------------------------------------------
    //
    // Method: exec
    //
    // Description:
    //   Run the CURL as prepared
    //
    // Synopsis:
    //   $oCURL->exec();
    //
    // Returns:
    //   The result of the CURL query on success, or FALSE on
    //   error.
    //
    // ------------------------------------------------------
    
function exec() {
        
// Initialize
        
$this->_response '';
        
$this->_headers  = array();
        
$this->_info     = array();

        
// Is everything fine?
        
if (!$this->_pathOk) {
            
$this->_setError('Object not initialized, use init() or setType() method.'1__FILE____LINE__);
            return 
false;
        }

        
// Output or return value?
        
$bOutput = (isset($this->_options[CURLOPT_RETURNTRANSFER])
                    && !
$this->_options[CURLOPT_RETURNTRANSFER]);

        
// Depending on method (module vs. command)
        // we run the CURL query differently
        
if ($this->_type == CURLTYPE_PHPMODULE) {

            
// +-+-+-+-+-+-+-+-+-+-+-+-+
            // CURL as PHP module
            // +-+-+-+-+-+-+-+-+-+-+-+-+

            // Prepare CURL thing
            
if (!($oCH curl_init($this->_url))) {
                
$this->_setError(curl_error($oCH), curl_errno($oCH), __FILE____LINE__);
                return 
false;

            }

            
// Add the options
            
foreach ($this->_options as $cOption => $vValue) {
                if (!
curl_setopt($oCH$cOption$vValue)) {
                    
$this->_setError(curl_error($oCH), curl_errno($oCH), __FILE____LINE__);
                    return 
false;
                }
            }

            
// If we return the result instead of ouput
            // fine tune the CURL object
            
if (!$bOutput) {
                
// Force to get HTTP headers so we always know what's going on.
                // If the user didn't want them then we'll send the
                // body of the response instead of the whole answer.)
                
curl_setopt($oCHCURLOPT_HEADER1);
                
// Same for body
                
curl_setopt($oCHCURLOPT_NOBODY0);
//              jd_Debug::output('FORCED HEADER AND BODY CAPTURE');
            
}

            
// Contact server and get answer
            
if (($this->_response curl_exec($oCH)) === false
                 
|| !($this->_info curl_getinfo($oCH))) {
                
$this->_setError(curl_error($oCH), curl_errno($oCH), __FILE____LINE__);
                
jd_Debug::output($this->getError());
                return 
false;
            }

        } elseif (
$this->_type == CURLTYPE_EMULATE) {
            
// +-+-+-+-+-+-+-+-+-+-+-+-+
            // Emulate CURL
            // +-+-+-+-+-+-+-+-+-+-+-+-+
            
$this->_info[CURLINFO_TOTAL_TIME] = $this->_info[CURLINFO_PRETRANSFER_TIME] = 0;
            
// To handle redirection
            
$bDestinationReached true;

            do {
               if (
$this->_verifyURL($this->_url) === false
                   
|| ($sHeaders $this->_prepareHTTPHeaders()) === false) {
                  return 
false;
               }

               
// Keep track of some information
               
$this->_info[CURLINFO_EFFECTIVE_URL] = $this->_url;
               
$this->_info[CURLINFO_TOTAL_TIME] = ($this->_info[CURLINFO_PRETRANSFER_TIME] += $this->_info[CURLINFO_NAMELOOKUP_TIME]);

               
$dThen microtime();
               if (isset(
$this->_option[CURLOPT_TIMEOUT])
                   && 
$this->_option[CURLOPT_TIMEOUT] > 0) {
                  
$iTimeout $this->_option[CURLOPT_TIMEOUT];
                  
$fp fsockopen($this->_connect['host'], $this->_connect['port'], $sError$iError$iTimeout);

               } else {
                  
$iTimeout null;
                  
$fp fsockopen($this->_connect['host'], $this->_connect['port'], $sError$iError);
               }

               
// Keep track of various times
               
$this->_info[CURLINFO_CONNECT_TIME] = (microtime() - $dThen) / 1000;
               
$this->_info[CURLINFO_TOTAL_TIME] = ($this->_info[CURLINFO_PRETRANSFER_TIME] += $this->_info[CURLINFO_CONNECT_TIME]);

               if (
$fp == false) {
                  
$this->_setError($sError, ($iError == 0) ? CURLE_FAILED_INIT CURLE_COULDNT_CONNECT__FILE____LINE__);
                  return 
false;
               }

               
$dThen microtime();
               if ((
$this->_info[CURLINFO_SIZE_UPLOAD] = fwrite($fp$sHeaders "\r\n" $this->_prepareBody())) === false) {
                  
$this->_setError('Problem while sending data to server.'CURLE_WRITE_ERROR__FILE____LINE__);
                  
fclose($fp);
                  return 
false;
               }
               
$dElapsed = (microtime() - $dThen) / 1000;
               
$this->_info[CURLINFO_SPEED_UPLOAD] = $this->_info[CURLINFO_SIZE_UPLOAD] / $dElapsed;
               
$this->_info[CURLINFO_TOTAL_TIME] += $dElapsed;

               
$dThen microtime();
               
// Buffer the result (fastest solution to read socket)
               
ob_start();
               if (
fpassthru($fp) === false) {
                  
$this->_setError('Problem while reading data from server.'CURLE_READ_ERROR__FILE____LINE__);
               }
               
$dElapsed = (microtime() - $dThen) / 1000;
               
$this->_response ob_get_contents();
               
$this->_info[CURLINFO_SPEED_DOWNLOAD] = strlen($this->_response) / $dElapsed;
               
$this->_info[CURLINFO_TOTAL_TIME] += $dElapsed;

               
ob_end_clean();
               
$aSocketStatus socket_get_status($fp);
               
fclose($fp);
               if (
$this->hasError()) {
                  if (
$aSocketStatus['timed_out']) {
                     
$this->_setError('Connection timed out'CURLE_TIMEOUTED__FILE____LINE__);
                  }
                  return 
false;
               }

               
// Get the HTTP code

               // Follow redirection?
               
if (isset($this->_option[CURLOPT_FOLLOWLOCATION])
                   && 
$this->_option[CURLOPT_FOLLOWLOCATION]
                   && 
$this->_info[CURLINFO_HTTP_CODE] == 300) {
                  
$bDestinationReached false;
               }

            } while (!
$bDestinationReached);

        } elseif (
$this->_type == CURLTYPE_EXTERNAL) {
            
// +-+-+-+-+-+-+-+-+-+-+-+-+
            // CURL as External command
            // +-+-+-+-+-+-+-+-+-+-+-+-+
            
$this->_setError('Not implemented yet'1__FILE____LINE__);
            return 
false;

        } else {
            
// +-+-+-+-+-+-+-+-+-+-+-+-+
            // CURL as Unknown
            // +-+-+-+-+-+-+-+-+-+-+-+-+
            
$this->_setError('Unknown CURL type.'1__FILE____LINE__);
            return 
false;
        }

        
// Ok, the query ran successfully
        
$this->_ranAt time();

        
// Set the "body" and "headers" properties (if any)
        //
        // Note: There may be some instance where headers delimiters
        //       are not "\r\n" (Windows, Mac?) but we don't handle them
        //       here. Just be aware that there may be a problem...
        //
        
if (strpos($this->_response"\r\n\r\n") !== false) {
            
//jd_Debug::output('Found HTTP headers');

            // Get the headers and body
            
$aPage explode("\r\n\r\n"$this->_response2);

            
$this->_body $aPage[1];

            
// make an array of all the HTTP headers
            
$this->_headers explode("\r\n"$aPage[0]);

        } else {
            
//jd_Debug::output('NO HTTP headers found');

            // No headers found
            
$this->_body $this->_response;
        }

//      jd_Debug::output("-------------- HTTP HEADERS ----------------\r\n");
//      jd_Debug::output($this->_headers);
//      jd_Debug::output("-------------- HTTP HEADERS ----------------\r\n");
//      jd_Debug::output("--------------- HTML BODY -----------------\r\n");
//      jd_Debug::output($this->_body);
//      jd_Debug::output("--------------- HTML BODY -----------------\r\n");
//      jd_Debug::output("--------------- WHOLE RESPONSE -----------------\r\n");
//      jd_Debug::output($this->_response);
//      jd_Debug::output("--------------- WHOLE RESPONSE -----------------\r\n");

        // HTTP request Ok?
        
if ($this->_info['http_code'] >= 400) {
            
$this->_setError('HTTP error'$this->_info['http_code'], __FILE____LINE__);
            return 
false;
        }

        
// Done. Everything's fine
        
$this->clearError();

        
// Depending on several options, we return different things
        
if (isset($this->_options[CURLOPT_HEADER])
            && 
$this->_options[CURLOPT_HEADER]) {
            
// We wanted the HTTP headers returned
            
if (isset($this->_options[CURLOPT_NOBODY])
               && 
$this->_options[CURLOPT_NOBODY]) {
                
// We didn't want the body of the return
                
if ($bOutput) {
//                  echo implode("\r\n", $this->_headers);
                    
return true;

                } else {
                    return 
implode("\r\n"$this->_headers);
                }

            } else {
                
// We also wanted the body to be returned
                // Simply return the whole response
                
if ($bOutput) {
//                  echo $this->_response;
                    
return true;

                } else {
                    return 
$this->_response;
                }
            }
        } else if (!isset(
$this->_options[CURLOPT_NOBODY])
                   || !
$this->_options[CURLOPT_NOBODY]) {
            
// We didn't want the HTTP headers, but yes to the body part
            
if ($bOutput) {
//              echo $this->_body;
                
return true;

            } else {
                return 
$this->_body;
            }

        } 
// End [IF]

        // We didn't want anything (HTTP headers nor body)
        
return ($bOutput) ? true '';

    } 
// End [FUNCTION] jd_Curl::exec method
    // ------------------------------------------------------


    // ------------------------------------------------------
    //
    // Method: init
    //
    // ------------------------------------------------------
    
function init($sURL$cType CURLTYPE_PHPMODULE$sPath '') {
        
$this->_url $sURL;

        
// Initialize the path to binary or as PHP module
        
if ($cType == CURLTYPE_PHPMODULE) {
            
// PHP module loaded?
            
return $this->setType(CURLTYPE_PHPMODULE);

        } else if (
$cType == CURLTYPE_EXTERNAL) {
            
// External CURL binary
            
return $this->setType(CURLTYPE_EXTERNAL$sPath);

        } else if (
$cType == CURLTYPE_EMULATE) {
            
// Emulate CURL
            
return $this->setType(CURLTYPE_EMULATE);

        } else if (
$cType != '') {
            
$this->_setError('Unknown method'1__FILE____LINE__);
            return 
false;
        }

        return 
true;

    } 
// End [FUNCTION] jd_Curl::init method
    // ------------------------------------------------------


    // ------------------------------------------------------
    //
    // Method: getVersion
    //
    // ------------------------------------------------------
    
function getVersion() {
        
// Verify it's initialized Ok
        
if (!$this->_pathOk) {
            
$this->_setError('Object not initialized, use init() or setType() method.'1__FILE____LINE__);
            return 
false;
        }

        
// Depending on PHP module or external binary we check
        // for version differently
        
if ($this->path == '') {
            
// PHP module
            
return curl_version();

        } else {
            
// CURL as external command
            
return 'getVersion(): Not implemented yet for external CURL binary';
        }

    } 
// End [FUNCTION] jd_Curl::getVersion method
    // ------------------------------------------------------


    /**
     * Set the CURL type
     *
     * Depending on your PHP and system installation you can use either
     * one of the following CURL type:
     *  - CURLTYPE_PHPMODULE: PHP extension
     *  - CURLTYPE_EXTERNAL : External CURL command
     *  - CURLTYPE_EMULATE  : CURL emulation (limited features.)
     * If you set the type to CURLTYPE_PHPMODULE but the module doesn't exist
     * or cannot be dynamically loaded, the CURLTYPE_EMULATE will be used
     * instead. Note that CURLTYPE_EMULATE has a limited set of features.
     *
     * @param string CURLTYPE_PHPMODULE, CURLTYPE_EXTERNAL or CURLTYPE_EMULATE
     * @param string Path to CURL binary (to be used with CURLTYPE_EXTERNAL)
     **/
    
function setType($cType$sPath '') {
        
$this->_type $cType;
        switch (
$cType) {
            case 
CURLTYPE_PHPMODULE:
               
// If no path is set, we consider we'll use CURL as
               // a PHP module.
               
$this->_path '';
               
$this->_pathOk true;

               
// Is the CURL extension available?
               // Can we dynamically load the library?
               // Safe mode must be turned OFF and this must be a CGI/CLI
               
if (!extension_loaded('curl')
                   && (
ini_get('safe_mode')
                       || (
php_sapi_name() != 'cgi' && php_sapi_name() != 'cli')
                       || !@
dl('php_curl.' . ((strpos(PHP_OS'WIN') >= 0) ? 'dll' 'so')))) {

                  
// Default to CURL emulator mode when extension
                  // not available and cannot load lib dynamically
                  
$this->_type CURLTYPE_EMULATE;
               }
               break;

            case 
CURLTYPE_EXTERNAL:
                
// Save path to CURL bin
                
$this->_path $sPath;

                
// Verify the path exists
                
if (!($this->_pathOk file_exists($sPath))) {
                    
$this->_setError('CURL binary not found.'1__FILE____LINE__);
                    return 
false;
                }
                break;

            case 
CURLTYPE_EMULATE:
                
$this->_path '';
                
$this->_pathOk true;
                break;

            default:
                
$this->_pathOk false;
                
$this->_setError('Unknown type'1__FILE____LINE__);
                return 
false;

        } 
// End [SWITCH] on CURL type

        
return true;

    } 
// End [FUNCTION] jd_Curl::setType method
    // ------------------------------------------------------


    // ------------------------------------------------------
    //
    // Method: setOption
    //
    // ------------------------------------------------------
    
function setOption($cOption$vValue1$vValue2 '') {
        
// Check some options
        
switch ($cOption) {
            case 
CURLOPT_POSTFIELDS:
                
// POST field passed as an array (field name => value)?
                
if (is_array($vValue1)) {
                    
$vSet '';
                    foreach (
$vValue1 as $sName => $vValue) {
                        
$vSet .= rawurlencode($sName) . '=' rawurlencode($vValue) . '&';
                    }

                } else if (
$vValue2 != '') {
                    
// Values passed are vValue1 is name of field
                    // and vValue2 its value
                    
$vSet = ((isset($this->_options[CURLOPT_POSTFIELDS])) ? $this->_options[CURLOPT_POSTFIELDS] : '') . rawurlencode($vValue1) . '=' rawurlencode($vValue2) . '&';

                } else {
                    
// A "regular" CURL Post fields option value was passed
                    
$vSet $vValue1;
                }
                break;

            case 
CURLOPT_COOKIE:
                
// Cookies as an array (cookie name => value)?
                
if (is_array($vValue1)) {
                    
$vSet '';
                    foreach (
$vValue1 as $sName => $vValue) {
                        
$vSet .= rawurlencode($sName) . '=' rawurlencode($vValue) . ';';
                    }

                } else if (
$vValue2 != '') {
                    
// Values passed are vValue1 is name of cookie
                    // and vValue2 its value
                    
$vSet = ((isset($this->_options[CURLOPT_COOKIE])) ? $this->_options[CURLOPT_COOKIE] : '') . rawurlencode($vValue1) . '=' rawurlencode($vValue2) . ';';

                } else {
                    
// A "regular" CURL Post fields option value was passed
                    
$vSet $vValue1;
                }
                break;

            case 
CURLOPT_USERPWD:
            case 
CURLOPT_PROXYUSERPWD:
                if (
$vValue2 != '') {
                    
// User name and password passed separately
                    
$vSet $vValue1 ':' $vValue2;
                } else {
                    
// A "regular" CURL username:password was passed
                    
$vSet $vValue1;
                }
                break;

            case 
CURLOPT_HTTPHEADER:
            case 
CURLOPT_QUOTE:
            case 
CURLOPT_POSTQUOTE:
                if (!
is_array($vValue1)) {
                    
$this->_setError('Expected array for value'1__FILE____LINE__);
                    return 
false;
                }
                
// Note: we intentionally didn't put a "break" here

            
default:
                
// For other options, just set it like that
                
$this->_options[$cOption] = $vValue1;
                return 
true;

        } 
// End [SWITCH] on special options

        // Set the value of special options
        
$this->_options[$cOption] = $vSet;

        return 
true;

    } 
// End [FUNCTION] jd_Curl::setOption method
    // ------------------------------------------------------


    // ------------------------------------------------------
    //
    // Method: setopt
    //
    // Description:
    //   To ease conversion to OOP module of existing code.
    // ------------------------------------------------------
    
function setopt($cOption$vValue) {
        return 
$this->setOption($cOption$vValue);

    } 
// End [FUNCTION] jd_Curl::setopt method
    // ------------------------------------------------------


    // ------------------------------------------------------
    //
    // Method: getInfo
    //
    // Description:
    //   Returns the info from last CURL query
    // ------------------------------------------------------
    
function getInfo() {
        return 
$this->_info;

    } 
// End [FUNCTION] jd_Curl::getInfo method
    // ------------------------------------------------------


    // ------------------------------------------------------
    //
    // Method: info
    //
    // Description:
    //   Returns the info from last CURL query (to ease conversion
    //   to OOP module of CURL, prefered method is "getInfo")
    // ------------------------------------------------------
    
function info() {
        return 
$this->_info;

    } 
// End [FUNCTION] jd_Curl::info method
    // ------------------------------------------------------


    // ------------------------------------------------------
    //
    // Method: getResponse
    //
    // Description:
    //   Returns the response as received from the last CURL query
    // ------------------------------------------------------
    
function getResponse() {
        if (!
$this->_ranAt) {
            
$this->_setError('exec() method didn\t run or not properly.'1__FILE____LINE__);
        }
        return 
$this->_response;

    } 
// End [FUNCTION] jd_Curl::getResponse method
    // ------------------------------------------------------


    // ------------------------------------------------------
    //
    // Method: getHeaders
    //
    // Description:
    //   Returns the HTTP headers as received from the last CURL query
    // ------------------------------------------------------
    
function getHeaders() {
        if (!
$this->_ranAt) {
            
$this->_setError('exec() method didn\t run or not properly.'1__FILE____LINE__);
            return 
false;

        } else if (!isset(
$this->_options[CURLOPT_HEADER])
                   || !
$this->_options[CURLOPT_HEADER]) {
            
// If the headers were not requested, simply
            // log the error but don't return FALSE.
            // This is a kind of warning method...
            
$this->_setError('Headers were not requested.'1__FILE____LINE__);
        }
        return 
$this->_headers;

    } 
// End [FUNCTION] jd_Curl::getHeaders method
    // ------------------------------------------------------


    // ------------------------------------------------------
    //
    // Method: getBody
    //
    // Description:
    //   Returns the body of the response as received from
    //   the last CURL query. Body is the response less any
    //   HTTP headers.
    // ------------------------------------------------------
    
function getBody() {
        if (!
$this->_ranAt) {
            
$this->_setError('exec() method didn\t run or not properly'1__FILE____LINE__);
            return 
false;
        }
        return 
$this->_body;

    } 
// End [FUNCTION] jd_Curl::getBody method
    // ------------------------------------------------------


   /**
    * _prepareHTTPHeaders
    *
    * @access private
    * @return string Body of call
    **/
   
function _prepareHTTPHeaders() {
      
// Initialize HTTP headers
      
$sRequest null;
      
$aHeaders = array();
      
$iLength 0;

      
// Complete the method with the URL to call
      
$aURL parse_url($this->_url);
      
$sHost $aURL['host'];
      if (isset(
$aURL['port'])
          && ((
strtolower($aURL['scheme']) == 'http' && $aURL['port'] != 80)
              || (
strtolower($aURL['scheme']) == 'https' && $aURL['port'] != 443))) {
         
$sHost .= ':' $aURL['port'];
      }
      
$sURI = (isset($aURL['path'])) ? $aURL['path'] : '/';
      if (!empty(
$aURL['query'])) {
         
$sURI .= '?' $aURL['query'];
      }
      
$aHeader['Host'] = $sHost;
      
$sRequest 'GET ' $sURI ' HTTP/1.0';

      foreach (
$this->_options as $cOption => $sValue) {
         
// Check some options
         
switch ($cOption) {
            case 
CURLOPT_COOKIE:
               
$aHeaders[] = 'Cookie: ' $sValue;
               break;

            case 
CURLOPT_USERPWD:
               
$aHeaders['WWW-Authentication'] = base64_encode($sValue);
               break;

            case 
CURLOPT_UPLOAD:
               
$aHeaders['Content-Type'] = 'multipart/form-data';
               
$sRequest 'POST ' $sURI ' HTTP/1.0';
               break;

            case 
CURLOPT_INFILESIZE:
               
$iLength += (integer) $sValue;
               break;

            case 
CURLOPT_POSTFIELDS:
               
$iLength += strlen($sValue);
               
// No <break> here. This is INTENTIONAL!!!

            
case CURLOPT_POST:
               
$aHeaders['Content-Type'] = 'application/x-www-form-urlencoded';
               
$sRequest 'POST ' $sURI ' HTTP/1.0';
               break;

            case 
CURLOPT_REFERER:
               
$aHeaders['Referer'] = $sValue;
               break;

            case 
CURLOPT_USERAGENT:
               
$aHeaders['User-Agent'] = $sValue;
               break;

            case 
CURLOPT_TIMEVALUE:
               
$sDateSince $sValue;
               if (isset(
$aHeaders['If-Modified-Since'])) {
                  
$aHeaders['If-Modified-Since'] = $sDateSince;

               } elseif (isset(
$aHeaders['If-Unmodified-Since'])) {
                  
$aHeaders['If-Unmodified-Since'] = $sDateSince;
               }
               break;

            case 
CURLOPT_TIMECONDITION:
               switch (
$sValue) {
                  case 
TIMECOND_IFMODSINCE:
                     
$aHeaders['If-Modified-Since'] = isset($sDateSince) ? $sDateSince null;
                     break;

                  case 
TIMECOND_IFUNMODSINCE:
                     
$aHeaders['If-Unmodified-Since'] = isset($sDateSince) ? $sDateSince null;
                     break;
               }
               break;

            case 
CURLOPT_PUT:
               
$sRequest 'PUT ' $sURI ' HTTP/1.0';
               break;

            case 
CURLOPT_CUSTOMREQUEST:
               
$sRequest $sValue;
               break;

            case 
CURLOPT_HTTPHEADER:
               
// List of HTTP headers that was provided.
               
foreach ($sValue as $sName => $vValue) {
                  if (
is_numeric($sName)) {
                     
$aHeaders[] = $vValue;

                  } elseif (
trim($sName) == '') {
                     
// Top HTTP header
                     
$sRequest $vValue;

                  } else {
                     
$aHeaders[$sName] = $vValue;
                  }
               }
               break;

         } 
// End [SWITCH] on special HTTP headers options

      
// End [FOREACH] option
      
if ($iLength 0) {
         
$aHeaders['Content-Length'] = $iLength;
      }

      
// Build the HTTP header, put the one ordered first,
      // then the rest
      
$aOrder = array('Host''WWW-Authentication''Content-Type''Content-Length');
      
$sHeaders $sRequest "\r\n";
      foreach (
$aOrder as $sHeader) {
         if (isset(
$aHeaders[$sHeader]) && !is_null($aHeaders[$sHeader])) {
            
$sHeaders .= $sHeader ': ' $aHeaders[$sHeader] . "\r\n";
            unset(
$aHeaders[$sHeader]);
         }
      }
      
// Add remaining headers
      
foreach ($aHeaders as $sHeader => $sValue) {
         if (
is_null($sValue)) {
            continue;
         }
         if (
is_numeric($sHeader)) {
            
$sHeaders .= $sValue "\r\n";
         } else {
            
$sHeaders .= $sHeader ': ' $sValue "\r\n";
         }
      }

      return 
$sHeaders;

   } 
// End [FUNCTION] jd_Curl::_prepareHTTPHeaders method
   // ------------------------------------------------------


   /**
    * _prepareBody
    *
    * @access private
    * @return string Body of call
    **/
   
function _prepareBody() {
      return (isset(
$this->_options[CURLOPT_POSTFIELDS])) ? $this->_options[CURLOPT_POSTFIELDS] : null;

   } 
// End [FUNCTION] jd_Curl::_prepareBody method
   // ------------------------------------------------------


   /**
    * _verifyURL
    *
    * For the CURL emulator, only supports HTTP, for now.
    *
    * @access private
    * @param  string URL to verify
    * @return boolean TRUE is URL is valid/supported, FALSE otherwise
    **/
   
function _verifyURL($sURL) {
      
$aURL parse_url($sURL);
      if (empty(
$aURL['scheme'])
          || empty(
$aURL['host'])) {
         
$this->_setError('Malformed URL'CURLE_URL_MALFORMAT__FILE____LINE__);
         return 
false;

      } elseif (
strtolower($aURL['scheme']) != 'http') {
         
$this->_setError('Unsupported protocol'CURLE_UNSUPPORTED_PROTOCOL__FILE____LINE__);
         return 
false;

      } elseif (!empty(
$aURL['port'])
                && !
is_numeric($aURL['port'])) {
         
$this->_setError('Malformed URL'CURLE_URL_MALFORMAT__FILE____LINE__);
         return 
false;

      }

      
$this->_connect $aURL;
      if (
$aURL['scheme'] == 'http' && !isset($aURL['port'])) {
         
$this->_connect['port'] = 80;
      }

      
// Get the host's IP address
      
$dNow microtime();
      if (
preg_match('/^((2([0-4][0-9]|5[0-5])|1[0-9]{2}|[1-9][0-9]|[0-9])\.){3}(2([0-4][0-9]|5[0-5])|1[0-9]{2}|[1-9][0-9]|[0-9])$/'$aURL['host'])) {
         
// Host "name" is already a valid IP address.
         
$this->_connect['host'] = $aURL['host'];

      } elseif (!(
$this->_connect['host'] = @gethostbyname($aURL['host']))) {
         
$this->_setError('Couldn\'t resolve host'CURLE_COULDNT_RESOLVE_HOST__FILE____LINE__);
      }
      
$this->_info[CURLINFO_NAMELOOKUP_TIME] = (microtime() - $dThen) / 1000;
      if (
$this->hasError()) {
         return 
false;
      }

      return 
true;

   } 
// End [FUNCTION] jd_Curl::_prepareBody method
   // ------------------------------------------------------


    // ------------------------------------------------------
    //
    // Method: close
    //
    // ------------------------------------------------------
    
function close() {
        
// Re-initialize the object (most of the properties)
        
$this->_url      '';
        
$this->_response '';
        
$this->_headers  = array();
        
$this->_info     = array();
        
$this->_options  = array();
        
$this->_body     '';
        
$this->_ranAt    0;

    } 
// End [FUNCTION] jd_Curl::close method
    // ------------------------------------------------------


    /**
     * Define CURL constant if extension is not available
     *
     * @deprecated
     **/
    
function defineConstants() {


    } 
// End [FUNCTION] jd_Curl::defineConstants method
    // ------------------------------------------------------


// End [CLASS] jd_Curl
// *********************************************************** //


?>