core-bundle/src/Resources/contao/library/Contao/Request.php
public function send($strUrl, $strData=null, $strMethod=null)
	{
		if ($strData !== null)
		{
			$this->strData = $strData;
		}

		if ($strMethod !== null)
		{
			$this->strMethod = $strMethod;
		}

		$errstr = '';
		$errno = null;
		$uri = parse_url($strUrl);

		switch ($uri['scheme'])
		{
			case 'http':
				$port = $uri['port'] ?? 80;
				$host = $uri['host'] . (($port != 80) ? ':' . $port : '');
				$fp = @fsockopen($uri['host'], $port, $errno, $errstr, 10);
				break;

			case 'https':
				$port = $uri['port'] ?? 443;
				$host = $uri['host'] . (($port != 443) ? ':' . $port : '');
				$fp = @fsockopen('ssl://' . $uri['host'], $port, $errno, $errstr, 15);
				break;

			default:
				$this->strError = 'Invalid schema ' . $uri['scheme'];

				return;
				break;
		}

		if (!\is_resource($fp))
		{
			$this->strError = trim($errno .' '. $errstr);

			return;
		}

		$path = $uri['path'] ?? '/';

		if (isset($uri['query']))
		{
			$path .= '?' . $uri['query'];
		}

		$default = array
		(
			'Host' => 'Host: ' . $host,
			'User-Agent' => 'User-Agent: Contao (+https://contao.org/)',
			'Content-Length' => 'Content-Length: '. \strlen($this->strData),
			'Connection' => 'Connection: close'
		);

		if (isset($uri['user']))
		{
			$default['Authorization'] = 'Authorization: Basic ' . base64_encode($uri['user'] . ':' . $uri['pass']);
		}
		elseif ($this->strUsername != '')
		{
			$default['Authorization'] = 'Authorization: Basic ' . base64_encode($this->strUsername . ':' . $this->strPassword);
		}

		foreach ($this->arrHeaders as $header=>$value)
		{
			$default[$header] = $header . ': ' . $value;
		}

		$request = strtoupper($this->strMethod) .' '. $path ." HTTP/1.0\r\n";
		$request .= implode("\r\n", $default);
		$request .= "\r\n\r\n";

		if ($this->strData != '')
		{
			$request .= $this->strData . "\r\n";
		}

		$this->strRequest = $request;
		fwrite($fp, $request);
		$response = '';

		while (!feof($fp) && ($chunk = fread($fp, 1024)) != false)
		{
			$response .= $chunk;
		}

		fclose($fp);

		list($split, $this->strResponse) = explode("\r\n\r\n", $response, 2);
		$split = preg_split("/\r\n|\n|\r/", $split);
		$this->arrResponseHeaders = array();
		list(, $code, $text) = explode(' ', trim(array_shift($split)), 3);

		while (($line = trim(array_shift($split))) != false)
		{
			list($header, $value) = explode(':', $line, 2);

			if (isset($this->arrResponseHeaders[$header]) && $header == 'Set-Cookie')
			{
				$this->arrResponseHeaders[$header] .= ',' . trim($value);
			}
			else
			{
				$this->arrResponseHeaders[$header] = trim($value);
			}
		}

		$responses = array
		(
			100 => 'Continue',
			101 => 'Switching Protocols',
			200 => 'OK',
			201 => 'Created',
			202 => 'Accepted',
			203 => 'Non-Authoritative Information',
			204 => 'No Content',
			205 => 'Reset Content',
			206 => 'Partial Content',
			300 => 'Multiple Choices',
			301 => 'Moved Permanently',
			302 => 'Found',
			303 => 'See Other',
			304 => 'Not Modified',
			305 => 'Use Proxy',
			307 => 'Temporary Redirect',
			400 => 'Bad Request',
			401 => 'Unauthorized',
			402 => 'Payment Required',
			403 => 'Forbidden',
			404 => 'Not Found',
			405 => 'Method Not Allowed',
			406 => 'Not Acceptable',
			407 => 'Proxy Authentication Required',
			408 => 'Request Timeout',
			409 => 'Conflict',
			410 => 'Gone',
			411 => 'Length Required',
			412 => 'Precondition Failed',
			413 => 'Request Entity Too Large',
			414 => 'Request-URI Too Large',
			415 => 'Unsupported Media Type',
			416 => 'Requested Range Not Satisfiable',
			417 => 'Expectation Failed',
			500 => 'Internal Server Error',
			501 => 'Not Implemented',
			502 => 'Bad Gateway',
			503 => 'Service Unavailable',
			504 => 'Gateway Timeout',
			505 => 'HTTP Version Not Supported'
		);

		if (!isset($responses[$code]))
		{
			$code = floor($code / 100) * 100;
		}

		$this->intCode = (int) $code;

		switch ($this->intCode)
		{
			case 200:
			case 304:
				// Ok
				break;

			case 301:
			case 302:
			case 303:
			case 307:
				if ($this->blnFollowRedirects && $this->intRedirects < $this->intRedirectLimit && !empty($this->arrResponseHeaders['Location']))
				{
					++$this->intRedirects;
					$strLocation = $this->arrResponseHeaders['Location'];

					// Make sure the location is an absolute URL (see #7799)
					if (!preg_match('@^https?://@', $strLocation))
					{
						$strLocation = $uri['scheme'] . '://' . $host . $strLocation;
					}

					$this->send($strLocation);
				}
				break;

			default:
				$this->strError = $text ?: $responses[$this->intCode];
				break;
		}
	}
public function send($strUrl, $strData=null, $strMethod=null)
	{
		if ($strData !== null)
		{
			$this->strData = $strData;
		}

		if ($strMethod !== null)
		{
			$this->strMethod = $strMethod;
		}

		$errstr = '';
		$errno = null;
		$uri = parse_url($strUrl);

		switch ($uri['scheme'])
		{
			case 'http':
				$port = $uri['port'] ?? 80;
				$host = $uri['host'] . (($port != 80) ? ':' . $port : '');
				$fp = @fsockopen($uri['host'], $port, $errno, $errstr, 10);
				break;

			case 'https':
				$port = $uri['port'] ?? 443;
				$host = $uri['host'] . (($port != 443) ? ':' . $port : '');
				$fp = @fsockopen('ssl://' . $uri['host'], $port, $errno, $errstr, 15);
				break;

			default:
				$this->strError = 'Invalid schema ' . $uri['scheme'];

				return;
				break;
		}

		if (!\is_resource($fp))
		{
			$this->strError = trim($errno .' '. $errstr);

			return;
		}

		$path = $uri['path'] ?? '/';

		if (isset($uri['query']))
		{
			$path .= '?' . $uri['query'];
		}

		$default = array
		(
			'Host' => 'Host: ' . $host,
			'User-Agent' => 'User-Agent: Contao (+https://contao.org/)',
			'Content-Length' => 'Content-Length: '. \strlen($this->strData),
			'Connection' => 'Connection: close'
		);

		if (isset($uri['user']))
		{
			$default['Authorization'] = 'Authorization: Basic ' . base64_encode($uri['user'] . ':' . $uri['pass']);
		}
		elseif ($this->strUsername != '')
		{
			$default['Authorization'] = 'Authorization: Basic ' . base64_encode($this->strUsername . ':' . $this->strPassword);
		}

		foreach ($this->arrHeaders as $header=>$value)
		{
			$default[$header] = $header . ': ' . $value;
		}

		$request = strtoupper($this->strMethod) .' '. $path ." HTTP/1.0\r\n";
		$request .= implode("\r\n", $default);
		$request .= "\r\n\r\n";

		if ($this->strData != '')
		{
			$request .= $this->strData . "\r\n";
		}

		$this->strRequest = $request;
		fwrite($fp, $request);
		$response = '';

		while (!feof($fp) && ($chunk = fread($fp, 1024)) != false)
		{
			$response .= $chunk;
		}

		fclose($fp);

		list($split, $this->strResponse) = explode("\r\n\r\n", $response, 2);
		$split = preg_split("/\r\n|\n|\r/", $split);
		$this->arrResponseHeaders = array();
		list(, $code, $text) = explode(' ', trim(array_shift($split)), 3);

		while (($line = trim(array_shift($split))) != false)
		{
			list($header, $value) = explode(':', $line, 2);

			if (isset($this->arrResponseHeaders[$header]) && $header == 'Set-Cookie')
			{
				$this->arrResponseHeaders[$header] .= ',' . trim($value);
			}
			else
			{
				$this->arrResponseHeaders[$header] = trim($value);
			}
		}

		$responses = array
		(
			100 => 'Continue',
			101 => 'Switching Protocols',
			200 => 'OK',
			201 => 'Created',
			202 => 'Accepted',
			203 => 'Non-Authoritative Information',
			204 => 'No Content',
			205 => 'Reset Content',
			206 => 'Partial Content',
			300 => 'Multiple Choices',
			301 => 'Moved Permanently',
			302 => 'Found',
			303 => 'See Other',
			304 => 'Not Modified',
			305 => 'Use Proxy',
			307 => 'Temporary Redirect',
			400 => 'Bad Request',
			401 => 'Unauthorized',
			402 => 'Payment Required',
			403 => 'Forbidden',
			404 => 'Not Found',
			405 => 'Method Not Allowed',
			406 => 'Not Acceptable',
			407 => 'Proxy Authentication Required',
			408 => 'Request Timeout',
			409 => 'Conflict',
			410 => 'Gone',
			411 => 'Length Required',
			412 => 'Precondition Failed',
			413 => 'Request Entity Too Large',
			414 => 'Request-URI Too Large',
			415 => 'Unsupported Media Type',
			416 => 'Requested Range Not Satisfiable',
			417 => 'Expectation Failed',
			500 => 'Internal Server Error',
			501 => 'Not Implemented',
			502 => 'Bad Gateway',
			503 => 'Service Unavailable',
			504 => 'Gateway Timeout',
			505 => 'HTTP Version Not Supported'
		);

		if (!isset($responses[$code]))
		{
			$code = floor($code / 100) * 100;
		}

		$this->intCode = (int) $code;

		switch ($this->intCode)
		{
			case 200:
			case 304:
				// Ok
				break;

			case 301:
			case 302:
			case 303:
			case 307:
				if ($this->blnFollowRedirects && $this->intRedirects < $this->intRedirectLimit && !empty($this->arrResponseHeaders['Location']))
				{
					++$this->intRedirects;
					$strLocation = $this->arrResponseHeaders['Location'];

					// Make sure the location is an absolute URL (see #7799)
					if (!preg_match('@^https?://@', $strLocation))
					{
						$strLocation = $uri['scheme'] . '://' . $host . $strLocation;
					}

					$this->send($strLocation);
				}
				break;

			default:
				$this->strError = $text ?: $responses[$this->intCode];
				break;
		}
	}
public function send ( $ strUrl , $ strData = null , $ strMethod = null ) { if ( $ strData !== null ) { $ this -> strData = $ strData ; } if ( $ strMethod !== null ) { $ this -> strMethod = $ strMethod ; } $ errstr = '' ; $ errno = null ; $ uri = parse_url ( $ strUrl ) ; switch ( $ uri [ 'scheme' ] ) { case 'http' : $ port = $ uri [ 'port' ] ?? 80 ; $ host = $ uri [ 'host' ] . ( ( $ port != 80 ) ? ':' . $ port : '' ) ; $ fp = @ fsockopen ( $ uri [ 'host' ] , $ port , $ errno , $ errstr , 10 ) ; break ; case 'https' : $ port = $ uri [ 'port' ] ?? 443 ; $ host = $ uri [ 'host' ] . ( ( $ port != 443 ) ? ':' . $ port : '' ) ; $ fp = @ fsockopen ( 'ssl://' . $ uri [ 'host' ] , $ port , $ errno , $ errstr , 15 ) ; break ; default : $ this -> strError = 'Invalid schema ' . $ uri [ 'scheme' ] ; return ; break ; } if ( ! \ is_resource ( $ fp ) ) { $ this -> strError = trim ( $ errno . ' ' . $ errstr ) ; return ; } $ path = $ uri [ 'path' ] ?? '/' ; if ( isset ( $ uri [ 'query' ] ) ) { $ path .= '?' . $ uri [ 'query' ] ; } $ default = array ( 'Host' => 'Host: ' . $ host , 'User-Agent' => 'User-Agent: Contao (+https://contao.org/)' , 'Content-Length' => 'Content-Length: ' . \ strlen ( $ this -> strData ) , 'Connection' => 'Connection: close' ) ; if ( isset ( $ uri [ 'user' ] ) ) { $ default [ 'Authorization' ] = 'Authorization: Basic ' . base64_encode ( $ uri [ 'user' ] . ':' . $ uri [ 'pass' ] ) ; } elseif ( $ this -> strUsername != '' ) { $ default [ 'Authorization' ] = 'Authorization: Basic ' . base64_encode ( $ this -> strUsername . ':' . $ this -> strPassword ) ; } foreach ( $ this -> arrHeaders as $ header => $ value ) { $ default [ $ header ] = $ header . ': ' . $ value ; } $ request = strtoupper ( $ this -> strMethod ) . ' ' . $ path . " HTTP/1.0\r\n" ; $ request .= implode ( "\r\n" , $ default ) ; $ request .= "\r\n\r\n" ; if ( $ this -> strData != '' ) { $ request .= $ this -> strData . "\r\n" ; } $ this -> strRequest = $ request ; fwrite ( $ fp , $ request ) ; $ response = '' ; while ( ! feof ( $ fp ) && ( $ chunk = fread ( $ fp , 1024 ) ) != false ) { $ response .= $ chunk ; } fclose ( $ fp ) ; list ( $ split , $ this -> strResponse ) = explode ( "\r\n\r\n" , $ response , 2 ) ; $ split = preg_split ( "/\r\n|\n|\r/" , $ split ) ; $ this -> arrResponseHeaders = array ( ) ; list ( , $ code , $ text ) = explode ( ' ' , trim ( array_shift ( $ split ) ) , 3 ) ; while ( ( $ line = trim ( array_shift ( $ split ) ) ) != false ) { list ( $ header , $ value ) = explode ( ':' , $ line , 2 ) ; if ( isset ( $ this -> arrResponseHeaders [ $ header ] ) && $ header == 'Set-Cookie' ) { $ this -> arrResponseHeaders [ $ header ] .= ',' . trim ( $ value ) ; } else { $ this -> arrResponseHeaders [ $ header ] = trim ( $ value ) ; } } $ responses = array ( 100 => 'Continue' , 101 => 'Switching Protocols' , 200 => 'OK' , 201 => 'Created' , 202 => 'Accepted' , 203 => 'Non-Authoritative Information' , 204 => 'No Content' , 205 => 'Reset Content' , 206 => 'Partial Content' , 300 => 'Multiple Choices' , 301 => 'Moved Permanently' , 302 => 'Found' , 303 => 'See Other' , 304 => 'Not Modified' , 305 => 'Use Proxy' , 307 => 'Temporary Redirect' , 400 => 'Bad Request' , 401 => 'Unauthorized' , 402 => 'Payment Required' , 403 => 'Forbidden' , 404 => 'Not Found' , 405 => 'Method Not Allowed' , 406 => 'Not Acceptable' , 407 => 'Proxy Authentication Required' , 408 => 'Request Timeout' , 409 => 'Conflict' , 410 => 'Gone' , 411 => 'Length Required' , 412 => 'Precondition Failed' , 413 => 'Request Entity Too Large' , 414 => 'Request-URI Too Large' , 415 => 'Unsupported Media Type' , 416 => 'Requested Range Not Satisfiable' , 417 => 'Expectation Failed' , 500 => 'Internal Server Error' , 501 => 'Not Implemented' , 502 => 'Bad Gateway' , 503 => 'Service Unavailable' , 504 => 'Gateway Timeout' , 505 => 'HTTP Version Not Supported' ) ; if ( ! isset ( $ responses [ $ code ] ) ) { $ code = floor ( $ code / 100 ) * 100 ; } $ this -> intCode = ( int ) $ code ; switch ( $ this -> intCode ) { case 200 : case 304 : // Ok break ; case 301 : case 302 : case 303 : case 307 : if ( $ this -> blnFollowRedirects && $ this -> intRedirects < $ this -> intRedirectLimit && ! empty ( $ this -> arrResponseHeaders [ 'Location' ] ) ) { ++ $ this -> intRedirects ; $ strLocation = $ this -> arrResponseHeaders [ 'Location' ] ; // Make sure the location is an absolute URL (see #7799) if ( ! preg_match ( '@^https?://@' , $ strLocation ) ) { $ strLocation = $ uri [ 'scheme' ] . '://' . $ host . $ strLocation ; } $ this -> send ( $ strLocation ) ; } break ; default : $ this -> strError = $ text ? : $ responses [ $ this -> intCode ] ; break ; } }
Send the HTTP request

@param string $strUrl    The target URL
@param string $strData   Optional request data
@param string $strMethod An optional request method
Send the HTTP request