1313use Psr \Http \Message \ServerRequestFactoryInterface ;
1414use Psr \Http \Message \StreamFactoryInterface ;
1515use Redmine \Exception \ClientException ;
16+ use Redmine \Http \HttpClient ;
17+ use Redmine \Http \Request ;
18+ use Redmine \Http \Response ;
1619
1720/**
1821 * Psr18 client.
1922 */
20- final class Psr18Client implements Client
23+ final class Psr18Client implements Client, HttpClient
2124{
2225 use ClientApiTrait;
2326
@@ -73,6 +76,53 @@ public function __construct(
7376 $ this ->password = $ password ;
7477 }
7578
79+ /**
80+ * Create and send a HTTP request and return the response
81+ *
82+ * @throws ClientException If anything goes wrong on creating or sending the request
83+ */
84+ public function request (Request $ request ): Response
85+ {
86+ $ response = $ this ->runRequest (
87+ $ request ->getMethod (),
88+ $ request ->getPath (),
89+ $ request ->getContent (),
90+ $ request ->getContentType ()
91+ );
92+
93+ return new class (
94+ $ response ->getStatusCode (),
95+ $ response ->getHeaderLine ('Content-Type ' ),
96+ strval ($ response ->getBody ())
97+ ) implements Response {
98+ private $ statusCode ;
99+ private $ contentType ;
100+ private $ body ;
101+
102+ public function __construct (int $ statusCode , string $ contentType , string $ body )
103+ {
104+ $ this ->statusCode = $ statusCode ;
105+ $ this ->contentType = $ contentType ;
106+ $ this ->body = $ body ;
107+ }
108+
109+ public function getStatusCode (): int
110+ {
111+ return $ this ->statusCode ;
112+ }
113+
114+ public function getContentType (): string
115+ {
116+ return $ this ->contentType ;
117+ }
118+
119+ public function getContent (): string
120+ {
121+ return $ this ->body ;
122+ }
123+ };
124+ }
125+
76126 /**
77127 * Sets to an existing username so api calls can be
78128 * impersonated to this user.
@@ -92,34 +142,58 @@ public function stopImpersonateUser(): void
92142
93143 /**
94144 * Create and send a GET request.
145+ *
146+ * @throws ClientException If anything goes wrong on the request
147+ *
148+ * @return bool true if status code of the response is not 4xx oder 5xx
95149 */
96150 public function requestGet (string $ path ): bool
97151 {
98- return $ this ->runRequest ('GET ' , $ path );
152+ $ response = $ this ->runRequest ('GET ' , $ path );
153+
154+ return $ response ->getStatusCode () < 400 ;
99155 }
100156
101157 /**
102158 * Create and send a POST request.
159+ *
160+ * @throws ClientException If anything goes wrong on the request
161+ *
162+ * @return bool true if status code of the response is not 4xx oder 5xx
103163 */
104164 public function requestPost (string $ path , string $ body ): bool
105165 {
106- return $ this ->runRequest ('POST ' , $ path , $ body );
166+ $ response = $ this ->runRequest ('POST ' , $ path , $ body );
167+
168+ return $ response ->getStatusCode () < 400 ;
107169 }
108170
109171 /**
110172 * Create and send a PUT request.
173+ *
174+ * @throws ClientException If anything goes wrong on the request
175+ *
176+ * @return bool true if status code of the response is not 4xx oder 5xx
111177 */
112178 public function requestPut (string $ path , string $ body ): bool
113179 {
114- return $ this ->runRequest ('PUT ' , $ path , $ body );
180+ $ response = $ this ->runRequest ('PUT ' , $ path , $ body );
181+
182+ return $ response ->getStatusCode () < 400 ;
115183 }
116184
117185 /**
118186 * Create and send a DELETE request.
187+ *
188+ * @throws ClientException If anything goes wrong on the request
189+ *
190+ * @return bool true if status code of the response is not 4xx oder 5xx
119191 */
120192 public function requestDelete (string $ path ): bool
121193 {
122- return $ this ->runRequest ('DELETE ' , $ path );
194+ $ response = $ this ->runRequest ('DELETE ' , $ path );
195+
196+ return $ response ->getStatusCode () < 400 ;
123197 }
124198
125199 /**
@@ -162,25 +236,23 @@ public function getLastResponseBody(): string
162236 * Create and run a request.
163237 *
164238 * @throws ClientException If anything goes wrong on the request
165- *
166- * @return bool true if status code of the response is not 4xx oder 5xx
167239 */
168- private function runRequest (string $ method , string $ path , string $ body = '' ): bool
240+ private function runRequest (string $ method , string $ path , string $ body = '' , string $ contentType = '' ): ResponseInterface
169241 {
170242 $ this ->lastResponse = null ;
171243
172- $ request = $ this ->createRequest ($ method , $ path , $ body );
244+ $ request = $ this ->createRequest ($ method , $ path , $ body, $ contentType );
173245
174246 try {
175247 $ this ->lastResponse = $ this ->httpClient ->sendRequest ($ request );
176248 } catch (ClientExceptionInterface $ e ) {
177249 throw new ClientException ($ e ->getMessage (), $ e ->getCode (), $ e );
178250 }
179251
180- return $ this ->lastResponse -> getStatusCode () < 400 ;
252+ return $ this ->lastResponse ;
181253 }
182254
183- private function createRequest (string $ method , string $ path , string $ body = '' ): RequestInterface
255+ private function createRequest (string $ method , string $ path , string $ body = '' , string $ contentType = '' ): RequestInterface
184256 {
185257 $ request = $ this ->requestFactory ->createRequest (
186258 $ method ,
@@ -228,14 +300,19 @@ private function createRequest(string $method, string $path, string $body = ''):
228300 }
229301
230302 // set Content-Type header
231- $ tmp = parse_url ($ this ->url . $ path );
232-
233- if ($ this ->isUploadCall ($ path )) {
234- $ request = $ request ->withHeader ('Content-Type ' , 'application/octet-stream ' );
235- } elseif ('json ' === substr ($ tmp ['path ' ], -4 )) {
236- $ request = $ request ->withHeader ('Content-Type ' , 'application/json ' );
237- } elseif ('xml ' === substr ($ tmp ['path ' ], -3 )) {
238- $ request = $ request ->withHeader ('Content-Type ' , 'text/xml ' );
303+ if ($ contentType !== '' ) {
304+ $ request = $ request ->withHeader ('Content-Type ' , $ contentType );
305+ } else {
306+ // guess Content-Type from path
307+ $ tmp = parse_url ($ this ->url . $ path );
308+
309+ if ($ this ->isUploadCall ($ path )) {
310+ $ request = $ request ->withHeader ('Content-Type ' , 'application/octet-stream ' );
311+ } elseif ('json ' === substr ($ tmp ['path ' ], -4 )) {
312+ $ request = $ request ->withHeader ('Content-Type ' , 'application/json ' );
313+ } elseif ('xml ' === substr ($ tmp ['path ' ], -3 )) {
314+ $ request = $ request ->withHeader ('Content-Type ' , 'text/xml ' );
315+ }
239316 }
240317
241318 return $ request ;
0 commit comments