File indexing completed on 2024-06-23 05:55:43

0001 <?php
0002 
0003 /**
0004  * Copyright (c) 2007-2011, Servigistics, Inc.
0005  * All rights reserved.
0006  *
0007  * Redistribution and use in source and binary forms, with or without
0008  * modification, are permitted provided that the following conditions are met:
0009  *
0010  *  - Redistributions of source code must retain the above copyright notice,
0011  *    this list of conditions and the following disclaimer.
0012  *  - Redistributions in binary form must reproduce the above copyright
0013  *    notice, this list of conditions and the following disclaimer in the
0014  *    documentation and/or other materials provided with the distribution.
0015  *  - Neither the name of Servigistics, Inc. nor the names of
0016  *    its contributors may be used to endorse or promote products derived from
0017  *    this software without specific prior written permission.
0018  *
0019  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0020  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0021  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0022  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0023  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0024  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0025  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0026  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0027  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0028  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0029  * POSSIBILITY OF SUCH DAMAGE.
0030  *
0031  * @copyright Copyright 2007-2011 Servigistics, Inc. (http://servigistics.com)
0032  * @license http://solr-php-client.googlecode.com/svn/trunk/COPYING New BSD
0033  * @version $Id: $
0034  *
0035  * @package Apache
0036  * @subpackage Solr
0037  * @author Donovan Jimenez <djimenez@conduit-it.com>
0038  */
0039 require_once 'Zend/Service/Solr/HttpTransport/Abstract.php';
0040 
0041 /**
0042  * HTTP Transport implemenation that uses the builtin http URL wrappers and file_get_contents
0043  */
0044 class Zend_Service_Solr_HttpTransport_FileGetContents extends Zend_Service_Solr_HttpTransport_Abstract {
0045     /**
0046      * SVN Revision meta data for this class
0047      */
0048     const SVN_REVISION = '$Revision:  $';
0049 
0050     /**
0051      * SVN ID meta data for this class
0052      */
0053     const SVN_ID = '$Id:  $';
0054 
0055     /**
0056      * Reusable stream context resources for GET and POST operations
0057      *
0058      * @var resource
0059      */
0060     private $_getContext, $_headContext, $_postContext;
0061 
0062     /**
0063      * Initializes our reuseable get and post stream contexts
0064      */
0065     public function __construct() {
0066         $this->_getContext = stream_context_create();
0067         $this->_headContext = stream_context_create();
0068         $this->_postContext = stream_context_create();
0069     }
0070 
0071     public function performGetRequest($url, $timeout = false) {
0072         // set the timeout if specified
0073         if ($timeout !== FALSE && $timeout > 0.0) {
0074             // timeouts with file_get_contents seem to need
0075             // to be halved to work as expected
0076             $timeout = (float) $timeout / 2;
0077 
0078             stream_context_set_option($this->_getContext, 'http', 'timeout', $timeout);
0079         } else {
0080             // use the default timeout pulled from default_socket_timeout otherwise
0081             stream_context_set_option($this->_getContext, 'http', 'timeout', $this->getDefaultTimeout());
0082         }
0083 
0084         // $http_response_headers will be updated by the call to file_get_contents later
0085         // see http://us.php.net/manual/en/wrappers.http.php for documentation
0086         // Unfortunately, it will still create a notice in analyzers if we don't set it here
0087         $http_response_header = null;
0088         $responseBody = @file_get_contents($url, false, $this->_getContext);
0089 
0090         return $this->_getResponseFromParts($responseBody, $http_response_header);
0091     }
0092 
0093     public function performHeadRequest($url, $timeout = false) {
0094         stream_context_set_option($this->_headContext, array(
0095             'http' => array(
0096                 // set HTTP method
0097                 'method' => 'HEAD',
0098                 // default timeout
0099                 'timeout' => $this->getDefaultTimeout()
0100             )
0101                 )
0102         );
0103 
0104         // set the timeout if specified
0105         if ($timeout !== FALSE && $timeout > 0.0) {
0106             // timeouts with file_get_contents seem to need
0107             // to be halved to work as expected
0108             $timeout = (float) $timeout / 2;
0109 
0110             stream_context_set_option($this->_headContext, 'http', 'timeout', $timeout);
0111         }
0112 
0113         // $http_response_headers will be updated by the call to file_get_contents later
0114         // see http://us.php.net/manual/en/wrappers.http.php for documentation
0115         // Unfortunately, it will still create a notice in analyzers if we don't set it here
0116         $http_response_header = null;
0117         $responseBody = @file_get_contents($url, false, $this->_headContext);
0118 
0119         return $this->_getResponseFromParts($responseBody, $http_response_header);
0120     }
0121 
0122     public function performPostRequest($url, $rawPost, $contentType, $timeout = false) {
0123         stream_context_set_option($this->_postContext, array(
0124             'http' => array(
0125                 // set HTTP method
0126                 'method' => 'POST',
0127                 // Add our posted content type
0128                 'header' => "Content-Type: $contentType",
0129                 // the posted content
0130                 'content' => $rawPost,
0131                 // default timeout
0132                 'timeout' => $this->getDefaultTimeout()
0133             )
0134                 )
0135         );
0136 
0137         // set the timeout if specified
0138         if ($timeout !== FALSE && $timeout > 0.0) {
0139             // timeouts with file_get_contents seem to need
0140             // to be halved to work as expected
0141             $timeout = (float) $timeout / 2;
0142 
0143             stream_context_set_option($this->_postContext, 'http', 'timeout', $timeout);
0144         }
0145 
0146         // $http_response_header will be updated by the call to file_get_contents later
0147         // see http://us.php.net/manual/en/wrappers.http.php for documentation
0148         // Unfortunately, it will still create a notice in analyzers if we don't set it here
0149         $http_response_header = null;
0150         $responseBody = @file_get_contents($url, false, $this->_postContext);
0151 
0152         // reset content of post context to reclaim memory
0153         stream_context_set_option($this->_postContext, 'http', 'content', '');
0154 
0155         return $this->_getResponseFromParts($responseBody, $http_response_header);
0156     }
0157 
0158     private function _getResponseFromParts($rawResponse, $httpHeaders) {
0159         //Assume 0, false as defaults
0160         $status = 0;
0161         $contentType = false;
0162 
0163         //iterate through headers for real status, type, and encoding
0164         if (is_array($httpHeaders) && count($httpHeaders) > 0) {
0165             //look at the first headers for the HTTP status code
0166             //and message (errors are usually returned this way)
0167             //
0168       //HTTP 100 Continue response can also be returned before
0169             //the REAL status header, so we need look until we find
0170             //the last header starting with HTTP
0171             //
0172       //the spec: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.1
0173             //
0174       //Thanks to Daniel Andersson for pointing out this oversight
0175             while (isset($httpHeaders[0]) && substr($httpHeaders[0], 0, 4) == 'HTTP') {
0176                 // we can do a intval on status line without the "HTTP/1.X " to get the code
0177                 $status = intval(substr($httpHeaders[0], 9));
0178 
0179                 // remove this from the headers so we can check for more
0180                 array_shift($httpHeaders);
0181             }
0182 
0183             //Look for the Content-Type response header and determine type
0184             //and encoding from it (if possible - such as 'Content-Type: text/plain; charset=UTF-8')
0185             foreach ($httpHeaders as $header) {
0186                 // look for the header that starts appropriately
0187                 if (strncasecmp($header, 'Content-Type:', 13) == 0) {
0188                     $contentType = substr($header, 13);
0189                     break;
0190                 }
0191             }
0192         }
0193 
0194         return new Zend_Service_Solr_HttpTransport_Response($status, $contentType, $rawResponse);
0195     }
0196 
0197 }