Source for file HTTP.php
Documentation is available at HTTP.php
* This file contains the code for a HTTP transport layer.
* LICENSE: This source file is subject to version 2.02 of the PHP license,
* that is bundled with this package in the file LICENSE, and is available at
* through the world-wide-web at http://www.php.net/license/2_02.txt. If you
* did not receive a copy of the PHP license and are unable to obtain it
* through the world-wide-web, please send a note to license@php.net so we can
* mail you a copy immediately.
* @author Shane Caraveo <Shane@Caraveo.com>
* @author Jan Schneider <jan@horde.org>
* @copyright 2003-2006 The PHP Group
* @license http://www.php.net/license/2_02.txt PHP License 2.02
* @link http://pear.php.net/package/SOAP
require_once 'SOAP/Transport.php';
* HTTP Transport for SOAP
* @author Shane Caraveo <shane@php.net>
* @author Jan Schneider <jan@horde.org>
* Connection timeout in seconds. 0 = none.
* HTTP-Response Content-Type.
* SOAP_Transport_HTTP Constructor
* @param string $url HTTP url to SOAP endpoint.
* @param string $encoding Encoding to use.
parent ::SOAP_Base ('HTTP');
* Sends and receives SOAP data.
* @param string Outgoing SOAP data.
* @return string|SOAP_Fault
function send($msg, $options = array ())
if (!$this->_validateUrl ()) {
if (isset ($options['timeout'])) {
$this->timeout = (int) $options['timeout'];
return $this->_sendHTTP ($msg, $options);
return $this->_sendHTTPS ($msg, $options);
return $this->_raiseSoapFault ('Invalid url scheme ' . $this->url);
* Sets data for HTTP authentication, creates authorization header.
* @param string $username Username.
* @param string $password Response data, minus HTTP headers.
* @param string $name Cookie name.
* @param mixed $value Cookie value.
* Generates the correct headers for the cookies.
* @param array $options Cookie options. If 'nocookies' is set and true
* the cookies from the last response are added
* automatically. 'cookies' is name-value-hash with
* a list of cookies to add.
* @return string The cookie header value.
function _generateCookieHeader ($options)
if (empty ($options['nocookies']) &&
// Add the cookies we got from the last request.
if ($cookie['domain'] == $this->urlparts['host']) {
$this->cookies[$cookie['name']] = $cookie['value'];
// Add cookies the user wants to set.
if (isset ($options['cookies'])) {
foreach ($options['cookies'] as $cookie) {
if ($cookie['domain'] == $this->urlparts['host']) {
$this->cookies[$cookie['name']] = $cookie['value'];
foreach ($this->cookies as $name => $value) {
* Validate url data passed to constructor.
$this->_raiseSoapFault ('Unable to parse URL ' . $this->url);
$this->_raiseSoapFault ('No host in URL ' . $this->url);
* Finds out what the encoding is.
* Sets the object property accordingly.
* @param array $headers Headers.
function _parseEncoding ($headers)
$h = stristr($headers, 'Content-Type');
preg_match_all('/^Content-Type:\s*(.*)$/im', $h, $ct, PREG_SET_ORDER );
// Strip the string of \r.
if (in_array($enc, $this->_encodings)) {
// Deal with broken servers that don't set content type on faults.
* @param array $headers The headers.
function _parseHeaders ($headers)
/* Largely borrowed from HTTP_Request. */
$headers = split("\r?\n", $headers);
foreach ($headers as $value) {
if (strpos($value,':') === false ) {
list ($name, $value) = split(':', $value);
$headervalue = trim($value);
if ($headername == 'set-cookie') {
// Parse a SetCookie header to fill _cookies array.
$cookie = array ('expires' => null ,
if (!strpos($headervalue, ';')) {
// Only a name=value pair.
list ($cookie['name'], $cookie['value']) = array_map('trim', explode('=', $headervalue));
$cookie['name'] = urldecode($cookie['name']);
$cookie['value'] = urldecode($cookie['value']);
// Some optional parameters are supplied.
$elements = explode(';', $headervalue);
list ($cookie['name'], $cookie['value']) = array_map('trim', explode('=', $elements[0 ]));
$cookie['name'] = urldecode($cookie['name']);
$cookie['value'] = urldecode($cookie['value']);
for ($i = 1; $i < count($elements); $i++ ) {
if ('secure' == $elName) {
$cookie['secure'] = true;
} elseif ('expires' == $elName) {
} elseif ('path' == $elName OR 'domain' == $elName) {
$cookie[$elName] = $elValue;
* Removes HTTP headers from response.
function _parseResponse ()
$this->_raiseSoapFault ('Invalid HTTP Response');
$this->response = $match[2 ];
// Find the response error, some servers response with 500 for
$this->_parseHeaders ($match[1 ]);
return $this->_parseResponse ();
/* Valid one-way message response. */
$this->_raiseSoapFault (" HTTP Response $code Bad Request" );
$this->_raiseSoapFault (" HTTP Response $code Authentication Failed" );
$this->_raiseSoapFault (" HTTP Response $code Forbidden" );
$this->_raiseSoapFault (" HTTP Response $code Not Found" );
$this->_raiseSoapFault (" HTTP Response $code Proxy Authentication Required" );
$this->_raiseSoapFault (" HTTP Response $code Request Timeout" );
$this->_raiseSoapFault (" HTTP Response $code Gone" );
if ($code >= 400 && $code < 500 ) {
$this->_raiseSoapFault (" HTTP Response $code Not Found, Server message: $msg" );
$this->_parseEncoding ($match[1 ]);
// XXX quick hack insertion of DIME
if (PEAR ::isError ($this->_decodeDIMEMessage ($this->response, $this->headers, $this->attachments))) {
// _decodeDIMEMessage already raised $this->fault
if (PEAR ::isError ($this->_decodeMimeMessage ($this->response, $this->headers, $this->attachments))) {
// _decodeMimeMessage already raised $this->fault
$this->_raiseSoapFault ($this->response);
// if no content, return false
return strlen($this->response) > 0;
* Creates an HTTP request, including headers, for the outgoing request.
* @param string $msg Outgoing SOAP package.
* @param array $options Options.
* @return string Outgoing payload.
function _getRequest ($msg, $options)
$action = isset ($options['soapaction']) ? $options['soapaction'] : '';
$fullpath .= '?' . $this->urlparts['query'];
if (isset ($this->urlparts['fragment'])) {
$fullpath .= '#' . $this->urlparts['fragment'];
if (isset ($options['proxy_host'])) {
$fullpath = 'http://' . $this->urlparts['host'] . ':' .
if (isset ($options['proxy_user'])) {
$this->headers['Proxy-Authorization'] = 'Basic ' .
if (isset ($options['user'])) {
$this->headers['User-Agent'] = $this->_userAgent;
$this->headers['SOAPAction'] = '"' . $action . '"';
$this->headers['Connection'] = 'close';
if (isset ($options['headers'])) {
$cookies = $this->_generateCookieHeader ($options);
$this->headers['Cookie'] = $cookies;
foreach ($this->headers as $k => $v) {
$headers .= " $k: $v\r\n";
* Sends the outgoing HTTP request and reads and parses the response.
* @param string $msg Outgoing SOAP package.
* @param array $options Options.
* @return string Response data without HTTP headers.
function _sendHTTP ($msg, $options)
$this->_getRequest ($msg, $options);
if (isset ($options['proxy_host'])) {
$host = $options['proxy_host'];
$port = isset ($options['proxy_port']) ? $options['proxy_port'] : 8080;
$fp = @fsockopen($host, $port, $this->errno, $this->errmsg);
return $this->_raiseSoapFault (" Connect Error to $host:$port" );
// some builds of PHP do not support this, silence the warning
return $this->_raiseSoapFault (" Error POSTing Data to $host" );
$data = fread($fp, 4096 );
if ($_tmp_status['timed_out']) {
return $this->_raiseSoapFault (" Timed out read from $host" );
} while (!$_tmp_status['eof']);
if (!$this->_parseResponse ()) {
* Sends the outgoing HTTPS request and reads and parses the response.
* @param string $msg Outgoing SOAP package.
* @param array $options Options.
* @return string Response data without HTTP headers.
function _sendHTTPS ($msg, $options)
/* Check if the required curl extension is installed. */
return $this->_raiseSoapFault ('CURL Extension is required for HTTPS');
if (isset ($options['proxy_host'])) {
$port = isset ($options['proxy_port']) ? $options['proxy_port'] : 8080;
$options['proxy_host'] . ':' . $port);
if (isset ($options['proxy_user'])) {
$options['proxy_user'] . ':' . $options['proxy_pass']);
if (isset ($options['user'])) {
$options['user'] . ':' . $options['pass']);
$action = isset ($options['soapaction']) ? $options['soapaction'] : '';
$headers['Content-Type'] = " text/xml; charset=$this->encoding";
$headers['SOAPAction'] = '"' . $action . '"';
if (isset ($options['headers'])) {
foreach ($headers as $header => $value) {
$headers[$header] = $header . ': ' . $value;
curl_setopt($ch, CURLOPT_USERAGENT , $this->_userAgent);
if (defined('CURLOPT_HTTP_VERSION')) {
$cookies = $this->_generateCookieHeader ($options);
if (isset ($options['curl'])) {
foreach ($options['curl'] as $key => $val) {
// Save the outgoing XML. This doesn't quite match _sendHTTP as CURL
// generates the headers, but having the XML is usually the most
// important part for tracing/debugging.
return $this->_raiseSoapFault ($m);
if (!$this->_parseResponse ()) {
Documentation generated on Mon, 04 Aug 2008 20:00:26 -0400 by phpDocumentor 1.4.0. PEAR Logo Copyright © PHP Group 2004.
|