xref: /plugin/combo/ComboStrap/Http.php (revision 04fd306c7c155fa133ebb3669986875d65988276)
137748cd8SNickeau<?php
237748cd8SNickeau
337748cd8SNickeau
437748cd8SNickeaunamespace ComboStrap;
537748cd8SNickeau
637748cd8SNickeau
737748cd8SNickeauclass Http
837748cd8SNickeau{
937748cd8SNickeau
101fa8c418SNickeau    public static function removeHeaderIfPresent(string $key)
111fa8c418SNickeau    {
121fa8c418SNickeau        foreach (headers_list() as $header) {
131fa8c418SNickeau            if (preg_match("/$key/i", $header)) {
141fa8c418SNickeau                header_remove($key);
151fa8c418SNickeau            }
161fa8c418SNickeau        }
171fa8c418SNickeau
181fa8c418SNickeau    }
191fa8c418SNickeau
20*04fd306cSNickeau    /**
21*04fd306cSNickeau     * @throws ExceptionNotFound
22*04fd306cSNickeau     */
23*04fd306cSNickeau    public static function getFirstHeader(string $name, array $headers = null): string
241fa8c418SNickeau    {
251fa8c418SNickeau
26*04fd306cSNickeau        $result = self::getHeadersForName($name, $headers);
27*04fd306cSNickeau
28*04fd306cSNickeau        if (count($result) == 0) {
29*04fd306cSNickeau            throw new ExceptionNotFound("No header was found with the header name $name");
301fa8c418SNickeau        }
311fa8c418SNickeau
32*04fd306cSNickeau        return $result[0];
33*04fd306cSNickeau
341fa8c418SNickeau
351fa8c418SNickeau    }
361fa8c418SNickeau
371fa8c418SNickeau    private static function getHeaders(): array
381fa8c418SNickeau    {
391fa8c418SNickeau        return (function_exists('xdebug_get_headers') ? xdebug_get_headers() : headers_list());
401fa8c418SNickeau    }
41c3437056SNickeau
42c3437056SNickeau    /**
43c3437056SNickeau     * Set the HTTP status
44c3437056SNickeau     * Dokuwiki test does not {@link \TestResponse::getStatusCode()} capture the status with all php function such
45c3437056SNickeau     * as {@link http_response_code},
46c3437056SNickeau     *
47c3437056SNickeau     * @param int $int
48c3437056SNickeau     */
49c3437056SNickeau    public static function setStatus(int $int)
50c3437056SNickeau    {
51c3437056SNickeau        /**
52c3437056SNickeau         * {@link http_status} function
53c3437056SNickeau         * that creates
54c3437056SNickeau         * header('HTTP/1.1 301 Moved Permanently');
55c3437056SNickeau         * header('HTTP/1.0 304 Not Modified');
56c3437056SNickeau         * header('HTTP/1.1 404 Not Found');
57c3437056SNickeau         *
58c3437056SNickeau         * not {@link http_response_code}
59c3437056SNickeau         */
60c3437056SNickeau        http_status($int);
61c3437056SNickeau
62c3437056SNickeau    }
63c3437056SNickeau
64c3437056SNickeau    public static function getStatus()
65c3437056SNickeau    {
66c3437056SNickeau        /**
67*04fd306cSNickeau         * See also {@link Http::getFirstHeader()}
68c3437056SNickeau         * if this does not work
69c3437056SNickeau         */
70c3437056SNickeau        return http_response_code();
71c3437056SNickeau    }
72c3437056SNickeau
73c3437056SNickeau    public static function setMime(string $mime)
74c3437056SNickeau    {
75*04fd306cSNickeau        $contentTypeHeader = HttpResponse::HEADER_CONTENT_TYPE;
76c3437056SNickeau        header("$contentTypeHeader: $mime");
77c3437056SNickeau    }
78c3437056SNickeau
79*04fd306cSNickeau
80*04fd306cSNickeau    public static function getHeadersForName(string $name, ?array $headers): array
81c3437056SNickeau    {
82*04fd306cSNickeau        if ($headers === null) {
83*04fd306cSNickeau            $headers = self::getHeaders();
84*04fd306cSNickeau        }
85*04fd306cSNickeau
86*04fd306cSNickeau        $result = array();
87*04fd306cSNickeau        $headerNameNormalized = trim(strtolower($name));
88*04fd306cSNickeau        foreach ($headers as $header) {
89*04fd306cSNickeau            $loc = strpos($header, ":");
90*04fd306cSNickeau            if ($loc === false) {
91*04fd306cSNickeau                continue;
92*04fd306cSNickeau            }
93*04fd306cSNickeau            $actualHeaderName = substr($header, 0, $loc);
94*04fd306cSNickeau            $actualHeaderNameNormalized = trim(strtolower($actualHeaderName));
95*04fd306cSNickeau            if ($actualHeaderNameNormalized === $headerNameNormalized) {
96*04fd306cSNickeau                $result[] = $header;
97*04fd306cSNickeau            }
98*04fd306cSNickeau        }
99*04fd306cSNickeau        return $result;
100*04fd306cSNickeau    }
101*04fd306cSNickeau
102*04fd306cSNickeau    /**
103*04fd306cSNickeau     * @throws ExceptionNotExists
104*04fd306cSNickeau     */
105*04fd306cSNickeau    public static function extractHeaderValue(string $header): string
106*04fd306cSNickeau    {
107*04fd306cSNickeau        $positionDoublePointSeparator = strpos($header, ':');
108*04fd306cSNickeau        if ($positionDoublePointSeparator === false) {
109*04fd306cSNickeau            throw new ExceptionNotExists("No value found");
110*04fd306cSNickeau        }
111*04fd306cSNickeau        return trim(substr($header, $positionDoublePointSeparator + 1));
112c3437056SNickeau    }
113c3437056SNickeau
114c3437056SNickeau    /**
115c3437056SNickeau     * PHP is blocking and fsockopen also.
116c3437056SNickeau     * Don't use it in a page rendering flow
117c3437056SNickeau     * https://segment.com/blog/how-to-make-async-requests-in-php/
118c3437056SNickeau     * @param $url
119c3437056SNickeau     */
120c3437056SNickeau    function sendAsyncRequest($url)
121c3437056SNickeau    {
122c3437056SNickeau        $parts = parse_url($url);
123c3437056SNickeau        $fp = fsockopen($parts['host'], isset($parts['port']) ? $parts['port'] : 80, $errno, $errstr, 30);
124c3437056SNickeau        $out = "GET " . $parts['path'] . "?" . $parts['query'] . " HTTP/1.1\r\n";
125c3437056SNickeau        $out .= "Host: " . $parts['host'] . "\r\n";
126c3437056SNickeau        $out .= "Content-Length: 0" . "\r\n";
127c3437056SNickeau        $out .= "Connection: Close\r\n\r\n";
128c3437056SNickeau
129c3437056SNickeau        fwrite($fp, $out);
130c3437056SNickeau        fclose($fp);
131c3437056SNickeau    }
132c3437056SNickeau
133c3437056SNickeau
13437748cd8SNickeau}
135