Files
grzanieplus.pl/plugins/sfWebBrowserPlugin/lib/sfSocketsAdapter.class.php
2025-03-12 17:06:23 +01:00

153 lines
4.2 KiB
PHP

<?php
/*
* This file is part of the sfWebBrowserPlugin package.
* (c) 2004-2006 Francois Zaninotto <francois.zaninotto@symfony-project.com>
* (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com> for the click-related functions
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* sfWebBrowser provides a basic HTTP client.
*
* @package sfWebBrowserPlugin
* @author Francois Zaninotto <francois.zaninotto@symfony-project.com>
* @author Benjamin Meynell <bmeynell@colorado.edu>
* @version 0.9
*/
class sfSocketsAdapter
{
protected
$options = array(),
$adapterErrorMessage = null,
$browser = null;
public function __construct($options = array())
{
$this->options = $options;
}
/**
* Submits a request
*
* @param string The request uri
* @param string The request method
* @param array The request parameters (associative array)
* @param array The request headers (associative array)
*
* @return sfWebBrowser The current browser object
*/
public function call($browser, $uri, $method = 'GET', $parameters = array(), $headers = array())
{
$m_headers = array_merge(array('Content-Type' => 'application/x-www-form-urlencoded'), $browser->getDefaultRequestHeaders(), $browser->initializeRequestHeaders($headers));
$request_headers = $browser->prepareHeaders($m_headers);
$url_info = parse_url($uri);
// initialize default values
isset($url_info['path']) ? $path = $url_info['path'] : $path = '/';
isset($url_info['query']) ? $qstring = '?'.$url_info['query'] : $qstring = null;
isset($url_info['port']) ? null : $url_info['port'] = 80;
if (!$socket = @fsockopen($url_info['host'], $url_info['port'], $errno, $errstr, 15))
{
throw new Exception("Could not connect ($errno): $errstr");
}
// build request
$request = "$method $path$qstring HTTP/1.1\r\n";
$request .= 'Host: '.$url_info['host'].':'.$url_info['port']."\r\n";
$request .= $request_headers;
$request .= "Connection: Close\r\n";
if ($method == 'PUT' && is_array($parameters) && array_key_exists('file', $parameters))
{
$fp = fopen($parameters['file'], 'rb');
$sent = 0;
$blocksize = (2 << 20); // 2MB chunks
$filesize = filesize($parameters['file']);
$request .= 'Content-Length: '.$filesize."\r\n";
$request .= "\r\n";
fwrite($socket, $request);
while ($sent < $filesize)
{
$data = fread($fp, $blocksize);
fwrite($socket, $data);
$sent += $blocksize;
}
fclose($fp);
}
elseif ($method == 'POST' || $method == 'PUT')
{
$body = is_array($parameters) ? http_build_query($parameters, '', '&') : $parameters;
$request .= 'Content-Length: '.strlen($body)."\r\n";
$request .= "\r\n";
$request .= $body;
}
$request .= "\r\n";
fwrite($socket, $request);
$response = '';
$response_body = '';
while (!feof($socket))
{
$response .= fgets($socket, 1024);
}
fclose($socket);
// parse response components: status line, headers and body
$response_lines = explode("\r\n", $response);
// http status line (ie "HTTP 1.1 200 OK")
$status_line = array_shift($response_lines);
$start_body = false;
$response_headers = array();
for($i=0; $i<count($response_lines); $i++)
{
// grab body
if ($start_body == true)
{
// ignore chunked encoding size
if (!preg_match('@^[0-9A-Fa-f]+\s*$@', $response_lines[$i]))
{
$response_body .= $response_lines[$i];
}
}
// body starts after first blank line
else if ($start_body == false && $response_lines[$i] == '')
{
$start_body = true;
}
// grab headers
else
{
$response_headers[] = $response_lines[$i];
}
}
$browser->setResponseHeaders($response_headers);
// grab status code
preg_match('@(\d{3})@', $status_line, $status_code);
if(isset($status_code[1]))
{
$browser->setResponseCode($status_code[1]);
}
$browser->setResponseText(trim($response_body));
return $browser;
}
}