- add an "Download big file" example
[m6w6/ext-http] / docs / examples / tutorial.txt
index d8d9fad84581dd48afd41703bc5d456f5feaf6f9..d2a8cf10c03e95ac005a06967bdc509a86f37e1e 100644 (file)
@@ -12,11 +12,12 @@ $Revision$
        read from and written to a file.
 
 <?php
-$r = new HttpRequest('http://www.google.com');
+$r = new HttpRequest('http://www.google.com/search');
 
 // store Googles cookies in a dedicated file
+touch('google.txt');
 $r->setOptions(
-       array(  'cookiestore'   => '../cookies/google.txt',
+       array(  'cookiestore'   => 'google.txt',
        )
 );
 
@@ -27,7 +28,7 @@ $r->setQueryData(
 );
 
 // HttpRequest::send() returns an HttpMessage object
-// of type HttpMessage::RESPONSE or throws an exception
+// of type HttpMessage::TYPE_RESPONSE or throws an exception
 try {
        print $r->send()->getBody();
 } catch (HttpException $e) {
@@ -44,7 +45,7 @@ try {
        redirect option.
 
 <?php
-$r = new HttpRequest('http://dev.iworks.at/.print_request.php', HTTP_POST);
+$r = new HttpRequest('http://dev.iworks.at/.print_request.php', HTTP_METH_POST);
 
 // if redirects is set to true, a single redirect is allowed;
 // one can set any reasonable count of allowed redirects
@@ -61,6 +62,7 @@ $r->setPostFields(
        )
 );
 // add the file to post (form name, file name, file type)
+touch('profile.jpg');
 $r->addPostFile('image', 'profile.jpg', 'image/jpeg');
 
 try {
@@ -82,8 +84,8 @@ try {
        $p = new HttpRequestPool;
        // if you want to set _any_ options of the HttpRequest object,
        // you need to do so *prior attaching* to the request pool!
-       $p->attach(new HttpRequest('http://pear.php.net', HTTP_HEAD));
-       $p->attach(new HttpRequest('http://pecl.php.net', HTTP_HEAD));
+       $p->attach(new HttpRequest('http://pear.php.net', HTTP_METH_HEAD));
+       $p->attach(new HttpRequest('http://pecl.php.net', HTTP_METH_HEAD));
 } catch (HttpException $e) {
        print $e;
        exit;
@@ -112,8 +114,8 @@ class Pool extends HttpRequestPool
        public function __construct()
        {
                parent::__construct(
-                       new HttpRequest('http://pear.php.net', HTTP_HEAD),
-                       new HttpRequest('http://pecl.php.net', HTTP_HEAD)
+                       new HttpRequest('http://pear.php.net', HTTP_METH_HEAD),
+                       new HttpRequest('http://pecl.php.net', HTTP_METH_HEAD)
                );
 
                // HttpRequestPool methods socketPerform() and socketSelect() are
@@ -186,7 +188,7 @@ class XmlRpcClient
        public function __construct($url, $namespace = '')
        {
                $this->namespace = $namespace;
-               $this->request = new HttpRequest($url, HTTP_POST);
+               $this->request = new HttpRequest($url, HTTP_METH_POST);
                $this->request->setContentType('text/xml');
        }
 
@@ -205,7 +207,7 @@ class XmlRpcClient
                if ($this->namespace) {
                        $method = $this->namespace .'.'. $method;
                }
-               $this->request->setPostData(xmlrpc_encode_request($method, $params));
+               $this->request->setRawPostData(xmlrpc_encode_request($method, $params));
                $response = $this->request->send();
                if ($response->getResponseCode() != 200) {
                        throw new Exception($response->getBody(), $response->getResponseCode());
@@ -339,4 +341,130 @@ class FeedAggregator
 }
 ?>
 
+- 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 HttpExcpetion("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;
+       }
+}
+?>