Skip to content

Commit 8cdc462

Browse files
committed
Implement HttpClient in Psr18Client
1 parent b384752 commit 8cdc462

File tree

1 file changed

+96
-19
lines changed

1 file changed

+96
-19
lines changed

src/Redmine/Client/Psr18Client.php

Lines changed: 96 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,14 @@
1313
use Psr\Http\Message\ServerRequestFactoryInterface;
1414
use Psr\Http\Message\StreamFactoryInterface;
1515
use 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

Comments
 (0)