00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00016 final class CurlHttpClient implements HttpClient
00017 {
00018 private $handle = null;
00019 private $timeout = null;
00020 private $followLocation = null;
00021 private $maxRedirects = null;
00022 private $maxFileSize = null;
00023 private $noBody = null;
00024
00028 public static function create()
00029 {
00030 return new self;
00031 }
00032
00037 public function setTimeout($timeout)
00038 {
00039 $this->timeout = $timeout;
00040 return $this;
00041 }
00042
00043 public function getTimeout()
00044 {
00045 return $this->timeout;
00046 }
00047
00054 public function setFollowLocation($really)
00055 {
00056 Assert::isBoolean($really);
00057 $this->followLocation = $really;
00058 return $this;
00059 }
00060
00061 public function isFollowLocation()
00062 {
00063 return $this->followLocation;
00064 }
00065
00070 public function setNoBody($really)
00071 {
00072 Assert::isBoolean($really);
00073 $this->noBody = $really;
00074 return $this;
00075 }
00076
00077 public function hasNoBody()
00078 {
00079 return $this->noBody;
00080 }
00081
00085 public function setMaxRedirects($maxRedirects)
00086 {
00087 $this->maxRedirects = $maxRedirects;
00088 return $this;
00089 }
00090
00091 public function getMaxRedirects()
00092 {
00093 return $this->maxRedirects;
00094 }
00095
00099 public function setMaxFileSize($maxFileSize)
00100 {
00101 $this->maxFileSize = $maxFileSize;
00102 return $this;
00103 }
00104
00105 public function getMaxFileSize()
00106 {
00107 return $this->maxFileSize;
00108 }
00109
00113 public function send(HttpRequest $request)
00114 {
00115 Assert::isTrue(
00116 in_array(
00117 $request->getMethod()->getId(),
00118 array(HttpMethod::GET, HttpMethod::POST)
00119 )
00120 );
00121
00122 $handle = curl_init();
00123
00124 $response = CurlHttpResponse::create()->
00125 setMaxFileSize($this->maxFileSize);
00126
00127 $options = array(
00128 CURLOPT_WRITEFUNCTION => array($response, 'writeBody'),
00129 CURLOPT_HEADERFUNCTION => array($response, 'writeHeader'),
00130 CURLOPT_URL => $request->getUrl()->toString(),
00131 CURLOPT_USERAGENT => 'onPHP::'.__CLASS__
00132 );
00133
00134 if ($this->timeout !== null)
00135 $options[CURLOPT_TIMEOUT] = $this->timeout;
00136
00137 if ($this->followLocation !== null)
00138 $options[CURLOPT_FOLLOWLOCATION] = $this->followLocation;
00139
00140 if ($this->maxRedirects !== null)
00141 $options[CURLOPT_MAXREDIRS] = $this->maxRedirects;
00142
00143 if ($request->getMethod()->getId() == HttpMethod::GET) {
00144 $options[CURLOPT_HTTPGET] = true;
00145
00146 if ($request->getGet()) {
00147 $options[CURLOPT_URL] .=
00148 '?'.$this->argumentsToString($request->getGet());
00149 }
00150 } else {
00151 $options[CURLOPT_POST] = true;
00152 $options[CURLOPT_POSTFIELDS] =
00153 $this->argumentsToString($request->getPost());
00154 }
00155
00156 if ($this->noBody !== null)
00157 $options[CURLOPT_NOBODY] = $this->noBody;
00158
00159 curl_setopt_array($handle, $options);
00160
00161 if (curl_exec($handle) === false) {
00162 throw new NetworkException(
00163 'curl error, code: '
00164 .curl_errno($handle)
00165 .' description: '
00166 .curl_error($handle)
00167 );
00168 }
00169
00170 $response->setStatus(
00171 new HttpStatus(
00172 curl_getinfo($handle, CURLINFO_HTTP_CODE)
00173 )
00174 );
00175
00176 curl_close($handle);
00177
00178 return $response;
00179 }
00180
00181 private function argumentsToString($array)
00182 {
00183 Assert::isArray($array);
00184 $result = array();
00185
00186 foreach ($array as $key => $value) {
00187 $result[] = $key.'='.urlencode($value);
00188 }
00189
00190 return implode('&', $result);
00191 }
00192 }
00193 ?>