Request.php 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. <?php
  2. /**
  3. * Hoa
  4. *
  5. *
  6. * @license
  7. *
  8. * New BSD License
  9. *
  10. * Copyright © 2007-2017, Hoa community. All rights reserved.
  11. *
  12. * Redistribution and use in source and binary forms, with or without
  13. * modification, are permitted provided that the following conditions are met:
  14. * * Redistributions of source code must retain the above copyright
  15. * notice, this list of conditions and the following disclaimer.
  16. * * Redistributions in binary form must reproduce the above copyright
  17. * notice, this list of conditions and the following disclaimer in the
  18. * documentation and/or other materials provided with the distribution.
  19. * * Neither the name of the Hoa nor the names of its contributors may be
  20. * used to endorse or promote products derived from this software without
  21. * specific prior written permission.
  22. *
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  24. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE
  27. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  28. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  29. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  30. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  31. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  32. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  33. * POSSIBILITY OF SUCH DAMAGE.
  34. */
  35. namespace Hoa\Http;
  36. /**
  37. * Class \Hoa\Http\Request.
  38. *
  39. * HTTP request support.
  40. *
  41. * @copyright Copyright © 2007-2017 Hoa community
  42. * @license New BSD License
  43. */
  44. class Request extends Http
  45. {
  46. /**
  47. * Method: CONNECT.
  48. *
  49. * @const string
  50. */
  51. const METHOD_CONNECT = 'connect';
  52. /**
  53. * Method: DELETE.
  54. *
  55. * @const string
  56. */
  57. const METHOD_DELETE = 'delete';
  58. /**
  59. * Method: GET.
  60. *
  61. * @const string
  62. */
  63. const METHOD_GET = 'get';
  64. /**
  65. * Method: HEAD.
  66. *
  67. * @const string
  68. */
  69. const METHOD_HEAD = 'head';
  70. /**
  71. * Method: OPTIONS.
  72. *
  73. * @const string
  74. */
  75. const METHOD_OPTIONS = 'options';
  76. /**
  77. * Method: PATCH.
  78. *
  79. * @const string
  80. */
  81. const METHOD_PATCH = 'patch';
  82. /**
  83. * Method: POST.
  84. *
  85. * @const string
  86. */
  87. const METHOD_POST = 'post';
  88. /**
  89. * Method: PUT.
  90. *
  91. * @const string
  92. */
  93. const METHOD_PUT = 'put';
  94. /**
  95. * Method: TRACE.
  96. *
  97. * @const string
  98. */
  99. const METHOD_TRACE = 'trace';
  100. /**
  101. * Other methods.
  102. *
  103. * @const string
  104. */
  105. const METHOD_EXTENDED = 'extended';
  106. /**
  107. * Request method (please, see self::METHOD_* constants).
  108. *
  109. * @var string
  110. */
  111. protected $_method = null;
  112. /**
  113. * Request URL.
  114. *
  115. * @var string
  116. */
  117. protected $_url = null;
  118. /**
  119. * Parse a HTTP packet.
  120. *
  121. * @param string $packet HTTP packet.
  122. * @return void
  123. * @throws \Hoa\Http\Exception
  124. */
  125. public function parse($packet)
  126. {
  127. $headers = explode("\r\n", $packet);
  128. $http = array_shift($headers);
  129. $this->setBody(null);
  130. foreach ($headers as $i => $header) {
  131. if ('' == trim($header)) {
  132. unset($headers[$i]);
  133. $this->setBody(
  134. trim(
  135. implode("\r\n", array_splice($headers, $i))
  136. )
  137. );
  138. break;
  139. }
  140. }
  141. if (0 === preg_match('#^([^\s]+)\s+([^\s]+)\s+HTTP/(1\.(?:0|1))$#i', $http, $matches)) {
  142. throw new Exception(
  143. 'HTTP headers are not well-formed: %s',
  144. 0,
  145. $http
  146. );
  147. }
  148. switch ($method = strtolower($matches[1])) {
  149. case self::METHOD_CONNECT:
  150. case self::METHOD_DELETE:
  151. case self::METHOD_GET:
  152. case self::METHOD_HEAD:
  153. case self::METHOD_OPTIONS:
  154. case self::METHOD_PATCH:
  155. case self::METHOD_POST:
  156. case self::METHOD_PUT:
  157. case self::METHOD_TRACE:
  158. $this->_method = $method;
  159. break;
  160. default:
  161. $this->_method = self::METHOD_EXTENDED;
  162. }
  163. $this->setUrl($matches[2]);
  164. $this->setHttpVersion((float) $matches[3]);
  165. $this->_parse($headers);
  166. return;
  167. }
  168. /**
  169. * Set request method.
  170. *
  171. * @param string $method Method (please, see self::METHOD_*
  172. * constants).
  173. * @return string
  174. */
  175. public function setMethod($method)
  176. {
  177. $old = $this->_method;
  178. $this->_method = $method;
  179. return $old;
  180. }
  181. /**
  182. * Get request method.
  183. *
  184. * @return string
  185. */
  186. public function getMethod()
  187. {
  188. return $this->_method;
  189. }
  190. /**
  191. * Set request URL.
  192. *
  193. * @param string $url URL.
  194. * @return string
  195. */
  196. public function setUrl($url)
  197. {
  198. $old = $this->_url;
  199. $this->_url = $url;
  200. return $old;
  201. }
  202. /**
  203. * Get request URL.
  204. *
  205. * @return string
  206. */
  207. public function getUrl()
  208. {
  209. return $this->_url;
  210. }
  211. /**
  212. * Dump (parse^-1).
  213. *
  214. * @return string
  215. */
  216. public function __toString()
  217. {
  218. return
  219. strtoupper($this->getMethod()) . ' ' .
  220. $this->getUrl() . ' ' .
  221. 'HTTP/' . $this->getHttpVersion() . CRLF .
  222. parent::__toString() . CRLF;
  223. }
  224. }