3 * Base class for HTTP_Request2 adapters
\r
9 * Copyright (c) 2008, 2009, Alexey Borzov <avb@php.net>
\r
10 * All rights reserved.
\r
12 * Redistribution and use in source and binary forms, with or without
\r
13 * modification, are permitted provided that the following conditions
\r
16 * * Redistributions of source code must retain the above copyright
\r
17 * notice, this list of conditions and the following disclaimer.
\r
18 * * Redistributions in binary form must reproduce the above copyright
\r
19 * notice, this list of conditions and the following disclaimer in the
\r
20 * documentation and/or other materials provided with the distribution.
\r
21 * * The names of the authors may not be used to endorse or promote products
\r
22 * derived from this software without specific prior written permission.
\r
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
\r
25 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
\r
26 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
\r
27 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
\r
28 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
\r
29 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
\r
30 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
\r
31 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
\r
32 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
\r
33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
\r
34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
37 * @package HTTP_Request2
\r
38 * @author Alexey Borzov <avb@php.net>
\r
39 * @license http://opensource.org/licenses/bsd-license.php New BSD License
\r
40 * @version CVS: $Id: Adapter.php 274684 2009-01-26 23:07:27Z avb $
\r
41 * @link http://pear.php.net/package/HTTP_Request2
\r
45 * Class representing a HTTP response
\r
47 require_once 'HTTP/Request2/Response.php';
\r
50 * Base class for HTTP_Request2 adapters
\r
52 * HTTP_Request2 class itself only defines methods for aggregating the request
\r
53 * data, all actual work of sending the request to the remote server and
\r
54 * receiving its response is performed by adapters.
\r
57 * @package HTTP_Request2
\r
58 * @author Alexey Borzov <avb@php.net>
\r
59 * @version Release: 0.4.1
\r
61 abstract class HTTP_Request2_Adapter
\r
64 * A list of methods that MUST NOT have a request body, per RFC 2616
\r
67 protected static $bodyDisallowed = array('TRACE');
\r
70 * Methods having defined semantics for request body
\r
72 * Content-Length header (indicating that the body follows, section 4.3 of
\r
73 * RFC 2616) will be sent for these methods even if no body was added
\r
76 * @link http://pear.php.net/bugs/bug.php?id=12900
\r
77 * @link http://pear.php.net/bugs/bug.php?id=14740
\r
79 protected static $bodyRequired = array('POST', 'PUT');
\r
82 * Request being sent
\r
83 * @var HTTP_Request2
\r
89 * @var string|resource|HTTP_Request2_MultipartBody
\r
90 * @see HTTP_Request2::getBody()
\r
92 protected $requestBody;
\r
95 * Length of the request body
\r
98 protected $contentLength;
\r
101 * Sends request to the remote server and returns its response
\r
103 * @param HTTP_Request2
\r
104 * @return HTTP_Request2_Response
\r
105 * @throws HTTP_Request2_Exception
\r
107 abstract public function sendRequest(HTTP_Request2 $request);
\r
110 * Calculates length of the request body, adds proper headers
\r
112 * @param array associative array of request headers, this method will
\r
113 * add proper 'Content-Length' and 'Content-Type' headers
\r
114 * to this array (or remove them if not needed)
\r
116 protected function calculateRequestLength(&$headers)
\r
118 $this->requestBody = $this->request->getBody();
\r
120 if (is_string($this->requestBody)) {
\r
121 $this->contentLength = strlen($this->requestBody);
\r
122 } elseif (is_resource($this->requestBody)) {
\r
123 $stat = fstat($this->requestBody);
\r
124 $this->contentLength = $stat['size'];
\r
125 rewind($this->requestBody);
\r
127 $this->contentLength = $this->requestBody->getLength();
\r
128 $headers['content-type'] = 'multipart/form-data; boundary=' .
\r
129 $this->requestBody->getBoundary();
\r
130 $this->requestBody->rewind();
\r
133 if (in_array($this->request->getMethod(), self::$bodyDisallowed) ||
\r
134 0 == $this->contentLength
\r
136 unset($headers['content-type']);
\r
137 // No body: send a Content-Length header nonetheless (request #12900),
\r
138 // but do that only for methods that require a body (bug #14740)
\r
139 if (in_array($this->request->getMethod(), self::$bodyRequired)) {
\r
140 $headers['content-length'] = 0;
\r
142 unset($headers['content-length']);
\r
145 if (empty($headers['content-type'])) {
\r
146 $headers['content-type'] = 'application/x-www-form-urlencoded';
\r
148 $headers['content-length'] = $this->contentLength;
\r