• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

voku / httpful / 5623107679

pending completion
5623107679

push

github

voku
[+]: fix test for the new release

1596 of 2486 relevant lines covered (64.2%)

81.28 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

73.95
/src/Httpful/Http.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Httpful;
6

7
use Httpful\Exception\ResponseException;
8
use Psr\Http\Message\StreamInterface;
9

10
class Http
11
{
12
    const DELETE = 'DELETE';
13

14
    const GET = 'GET';
15

16
    const HEAD = 'HEAD';
17

18
    const OPTIONS = 'OPTIONS';
19

20
    const PATCH = 'PATCH';
21

22
    const POST = 'POST';
23

24
    const PUT = 'PUT';
25

26
    const TRACE = 'TRACE';
27

28
    const HTTP_1_0 = '1.0';
29

30
    const HTTP_1_1 = '1.1';
31

32
    const HTTP_2_0 = '2';
33

34
    /**
35
     * @return array
36
     */
37
    public static function allMethods(): array
38
    {
39
        return [
460✔
40
            self::HEAD,
460✔
41
            self::POST,
460✔
42
            self::GET,
460✔
43
            self::PUT,
460✔
44
            self::DELETE,
460✔
45
            self::OPTIONS,
460✔
46
            self::TRACE,
460✔
47
            self::PATCH,
460✔
48
        ];
460✔
49
    }
50

51
    /**
52
     * @return array list of (always) idempotent HTTP methods
53
     */
54
    public static function idempotentMethods(): array
55
    {
56
        return [
×
57
            self::HEAD,
×
58
            self::GET,
×
59
            self::PUT,
×
60
            self::DELETE,
×
61
            self::OPTIONS,
×
62
            self::TRACE,
×
63
            self::PATCH,
×
64
        ];
×
65
    }
66

67
    /**
68
     * @param string $method HTTP method
69
     *
70
     * @return bool
71
     */
72
    public static function isIdempotent($method): bool
73
    {
74
        return \in_array($method, self::idempotentMethods(), true);
×
75
    }
76

77
    /**
78
     * @param string $method HTTP method
79
     *
80
     * @return bool
81
     */
82
    public static function isNotIdempotent($method): bool
83
    {
84
        return !\in_array($method, self::idempotentMethods(), true);
×
85
    }
86

87
    /**
88
     * @param string $method HTTP method
89
     *
90
     * @return bool
91
     */
92
    public static function isSafeMethod($method): bool
93
    {
94
        return \in_array($method, self::safeMethods(), true);
×
95
    }
96

97
    /**
98
     * @param string $method HTTP method
99
     *
100
     * @return bool
101
     */
102
    public static function isUnsafeMethod($method): bool
103
    {
104
        return !\in_array($method, self::safeMethods(), true);
×
105
    }
106

107
    /**
108
     * @param int $code
109
     *
110
     * @throws \Exception
111
     *
112
     * @return string
113
     */
114
    public static function reason(int $code): string
115
    {
116
        $codes = self::responseCodes();
296✔
117

118
        if (!\array_key_exists($code, $codes)) {
296✔
119
            throw new ResponseException('Unable to parse response code from HTTP response due to malformed response. Code: ' . $code);
×
120
        }
121

122
        return $codes[$code];
296✔
123
    }
124

125
    /**
126
     * @param int $code
127
     *
128
     * @return bool
129
     */
130
    public static function responseCodeExists(int $code): bool
131
    {
132
        return \array_key_exists($code, self::responseCodes());
28✔
133
    }
134

135
    /**
136
     * @return array of HTTP method strings
137
     */
138
    public static function safeMethods(): array
139
    {
140
        return [
×
141
            self::HEAD,
×
142
            self::GET,
×
143
            self::OPTIONS,
×
144
            self::TRACE,
×
145
        ];
×
146
    }
147

148
    /**
149
     * Create a new stream based on the input type.
150
     *
151
     * Options is an associative array that can contain the following keys:
152
     * - metadata: Array of custom metadata.
153
     * - size: Size of the stream.
154
     *
155
     * @param mixed $resource
156
     * @param array $options
157
     *
158
     * @throws \InvalidArgumentException if the $resource arg is not valid
159
     *
160
     * @return StreamInterface
161
     */
162
    public static function stream($resource = '', array $options = []): StreamInterface
163
    {
164
        // init
165
        $options['serialized'] = false;
52✔
166

167
        if (\is_array($resource)) {
52✔
168
            $resource = \serialize($resource);
20✔
169

170
            $options['serialized'] = true;
20✔
171
        }
172

173
        if (\is_scalar($resource)) {
52✔
174
            $stream = \fopen('php://temp', 'r+b');
52✔
175

176
            if (!\is_resource($stream)) {
52✔
177
                throw new \RuntimeException('fopen must create a resource');
×
178
            }
179

180
            if ($resource !== '') {
52✔
181
                \fwrite($stream, (string) $resource);
28✔
182
                \fseek($stream, 0);
28✔
183
            }
184

185
            return new Stream($stream, $options);
52✔
186
        }
187

188
        switch (\gettype($resource)) {
8✔
189
            case 'resource':
8✔
190
                return new Stream($resource, $options);
×
191
            case 'object':
8✔
192
                if ($resource instanceof StreamInterface) {
8✔
193
                    return $resource;
8✔
194
                }
195

196
                if (\method_exists($resource, '__toString')) {
×
197
                    return self::stream((string) $resource, $options);
×
198
                }
199

200
                break;
×
201
            case 'NULL':
×
202
                $stream = \fopen('php://temp', 'r+b');
×
203

204
                if (!\is_resource($stream)) {
×
205
                    throw new \RuntimeException('fopen must create a resource');
×
206
                }
207

208
                return new Stream($stream, $options);
×
209
        }
210

211
        throw new \InvalidArgumentException('Invalid resource type: ' . \gettype($resource));
×
212
    }
213

214
    /**
215
     * get all response-codes
216
     *
217
     * @return array
218
     */
219
    private static function responseCodes(): array
220
    {
221
        return [
296✔
222
            100 => 'Continue',
296✔
223
            101 => 'Switching Protocols',
296✔
224
            102 => 'Processing',
296✔
225
            200 => 'OK',
296✔
226
            201 => 'Created',
296✔
227
            202 => 'Accepted',
296✔
228
            203 => 'Non-Authoritative Information',
296✔
229
            204 => 'No Content',
296✔
230
            205 => 'Reset Content',
296✔
231
            206 => 'Partial Content',
296✔
232
            207 => 'Multi-Status',
296✔
233
            300 => 'Multiple Choices',
296✔
234
            301 => 'Moved Permanently',
296✔
235
            302 => 'Found',
296✔
236
            303 => 'See Other',
296✔
237
            304 => 'Not Modified',
296✔
238
            305 => 'Use Proxy',
296✔
239
            306 => 'Switch Proxy',
296✔
240
            307 => 'Temporary Redirect',
296✔
241
            400 => 'Bad Request',
296✔
242
            401 => 'Unauthorized',
296✔
243
            402 => 'Payment Required',
296✔
244
            403 => 'Forbidden',
296✔
245
            404 => 'Not Found',
296✔
246
            405 => 'Method Not Allowed',
296✔
247
            406 => 'Not Acceptable',
296✔
248
            407 => 'Proxy Authentication Required',
296✔
249
            408 => 'Request Timeout',
296✔
250
            409 => 'Conflict',
296✔
251
            410 => 'Gone',
296✔
252
            411 => 'Length Required',
296✔
253
            412 => 'Precondition Failed',
296✔
254
            413 => 'Request Entity Too Large',
296✔
255
            414 => 'Request-URI Too Long',
296✔
256
            415 => 'Unsupported Media Type',
296✔
257
            416 => 'Requested Range Not Satisfiable',
296✔
258
            417 => 'Expectation Failed',
296✔
259
            418 => 'I\'m a teapot',
296✔
260
            422 => 'Unprocessable Entity',
296✔
261
            423 => 'Locked',
296✔
262
            424 => 'Failed Dependency',
296✔
263
            425 => 'Unordered Collection',
296✔
264
            426 => 'Upgrade Required',
296✔
265
            429 => 'Too Many Requests',
296✔
266
            449 => 'Retry With',
296✔
267
            450 => 'Blocked by Windows Parental Controls',
296✔
268
            500 => 'Internal Server Error',
296✔
269
            501 => 'Not Implemented',
296✔
270
            502 => 'Bad Gateway',
296✔
271
            503 => 'Service Unavailable',
296✔
272
            504 => 'Gateway Timeout',
296✔
273
            505 => 'HTTP Version Not Supported',
296✔
274
            506 => 'Variant Also Negotiates',
296✔
275
            507 => 'Insufficient Storage',
296✔
276
            509 => 'Bandwidth Limit Exceeded',
296✔
277
            510 => 'Not Extended',
296✔
278
        ];
296✔
279
    }
280
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc