xref: /plugin/dw2pdf/src/HttpClient.php (revision 3c796bb4e5739d22b5fbba150b0054929c16ab9f)
1<?php
2
3namespace dokuwiki\plugin\dw2pdf\src;
4
5use dokuwiki\HTTP\DokuHTTPClient;
6use Mpdf\Http\ClientInterface;
7use Mpdf\PsrHttpMessageShim\Response;
8use Mpdf\PsrHttpMessageShim\Stream;
9use Mpdf\PsrLogAwareTrait\PsrLogAwareTrait;
10use Psr\Http\Message\RequestInterface;
11use Psr\Log\LoggerAwareInterface;
12
13/**
14 * mPDF HTTP client adapter that routes requests through Dokuwiki's HTTP stack.
15 *
16 * Basically wraps a simple, naive PSR-7 implementation around DokuHTTPClient.
17 */
18class HttpClient implements ClientInterface, LoggerAwareInterface
19{
20    use PsrLogAwareTrait;
21
22    /**
23     * Send the HTTP request using Dokuwiki's HTTP client, falling back to media resolution when possible.
24     *
25     * @inheritDoc
26     */
27    public function sendRequest(RequestInterface $request)
28    {
29        $uri = $request->getUri();
30
31        $url = (string)$uri;
32
33        // standard Dokuwiki HTTP client for any remote content
34        $client = new DokuHTTPClient();
35        $client->headers = $this->buildHeaders($request);
36        $client->referer = $request->getHeaderLine('Referer');
37        if ($agent = $request->getHeaderLine('User-Agent')) {
38            $client->agent = $agent;
39        }
40
41        $body = (string)$request->getBody();
42        if ($request->getBody()->isSeekable()) {
43            $request->getBody()->rewind();
44        }
45
46        $method = strtoupper($request->getMethod());
47        $client->sendRequest($url, $body, $method);
48
49        $response = (new Response())->withStatus($client->status ?: 500);
50
51        foreach ((array)$client->resp_headers as $name => $value) {
52            if (is_array($value)) {
53                foreach ($value as $single) {
54                    $response = $response->withHeader($name, $single);
55                }
56            } else {
57                $response = $response->withHeader($name, $value);
58            }
59        }
60
61        return $response->withBody(Stream::create($client->resp_body));
62    }
63
64    /**
65     * Convert PSR-7 headers to the associative format expected by DokuHTTPClient.
66     *
67     * @param RequestInterface $request Original request from mPDF.
68     * @return array<string,string>
69     */
70    private function buildHeaders(RequestInterface $request): array
71    {
72        $headers = [];
73        foreach ($request->getHeaders() as $name => $values) {
74            $headers[$name] = implode(', ', $values);
75        }
76
77        return $headers;
78    }
79}
80