svn: /pear/peardoc/trunk/en/package/http/ http-request2/adapters.xml http-request2/config.xml http-request2/intro.xml http-request2/observers.xml http-request2/request.xml http-request2/response.xml http-request2.xml

[email protected] (Alexey Borzov)
Newsgroups php.pear.doc
Message-ID <[email protected]>
avb                                      Fri, 25 Sep 2009 09:20:24 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=288727

Log:
Finished HTTP_Request2 docs

Changed paths:
    U   pear/peardoc/trunk/en/package/http/http-request2/adapters.xml
    U   pear/peardoc/trunk/en/package/http/http-request2/config.xml
    U   pear/peardoc/trunk/en/package/http/http-request2/intro.xml
    U   pear/peardoc/trunk/en/package/http/http-request2/observers.xml
    U   pear/peardoc/trunk/en/package/http/http-request2/request.xml
    U   pear/peardoc/trunk/en/package/http/http-request2/response.xml
    U   pear/peardoc/trunk/en/package/http/http-request2.xml
svn-diffs-288727.txt (text/x-diff, 19.6 KB)
Modified: pear/peardoc/trunk/en/package/http/http-request2/adapters.xml
===================================================================
--- pear/peardoc/trunk/en/package/http/http-request2/adapters.xml	2009-09-25 08:50:00 UTC (rev 288726)
+++ pear/peardoc/trunk/en/package/http/http-request2/adapters.xml	2009-09-25 09:20:24 UTC (rev 288727)
@@ -7,10 +7,10 @@
 >
  <refnamediv>
   <refname>Adapters</refname>
-  <refpurpose>Classes That Actually Perform the Request</refpurpose>
+  <refpurpose>Classes that actually perform the request</refpurpose>
  </refnamediv>
  <refsection xml:id="package.http.http-request2.adapters.overview">
-  <info><title>Adapters Overview</title></info>
+  <info><title>Overview</title></info>
   <para>
    Adapters in <classname>HTTP_Request2</classname> package are classes responsible for establishing
    the actual connection to the remote server, writing requests and reading responses. Adapter can
@@ -98,9 +98,9 @@
    <constant>CURLOPT_READFUNCTION</constant> callback. PHP does not allow setting another callback,
    <constant>CURLOPT_IOCTLFUNCTION</constant> (see <link xmlns:xlink="http://www.w3.org/1999/xlink"
     xlink:href="&url.php.bugs;47204">PHP bug #47204</link>) so the request body can not be
-   &quot;rewound&quot; when another request should be performed. Thus a <literal>POST</literal>
-   request to a resource protected by Digest authentication will always fail, since Digest scheme
-   requires two requests to be performed.
+   &quot;rewound&quot; when another request should be performed. Thus a request with a non-empty
+   body to a resource protected by Digest authentication will always fail, since Digest scheme
+   requires two requests to be performed.
   </para>
  </refsection>


Modified: pear/peardoc/trunk/en/package/http/http-request2/config.xml
===================================================================
--- pear/peardoc/trunk/en/package/http/http-request2/config.xml	2009-09-25 08:50:00 UTC (rev 288726)
+++ pear/peardoc/trunk/en/package/http/http-request2/config.xml	2009-09-25 09:20:24 UTC (rev 288727)
@@ -2,7 +2,7 @@
 <refentry xmlns="http://docbook.org/ns/docbook" xmlns:phd="http://www.php.net/ns/phd" version="lillet" xml:id="package.http.http-request2.config">
  <refnamediv>
   <refname>Configuration</refname>
-  <refpurpose>Configuration Parameters for <classname>HTTP_Request2</classname></refpurpose>
+  <refpurpose>Configuration parameters for <classname>HTTP_Request2</classname></refpurpose>
  </refnamediv>
  <refsection xml:id="package.http.http-request2.config.table">
   <info><title>List of Configuration Parameters</title></info>

Modified: pear/peardoc/trunk/en/package/http/http-request2/intro.xml
===================================================================
--- pear/peardoc/trunk/en/package/http/http-request2/intro.xml	2009-09-25 08:50:00 UTC (rev 288726)
+++ pear/peardoc/trunk/en/package/http/http-request2/intro.xml	2009-09-25 09:20:24 UTC (rev 288727)
@@ -44,15 +44,17 @@
       maybe proxy parameters (if you are using proxy).
      </simpara></listitem>
      <listitem><simpara>
-      Calling <phd:pearapi phd:package="HTTP_Request2"
-       phd:linkend="HTTP_Request2::send">send</phd:pearapi> method of that instance. This will pass
-      control to <link linkend="package.http.http-request2.adapters">an Adapter</link> that will send
+      Calling <function><phd:pearapi phd:package="HTTP_Request2"
+       phd:linkend="HTTP_Request2::send">send</phd:pearapi></function> method of that instance. This
+      will pass control to <link linkend="package.http.http-request2.adapters">an Adapter</link> that will send
       the request and read remote server's response. Request's progress may be monitored by using
       <link linkend="package.http.http-request2.observers">Observers</link>
      </simpara></listitem>
      <listitem><simpara>
       Processing the returned instance of <link
        linkend="package.http.http-request2.response"><classname>HTTP_Request2_Response</classname></link>.
+      An instance of <classname>HTTP_Request2_Exception</classname> can also be thrown by
+      <function>send</function> if response could not be received (completely or at all) or parsed.
      </simpara></listitem>
     </itemizedlist>
    </para>

Modified: pear/peardoc/trunk/en/package/http/http-request2/observers.xml
===================================================================
--- pear/peardoc/trunk/en/package/http/http-request2/observers.xml	2009-09-25 08:50:00 UTC (rev 288726)
+++ pear/peardoc/trunk/en/package/http/http-request2/observers.xml	2009-09-25 09:20:24 UTC (rev 288727)
@@ -1,17 +1,176 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<refentry xmlns="http://docbook.org/ns/docbook" version="lillet" xml:id="package.http.http-request2.observers">
+<refentry
+ xmlns="http://docbook.org/ns/docbook"
+ xmlns:phd="http://www.php.net/ns/phd"
+ version="lillet"
+ xml:id="package.http.http-request2.observers"
+>
+<!--
+FIXME: add links to PHP manual once docs for SplSubject and SplObserver are there. No sense adding
+them now, since nothing will be found.
+-->
  <refnamediv>
   <refname>Observers</refname>
-  <refpurpose>Monitoring the Request's Progress</refpurpose>
+  <refpurpose>Monitoring the request's progress</refpurpose>
  </refnamediv>
  <refsection xml:id="package.http.http-request2.observers.overview">
-  <info><title>Observers Overview</title></info>
+  <info><title>Overview</title></info>
   <para>
+   Observers are classes that can be attached to an instance of <classname>HTTP_Request2</classname>
+   and notified of request's progress. Possible uses:
+   <itemizedlist>
+    <listitem><simpara>
+     Drawing a progress bar for large file uploads and / or downloads;
+    </simpara></listitem>
+    <listitem><simpara>
+     Saving large response body to disk instead of storing it in memory;
+    </simpara></listitem>
+    <listitem><simpara>
+     Cancelling the request by throwing an exception in Observer.
+    </simpara></listitem>
+   </itemizedlist>
   </para>
+  <para>
+   <classname>HTTP_Request2</classname> implements <interfacename>SplSubject</interfacename>
+   interface, so Observers should implement <interfacename>SplObserver</interfacename>. When
+   Observer is notified of an event, it should use <phd:pearapi phd:package="HTTP_Request2"
+   phd:linkend="HTTP_Request2::getLastEvent" /> to access event details. That method returns an
+   associative array with <literal>'name'</literal> and <literal>'data'</literal> keys. Possible
+   event names are
+   <variablelist>
+    <varlistentry>
+     <term><literal>'connect'</literal></term>
+     <listitem><simpara>
+      On connection to remote server, <literal>'data'</literal> is the destination (&type.string;).
+     </simpara></listitem>
+    </varlistentry>
+    <varlistentry>
+     <term><literal>'disconnect'</literal></term>
+     <listitem><simpara>
+      On disconnection from server.
+     </simpara></listitem>
+    </varlistentry>
+    <varlistentry>
+     <term><literal>'sentHeaders'</literal></term>
+     <listitem><simpara>
+      On sending the request headers, <literal>'data'</literal> is the headers sent (&type.string;).
+     </simpara></listitem>
+    </varlistentry>
+    <varlistentry>
+     <term><literal>'sentBodyPart'</literal></term>
+     <listitem><simpara>
+      On sending a part of the request body, <literal>'data'</literal> is the length of that part
+      (&type.integer;).
+     </simpara></listitem>
+    </varlistentry>
+    <varlistentry>
+     <term><literal>'receivedHeaders'</literal></term>
+     <listitem><simpara>
+      On receiving the response headers, <literal>'data'</literal> is
+      <classname>HTTP_Request2_Response</classname> object containing these headers.
+     </simpara></listitem>
+    </varlistentry>
+    <varlistentry>
+     <term><literal>'receivedBodyPart'</literal></term>
+     <listitem><simpara>
+      On receiving a part of the response body, <literal>'data'</literal> is the received part
+      (&type.string;).
+     </simpara></listitem>
+    </varlistentry>
+    <varlistentry>
+     <term><literal>'receivedEncodedBodyPart'</literal></term>
+     <listitem><simpara>
+      As <literal>'receivedBodyPart'</literal>, but <literal>'data'</literal> is still encoded by
+      relevant <literal>Content-Encoding</literal>.
+     </simpara></listitem>
+    </varlistentry>
+    <varlistentry>
+     <term><literal>'receivedBody'</literal></term>
+     <listitem><simpara>
+      On receiving the complete response body, data is <classname>HTTP_Request2_Response</classname>
+      object, probably containing this body.
+     </simpara></listitem>
+    </varlistentry>
+   </variablelist>
+  </para>
+  <note><para>
+   As the events are actually send by request Adapters, you can receive fewer or different events
+   if you switch to another Adapter. Curl Adapter does not notify of <literal>'connect'</literal>,
+   <literal>'disconnect'</literal> and <literal>'receivedEncodedBodyPart'</literal> events (it
+   always uses <literal>'receivedBodyPart'</literal> as cURL extension takes care of decoding).
+   Mock Adapter does not send any notifications at all.
+  </para></note>
  </refsection>
+
  <refsection xml:id="package.http.http-request2.observers.example">
-  <info><title>Observers Example</title></info>
+  <info><title>Usage Example</title></info>
   <para>
+   The following example shows how an Observer can be used to save response body to disk without
+   storing it in memory. Note that only events relevant to that task are handled in its
+   <function>update</function> method, the others can be safely ignored.
   </para>
+  <para>
+   The package contains another Observer implementation: <phd:pearapi phd:package="HTTP_Request2"
+    phd:linkend="HTTP_Request2_Observer_Log" /> class that allows logging request progress to a file
+   or an instance of <link linkend="package.logging.log"><classname>Log</classname></link>.
+  </para>
+  <example>
+   <title>Saving response body to disk</title>
+   <programlisting role="php"><![CDATA[
+class HTTP_Request2_Observer_Download implements SplObserver
+{
+    protected $dir;
+
+    protected $fp;
+
+    public function __construct($dir)
+    {
+        if (!is_dir($dir)) {
+            throw new Exception("'{$dir}' is not a directory");
+        }
+        $this->dir = $dir;
+    }
+
+    public function update(SplSubject $subject)
+    {
+        $event = $subject->getLastEvent();
+
+        switch ($event['name']) {
+        case 'receivedHeaders':
+            if ($disposition = $event['data']->getHeader('content-disposition')
+                && 0 == strpos($disposition, 'attachment')
+                && preg_match('/filename="([^"]+)"/', $disposition, $m)
+            ) {
+                $filename = basename($m[1]);
+            } else {
+                $filename = basename($subject->getUrl()->getPath());
+            }
+            $target = $this->dir . DIRECTORY_SEPARATOR . $filename;
+            if (!($this->fp = @fopen($target, 'wb'))) {
+                throw new Exception("Cannot open target file '{$target}'");
+            }
+            break;
+
+        case 'receivedBodyPart':
+        case 'receivedEncodedBodyPart':
+            fwrite($this->fp, $event['data']);
+            break;
+
+        case 'receivedBody':
+            fclose($this->fp);
+        }
+    }
+}
+
+$request = new HTTP_Request2(
+    'http://pear.php.net/distributions/manual/pear_manual_en.tar.bz2',
+    HTTP_Request2::METHOD_GET, array('store_body' => false)
+);
+$request->attach(new HTTP_Request2_Observer_Download('.'));
+
+// This won't output anything since body isn't stored in the response
+echo $request->send()->getBody();
+   ]]></programlisting>
+  </example>
  </refsection>
 </refentry>

Modified: pear/peardoc/trunk/en/package/http/http-request2/request.xml
===================================================================
--- pear/peardoc/trunk/en/package/http/http-request2/request.xml	2009-09-25 08:50:00 UTC (rev 288726)
+++ pear/peardoc/trunk/en/package/http/http-request2/request.xml	2009-09-25 09:20:24 UTC (rev 288727)
@@ -7,7 +7,7 @@
 >
  <refnamediv>
   <refname><classname>HTTP_Request2</classname></refname>
-  <refpurpose>Class Representing a HTTP Request</refpurpose>
+  <refpurpose>Class representing a HTTP request message</refpurpose>
  </refnamediv>
  <refsection xml:id="package.http.http-request2.request.url">
   <info><title>Request <acronym>URL</acronym> and <literal>GET</literal> Parameters</title></info>

Modified: pear/peardoc/trunk/en/package/http/http-request2/response.xml
===================================================================
--- pear/peardoc/trunk/en/package/http/http-request2/response.xml	2009-09-25 08:50:00 UTC (rev 288726)
+++ pear/peardoc/trunk/en/package/http/http-request2/response.xml	2009-09-25 09:20:24 UTC (rev 288727)
@@ -1,17 +1,109 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<refentry xmlns="http://docbook.org/ns/docbook" version="lillet" xml:id="package.http.http-request2.response">
+<refentry
+ xmlns="http://docbook.org/ns/docbook"
+ xmlns:phd="http://www.php.net/ns/phd"
+ version="lillet"
+ xml:id="package.http.http-request2.response"
+>
  <refnamediv>
   <refname><classname>HTTP_Request2_Response</classname></refname>
-  <refpurpose>Class Representing a HTTP Response</refpurpose>
+  <refpurpose>Class representing a HTTP response message</refpurpose>
  </refnamediv>
  <refsection xml:id="package.http.http-request2.response.overview">
-  <info><title><classname>HTTP_Request2_Response</classname> Overview</title></info>
+  <info><title>Overview</title></info>
   <para>
+   <classname>HTTP_Request2_Response</classname> encapsulates a HTTP response message and provides
+   easy access to different parts of it. It also contains static helper methods
+   <phd:pearapi phd:package="HTTP_Request2" phd:linkend="HTTP_Request2_Response::decodeGzip" /> and
+   <phd:pearapi phd:package="HTTP_Request2" phd:linkend="HTTP_Request2_Response::decodeDeflate" />
+   for decoding response bodies encoded by <literal>Content-Encoding: gzip</literal> (as defined in
+   <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="&url.rfc;1952">RFC 1952</link>) and
+   <literal>Content-Encoding: deflate</literal> (<link xmlns:xlink="http://www.w3.org/1999/xlink"
+   xlink:href="&url.rfc;1950">RFC 1950</link>), respectively.
   </para>
+  <para>
+   An instance of this class will usually be returned by
+   <phd:pearapi phd:package="HTTP_Request2" phd:linkend="HTTP_Request2::send" />
+   method. You can also build an instance yourself using either helper methods of
+   <classname>HTTP_Request2_Adapter_Mock</classname> or manually (see below).
+  </para>
+  <para>
+   You can use the following methods for accessing various parts of HTTP response:
+   <phd:pearapi phd:package="HTTP_Request2" phd:linkend="HTTP_Request2_Response::getStatus">getStatus()</phd:pearapi>,
+   <phd:pearapi phd:package="HTTP_Request2" phd:linkend="HTTP_Request2_Response::getReasonPhrase">getReasonPhrase()</phd:pearapi>,
+   <phd:pearapi phd:package="HTTP_Request2" phd:linkend="HTTP_Request2_Response::getVersion">getVersion()</phd:pearapi>,
+   <phd:pearapi phd:package="HTTP_Request2" phd:linkend="HTTP_Request2_Response::getHeader">getHeader()</phd:pearapi>,
+   <phd:pearapi phd:package="HTTP_Request2" phd:linkend="HTTP_Request2_Response::getCookies">getCookies()</phd:pearapi>,
+   <phd:pearapi phd:package="HTTP_Request2" phd:linkend="HTTP_Request2_Response::getBody">getBody()</phd:pearapi>.
+   Note that the response object will not contain the response body if
+   <literal>'store_body'</literal> configuration parameter was set to &false;. Also note that
+   <function>getBody</function> always returns body completely decoded, if for some reason you want
+   to access body still encoded by <literal>gzip</literal> / <literal>deflate</literal> you'll need
+   to use Observers <emphasis>and</emphasis> Socket adapter.
+   <example>
+    <title>Accessing response parts</title>
+    <programlisting role="php"><![CDATA[
+$request  = new HTTP_Request2('http://www.example.com/');
+$response = $request->send();
+
+echo "Response status: " . $response->getStatus() . "\n";
+echo "Human-readable reason phrase: " . $response->getReasonPhrase() . "\n";
+echo "Response HTTP version: " . $response->getVersion() . "\n";
+echo "Response headers:\n";
+foreach ($response->getHeader() as $k => $v) {
+    echo "\t{$k}: {$v}\n";
+}
+echo "Value of a specific header (Content-Type): " . $response->getHeader('content-type') . "\n";
+echo "Cookies set in response:\n";
+foreach ($response->getCookies() as $c) {
+    echo "\tname: {$c['name']}, value: {$c['value']}" .
+         (empty($c['expires'])? '': ", expires: {$c['expires']}") .
+         (empty($c['domain'])? '': ", domain: {$c['domain']}") .
+         (empty($c['path'])? '': ", path: {$c['path']}") .
+         ", secure: " . ($c['secure']? 'yes': 'no') . "\n";
+
+}
+echo "Response body:\n" . $response->getBody();
+     ]]></programlisting>
+   </example>
+  </para>
  </refsection>
- <refsection xml:id="package.http.http-request2.response.reading">
-  <info><title>Reading the Response</title></info>
+ <refsection xml:id="package.http.http-request2.response.building">
+  <info><title>Building the Response Manually</title></info>
   <para>
+   The class is designed to be used in &quot;streaming&quot; scenario, building the response as it is being received:
+   <example>
+    <title>Building the response (pseudocode)</title>
+    <programlisting role="php"><![CDATA[
+$statusLine = read_status_line();
+$response = new HTTP_Request2_Response($statusLine);
+
+do {
+    $headerLine = read_header_line();
+    $response->parseHeaderLine($headerLine);
+} while ($headerLine != '');
+
+while ($chunk = read_body()) {
+    $response->appendBody($chunk);
+}
+     ]]></programlisting>
+   </example>
   </para>
+  <para>
+   Everything is straightforward enough, but a few things need considering:
+   <itemizedlist>
+    <listitem><simpara>
+     <phd:pearapi phd:package="HTTP_Request2"
+      phd:linkend="HTTP_Request2_Response::__construct">Constructor</phd:pearapi> will throw an
+     exception if the provided string does not look like a valid response status line.
+    </simpara></listitem>
+    <listitem><simpara>
+     It is necessary to pass an empty string to <phd:pearapi phd:package="HTTP_Request2"
+      phd:linkend="HTTP_Request2_Response::parseHeaderLine">parseHeaderLine()</phd:pearapi> to
+     indicate the end of response headers: this triggers some additional processing (e.g. cookie
+     parsing).
+    </simpara></listitem>
+   </itemizedlist>
+  </para>
  </refsection>
 </refentry>
\ No newline at end of file

Modified: pear/peardoc/trunk/en/package/http/http-request2.xml
===================================================================
--- pear/peardoc/trunk/en/package/http/http-request2.xml	2009-09-25 08:50:00 UTC (rev 288726)
+++ pear/peardoc/trunk/en/package/http/http-request2.xml	2009-09-25 09:20:24 UTC (rev 288727)
@@ -7,9 +7,15 @@
     PHP5 rewrite of <link linkend="package.http.http-request"><classname>HTTP_Request</classname></link>
     package. Provides cleaner API and pluggable Adapters:
     <itemizedlist>
-     <listitem><simpara>Socket adapter, based on old HTTP_Request code,</simpara></listitem>
-     <listitem><simpara>Curl adapter, wraps around PHP's cURL extension,</simpara></listitem>
-     <listitem><simpara>Mock adapter, useful for testing packages dependent on HTTP_Request2.</simpara></listitem>
+     <listitem><simpara>
+      Socket adapter, based on old <classname>HTTP_Request</classname> code,
+     </simpara></listitem>
+     <listitem><simpara>
+      Curl adapter, wraps around PHP's cURL extension,
+     </simpara></listitem>
+     <listitem><simpara>
+      Mock adapter, useful for testing packages dependent on <classname>HTTP_Request2</classname>.
+     </simpara></listitem>
     </itemizedlist>
    </para>
    <simpara>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.