HttpResponse::setFile('../archive.zip');
HttpResponse::send();
?>
-
-Exemplar Use Cases
-------------------
-
-- KISS XMLRPC Client
-
-<?php
-class XmlRpcClient
-{
- public $namespace;
- protected $request;
-
- public function __construct($url, $namespace = '')
- {
- $this->namespace = $namespace;
- $this->request = new HttpRequest($url, HTTP_METH_POST);
- $this->request->setContentType('text/xml');
- }
-
- public function setOptions($options = array())
- {
- return $this->request->setOptions($options);
- }
-
- public function addOptions($options)
- {
- return $this->request->addOptions($options);
- }
-
- public function __call($method, $params)
- {
- if ($this->namespace) {
- $method = $this->namespace .'.'. $method;
- }
- $this->request->setRawPostData(xmlrpc_encode_request($method, $params));
- $response = $this->request->send();
- if ($response->getResponseCode() != 200) {
- throw new Exception($response->getBody(), $response->getResponseCode());
- }
- return xmlrpc_decode($response->getBody(), 'utf-8');
- }
-
- public function getHistory()
- {
- return $this->request->getHistory();
- }
-}
-
-?>
-
-- Simple Feed Aggregator
-
-<?php
-class FeedAggregator
-{
- public $directory;
- protected $feeds = array();
-
- public function __construct($directory = 'feeds')
- {
- $this->setDirectory($directory);
- }
-
- public function setDirectory($directory)
- {
- $this->directory = $directory;
- foreach (glob($this->directory .'/*.xml') as $feed) {
- $this->feeds[basename($feed, '.xml')] = filemtime($feed);
- }
- }
-
- public function url2name($url)
- {
- return preg_replace('/[^\w\.-]+/', '_', $url);
- }
-
- public function hasFeed($url)
- {
- return isset($this->feeds[$this->url2name($url)]);
- }
-
- public function addFeed($url)
- {
- $r = $this->setupRequest($url);
- $r->send();
- $this->handleResponse($r);
- }
-
- public function addFeeds($urls)
- {
- $pool = new HttpRequestPool;
- foreach ($urls as $url) {
- $pool->attach($r = $this->setupRequest($url));
- }
- $pool->send();
-
- foreach ($pool as $request) {
- $this->handleResponse($request);
- }
- }
-
- public function getFeed($url)
- {
- $this->addFeed($url);
- return $this->loadFeed($this->url2name($url));
- }
-
- public function getFeeds($urls)
- {
- $feeds = array();
- $this->addFeeds($urls);
- foreach ($urls as $url) {
- $feeds[] = $this->loadFeed($this->url2name($url));
- }
- return $feeds;
- }
-
- protected function saveFeed($file, $contents)
- {
- if (file_put_contents($this->directory .'/'. $file .'.xml', $contents)) {
- $this->feeds[$file] = time();
- } else {
- throw new Exception("Could not save feed contents to $file.xml");
- }
- }
-
- protected function loadFeed($file)
- {
- if (isset($this->feeds[$file])) {
- if ($data = file_get_contents($this->directory .'/'. $file .'.xml')) {
- return $data;
- } else {
- throw new Exception("Could not load feed contents from $file.xml");
- }
- } else {
- throw new Exception("Unknown feed/file $file.xml");
- }
- }
-
- protected function setupRequest($url)
- {
- $r = new HttpRequest($url);
- $r->setOptions(array('redirect' => true));
-
- $file = $this->url2name($url);
-
- if (isset($this->feeds[$file])) {
- $r->setOptions(array('lastmodified' => $this->feeds[$file]));
- }
-
- return $r;
- }
-
- protected function handleResponse(HttpRequest $r)
- {
- if ($r->getResponseCode() != 304) {
- if ($r->getResponseCode() != 200) {
- throw new Exception("Unexpected response code ". $r->getResponseCode());
- }
- if (!strlen($body = $r->getResponseBody())) {
- throw new Exception("Received empty feed from ". $r->getUrl());
- }
- $this->saveFeed($this->url2name($r->getUrl()), $body);
- }
- }
-}
-?>
-
-- Download a big file
-
-<?php
-
-/*
- $bigGet = BigGet::url('http://www.example.com/big_file.bin');
- $bigGet->saveTo('file.bin');
-*/
-
-class BigGetRequest extends HttpRequest
-{
- public $id;
-}
-
-class BigGet extends HttpRequestPool
-{
- const SIZE = 1048576;
-
- private $url;
- private $size;
- private $count = 0;
- private $files = array();
-
- static function url($url)
- {
- $head = new HttpRequest($url, HttpRequest::METH_HEAD);
- $headers = $head->send()->getHeaders();
- $head = null;
-
- if (!isset($headers['Accept-Ranges'])) {
- throw new HttpException("Did not receive an Accept-Ranges header from HEAD $url");
- }
- if (!isset($headers['Content-Length'])) {
- throw new HttpException("Did not receive a Content-Length header from HEAD $url");
- }
-
- $bigget = new BigGet;
- $bigget->url = $url;
- $bigget->size = $headers['Content-Length'];
- return $bigget;
- }
-
- function saveTo($file)
- {
- $this->send();
- if ($w = fopen($file, 'wb')) {
- echo "\nCopying temp files to $file ...\n";
- foreach (glob("bigget_????.tmp") as $tmp) {
- echo "\t$tmp\n";
- if ($r = fopen($tmp, 'rb')) {
- stream_copy_to_stream($r, $w);
- fclose($r);
- }
- unlink($tmp);
- }
- fclose($w);
- echo "\nDone.\n";
- }
- }
-
- function send()
- {
- // use max 3 simultanous requests with a req size of 1MiB
- while ($this->count < 3 && -1 != $offset = $this->getRangeOffset()) {
- $this->attachNew($offset);
- }
-
- while ($this->socketPerform()) {
- if (!$this->socketSelect()) {
- throw new HttpSocketException;
- }
- }
- }
-
- private function attachNew($offset)
- {
- $stop = min($this->count * self::SIZE + self::SIZE, $this->size) - 1;
-
- echo "Attaching new request to get range: $offset-$stop\n";
-
- $req = new BigGetRequest(
- $this->url,
- HttpRequest::METH_GET,
- array(
- 'headers' => array(
- 'Range' => "bytes=$offset-$stop"
- )
- )
- );
- $this->attach($req);
- $req->id = $this->count++;
- }
-
- private function getRangeOffset()
- {
- return ($this->size >= $start = $this->count * self::SIZE) ? $start : -1;
- }
-
- protected function socketPerform()
- {
- try {
- $rc = parent::socketPerform();
- } catch (HttpRequestPoolException $x) {
- foreach ($x->exceptionStack as $e) {
- echo $e->getMessage(), "\n";
- }
- }
-
- foreach ($this->getFinishedRequests() as $r) {
- $this->detach($r);
-
- if (206 != $rc = $r->getResponseCode()) {
- throw new HttpException("Unexpected response code: $rc");
- }
-
- file_put_contents(sprintf("bigget_%04d.tmp", $r->id), $r->getResponseBody());
-
- if (-1 != $offset = $this->getRangeOffset()) {
- $this->attachNew($offset);
- }
- }
-
- return $rc;
- }
-}
-?>
-