Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
53.85% |
21 / 39 |
|
47.06% |
8 / 17 |
CRAP | |
0.00% |
0 / 1 |
| RequestBase | |
53.85% |
21 / 39 |
|
47.06% |
8 / 17 |
92.46 | |
0.00% |
0 / 1 |
| __construct | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| initHeaders | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| __clone | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
| setHeaders | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
| getHeaders | |
66.67% |
2 / 3 |
|
0.00% |
0 / 1 |
2.15 | |||
| getHeader | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
| hasHeader | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
| getHeaderLine | |
66.67% |
2 / 3 |
|
0.00% |
0 / 1 |
2.15 | |||
| setPathParams | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| getPathParams | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| getPathParam | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| getCookiePrefix | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| getCookie | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
2 | |||
| getParsedBody | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| setParsedBody | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| getBodyType | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
6 | |||
| hasBody | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
| 1 | <?php |
| 2 | |
| 3 | namespace MediaWiki\Rest; |
| 4 | |
| 5 | /** |
| 6 | * Shared code between RequestData and RequestFromGlobals |
| 7 | */ |
| 8 | abstract class RequestBase implements RequestInterface { |
| 9 | /** |
| 10 | * @var HeaderContainer|null |
| 11 | */ |
| 12 | private $headerCollection; |
| 13 | |
| 14 | /** @var array */ |
| 15 | private $pathParams = []; |
| 16 | |
| 17 | /** @var string */ |
| 18 | private $cookiePrefix; |
| 19 | |
| 20 | protected ?array $parsedBody = null; |
| 21 | |
| 22 | /** |
| 23 | * @internal |
| 24 | * @param string $cookiePrefix |
| 25 | */ |
| 26 | public function __construct( $cookiePrefix ) { |
| 27 | $this->cookiePrefix = $cookiePrefix; |
| 28 | } |
| 29 | |
| 30 | /** |
| 31 | * Override this in the implementation class if lazy initialisation of |
| 32 | * header values is desired. It should call setHeaders(). |
| 33 | * |
| 34 | * @internal |
| 35 | */ |
| 36 | protected function initHeaders() { |
| 37 | } |
| 38 | |
| 39 | public function __clone() { |
| 40 | if ( $this->headerCollection !== null ) { |
| 41 | $this->headerCollection = clone $this->headerCollection; |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | /** |
| 46 | * Erase any existing headers and replace them with the specified header |
| 47 | * lines. |
| 48 | * |
| 49 | * Call this either from the constructor or from initHeaders() of the |
| 50 | * implementing class. |
| 51 | * |
| 52 | * @internal |
| 53 | * @param string[] $headers The header lines |
| 54 | */ |
| 55 | public function setHeaders( $headers ) { |
| 56 | $this->headerCollection = new HeaderContainer; |
| 57 | $this->headerCollection->resetHeaders( $headers ); |
| 58 | } |
| 59 | |
| 60 | /** @inheritDoc */ |
| 61 | public function getHeaders() { |
| 62 | if ( $this->headerCollection === null ) { |
| 63 | $this->initHeaders(); |
| 64 | } |
| 65 | return $this->headerCollection->getHeaders(); |
| 66 | } |
| 67 | |
| 68 | /** @inheritDoc */ |
| 69 | public function getHeader( $name ) { |
| 70 | if ( $this->headerCollection === null ) { |
| 71 | $this->initHeaders(); |
| 72 | } |
| 73 | return $this->headerCollection->getHeader( $name ); |
| 74 | } |
| 75 | |
| 76 | /** @inheritDoc */ |
| 77 | public function hasHeader( $name ) { |
| 78 | if ( $this->headerCollection === null ) { |
| 79 | $this->initHeaders(); |
| 80 | } |
| 81 | return $this->headerCollection->hasHeader( $name ); |
| 82 | } |
| 83 | |
| 84 | /** @inheritDoc */ |
| 85 | public function getHeaderLine( $name ) { |
| 86 | if ( $this->headerCollection === null ) { |
| 87 | $this->initHeaders(); |
| 88 | } |
| 89 | return $this->headerCollection->getHeaderLine( $name ); |
| 90 | } |
| 91 | |
| 92 | /** @inheritDoc */ |
| 93 | public function setPathParams( $params ) { |
| 94 | $this->pathParams = $params; |
| 95 | } |
| 96 | |
| 97 | /** @inheritDoc */ |
| 98 | public function getPathParams() { |
| 99 | return $this->pathParams; |
| 100 | } |
| 101 | |
| 102 | /** @inheritDoc */ |
| 103 | public function getPathParam( $name ) { |
| 104 | return $this->pathParams[$name] ?? null; |
| 105 | } |
| 106 | |
| 107 | /** @inheritDoc */ |
| 108 | public function getCookiePrefix() { |
| 109 | return $this->cookiePrefix; |
| 110 | } |
| 111 | |
| 112 | /** @inheritDoc */ |
| 113 | public function getCookie( $name, $default = null ) { |
| 114 | $cookies = $this->getCookieParams(); |
| 115 | $prefixedName = $this->getCookiePrefix() . $name; |
| 116 | if ( array_key_exists( $prefixedName, $cookies ) ) { |
| 117 | return $cookies[$prefixedName]; |
| 118 | } else { |
| 119 | return $default; |
| 120 | } |
| 121 | } |
| 122 | |
| 123 | public function getParsedBody(): ?array { |
| 124 | return $this->parsedBody; |
| 125 | } |
| 126 | |
| 127 | public function setParsedBody( ?array $data ) { |
| 128 | $this->parsedBody = $data; |
| 129 | } |
| 130 | |
| 131 | public function getBodyType(): ?string { |
| 132 | [ $ct ] = explode( ';', $this->getHeaderLine( 'Content-Type' ), 2 ); |
| 133 | $ct = strtolower( trim( $ct ) ); |
| 134 | |
| 135 | if ( $ct === '' ) { |
| 136 | return null; |
| 137 | } |
| 138 | return $ct; |
| 139 | } |
| 140 | |
| 141 | /** |
| 142 | * Return true if the client provided a content-length header or a |
| 143 | * transfer-encoding header. |
| 144 | * |
| 145 | * @see https://www.rfc-editor.org/rfc/rfc9110.html#name-content-length |
| 146 | * |
| 147 | * @return bool |
| 148 | */ |
| 149 | public function hasBody(): bool { |
| 150 | // From RFC9110, section 8.6: A user agent SHOULD send Content-Length |
| 151 | // in a request when the method defines a meaning for enclosed content |
| 152 | // and it is not sending Transfer-Encoding. [...] |
| 153 | // A user agent SHOULD NOT send a Content-Length header field when the |
| 154 | // request message does not contain content and the method semantics do |
| 155 | // not anticipate such data. |
| 156 | |
| 157 | if ( $this->getHeaderLine( 'content-length' ) !== '' ) { |
| 158 | // If a content length is set, there is a body |
| 159 | return true; |
| 160 | } |
| 161 | |
| 162 | if ( $this->getHeaderLine( 'transfer-encoding' ) !== '' ) { |
| 163 | // If a transfer encoding is set, there is a body |
| 164 | return true; |
| 165 | } |
| 166 | |
| 167 | return false; |
| 168 | } |
| 169 | |
| 170 | } |