/**
  * Constructor.
  * @param $api_key string Your api key (Ignored for get_apikey requests)
  * @param $protocol string The protocol to use for requests (http|https)
  * @param $debug_level int The level of debugging required CS_REST_LOG_NONE | CS_REST_LOG_ERROR | CS_REST_LOG_WARNING | CS_REST_LOG_VERBOSE
  * @param $host string The host to send API requests to. There is no need to change this
  * @param $log CS_REST_Log The logger to use. Used for dependency injection
  * @param $serialiser The serialiser to use. Used for dependency injection
  * @param $transport The transport to use. Used for dependency injection
  * @access public
  */
 function CS_REST_Wrapper_Base($api_key, $protocol = 'https', $debug_level = CS_REST_LOG_NONE, $host = 'api.createsend.com', $log = NULL, $serialiser = NULL, $transport = NULL)
 {
     $this->_log = is_null($log) ? new CS_REST_Log($debug_level) : $log;
     $this->_protocol = $protocol;
     $this->_base_route = $protocol . '://' . $host . '/api/v3/';
     $this->_log->log_message('Creating wrapper for ' . $this->_base_route, get_class($this), CS_REST_LOG_VERBOSE);
     $this->_transport = is_null($transport) ? @CS_REST_TransportFactory::get_available_transport($this->is_secure(), $this->_log) : $transport;
     $transport_type = method_exists($this->_transport, 'get_type') ? $this->_transport->get_type() : 'Unknown';
     $this->_log->log_message('Using ' . $transport_type . ' for transport', get_class($this), CS_REST_LOG_WARNING);
     $this->_serialiser = is_null($serialiser) ? @CS_REST_SerialiserFactory::get_available_serialiser($this->_log) : $serialiser;
     $this->_log->log_message('Using ' . $this->_serialiser->get_type() . ' json serialising', get_class($this), CS_REST_LOG_WARNING);
     $this->_default_call_options = array('credentials' => $api_key . ':nopass', 'userAgent' => 'CS_REST_Wrapper v' . CS_REST_WRAPPER_VERSION . ' PHPv' . phpversion() . ' over ' . $transport_type . ' with ' . $this->_serialiser->get_type(), 'contentType' => 'application/json; charset=utf-8', 'deserialise' => true, 'host' => $host, 'protocol' => $protocol);
 }
 function make_call($call_options)
 {
     $start_host = strpos($call_options['route'], $call_options['host']);
     $host_len = strlen($call_options['host']);
     $domain = substr($call_options['route'], $start_host, $host_len);
     $host = $domain;
     $path = substr($call_options['route'], $start_host + $host_len);
     $protocol = substr($call_options['route'], 0, $start_host);
     $port = 80;
     $this->_log->log_message('Creating socket to ' . $domain . ' over ' . $protocol . ' for request to ' . $path, get_class($this), CS_REST_LOG_VERBOSE);
     if ($protocol === 'https://') {
         $domain = 'ssl://' . $domain;
         $port = 443;
     }
     if ($this->_socket_wrapper->open($domain, $port)) {
         $inflate_response = function_exists('gzinflate');
         $request = $this->_build_request($call_options, $host, $path, $inflate_response);
         $this->_log->log_message('Sending <pre>' . $request . '</pre> down the socket', get_class($this), CS_REST_LOG_VERBOSE);
         $this->_socket_wrapper->write($request);
         $response = $this->_socket_wrapper->read();
         $this->_socket_wrapper->close();
         $this->_log->log_message('API Call Info for ' . $call_options['method'] . ' ' . $call_options['route'] . ': ' . strlen($request) . ' bytes uploaded. ' . strlen($response) . ' bytes downloaded', get_class($this), CS_REST_LOG_VERBOSE);
         list($headers, $result) = @CS_REST_TransportFactory::split_and_inflate($response, $inflate_response, $this->_log);
         $this->_log->log_message('Received headers <pre>' . $headers . '</pre>', get_class($this), CS_REST_LOG_VERBOSE);
         return array('code' => $this->_get_status_code($headers), 'response' => trim($result));
     }
 }