File Coverage

blib/lib/HTTP/Status.pm
Criterion Covered Total %
statement 22 22 100.0
branch 15 16 93.7
condition 54 54 100.0
subroutine 14 14 100.0
pod 10 10 100.0
total 115 116 99.1


line stmt bran cond sub pod time code
1             package HTTP::Status;
2              
3 13     13   137688 use strict;
  13         45  
  13         444  
4 13     13   66 use warnings;
  13         26  
  13         677  
5              
6             our $VERSION = '6.45';
7              
8 13     13   92 use Exporter 5.57 'import';
  13         254  
  13         5761  
9              
10             our @EXPORT = qw(is_info is_success is_redirect is_error status_message);
11             our @EXPORT_OK = qw(is_client_error is_server_error is_cacheable_by_default status_constant_name status_codes);
12              
13             # Note also addition of mnemonics to @EXPORT below
14              
15             # Unmarked codes are from RFC 7231 (2017-12-20)
16             # See also:
17             # https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
18              
19             my %StatusCode = (
20             100 => 'Continue',
21             101 => 'Switching Protocols',
22             102 => 'Processing', # RFC 2518: WebDAV
23             103 => 'Early Hints', # RFC 8297: Indicating Hints
24             # 104 .. 199
25             200 => 'OK',
26             201 => 'Created',
27             202 => 'Accepted',
28             203 => 'Non-Authoritative Information',
29             204 => 'No Content',
30             205 => 'Reset Content',
31             206 => 'Partial Content', # RFC 7233: Range Requests
32             207 => 'Multi-Status', # RFC 4918: WebDAV
33             208 => 'Already Reported', # RFC 5842: WebDAV bindings
34             # 209 .. 225
35             226 => 'IM Used', # RFC 3229: Delta encoding
36             # 227 .. 299
37             300 => 'Multiple Choices',
38             301 => 'Moved Permanently',
39             302 => 'Found',
40             303 => 'See Other',
41             304 => 'Not Modified', # RFC 7232: Conditional Request
42             305 => 'Use Proxy',
43             307 => 'Temporary Redirect',
44             308 => 'Permanent Redirect', # RFC 7528: Permanent Redirect
45             # 309 .. 399
46             400 => 'Bad Request',
47             401 => 'Unauthorized', # RFC 7235: Authentication
48             402 => 'Payment Required',
49             403 => 'Forbidden',
50             404 => 'Not Found',
51             405 => 'Method Not Allowed',
52             406 => 'Not Acceptable',
53             407 => 'Proxy Authentication Required', # RFC 7235: Authentication
54             408 => 'Request Timeout',
55             409 => 'Conflict',
56             410 => 'Gone',
57             411 => 'Length Required',
58             412 => 'Precondition Failed', # RFC 7232: Conditional Request
59             413 => 'Payload Too Large',
60             414 => 'URI Too Long',
61             415 => 'Unsupported Media Type',
62             416 => 'Range Not Satisfiable', # RFC 7233: Range Requests
63             417 => 'Expectation Failed',
64             # 418 .. 420
65             421 => 'Misdirected Request', # RFC 7540: HTTP/2
66             422 => 'Unprocessable Entity', # RFC 4918: WebDAV
67             423 => 'Locked', # RFC 4918: WebDAV
68             424 => 'Failed Dependency', # RFC 4918: WebDAV
69             425 => 'Too Early', # RFC 8470: Using Early Data in HTTP
70             426 => 'Upgrade Required',
71             # 427
72             428 => 'Precondition Required', # RFC 6585: Additional Codes
73             429 => 'Too Many Requests', # RFC 6585: Additional Codes
74             # 430
75             431 => 'Request Header Fields Too Large', # RFC 6585: Additional Codes
76             # 432 .. 450
77             451 => 'Unavailable For Legal Reasons', # RFC 7725: Legal Obstacles
78             # 452 .. 499
79             500 => 'Internal Server Error',
80             501 => 'Not Implemented',
81             502 => 'Bad Gateway',
82             503 => 'Service Unavailable',
83             504 => 'Gateway Timeout',
84             505 => 'HTTP Version Not Supported',
85             506 => 'Variant Also Negotiates', # RFC 2295: Transparant Ngttn
86             507 => 'Insufficient Storage', # RFC 4918: WebDAV
87             508 => 'Loop Detected', # RFC 5842: WebDAV bindings
88             # 509
89             510 => 'Not Extended', # RFC 2774: Extension Framework
90             511 => 'Network Authentication Required', # RFC 6585: Additional Codes
91             );
92              
93             my %StatusCodeName;
94              
95             # keep some unofficial codes that used to be in this distribution
96             %StatusCode = (
97             %StatusCode,
98             418 => 'I\'m a teapot', # RFC 2324: HTCPC/1.0 1-april
99             449 => 'Retry with', # microsoft
100             509 => 'Bandwidth Limit Exceeded', # Apache / cPanel
101             );
102              
103             my $mnemonicCode = '';
104             my ($code, $message);
105             while (($code, $message) = each %StatusCode) {
106             # create mnemonic subroutines
107             $message =~ s/I'm/I am/;
108             $message =~ tr/a-z \-/A-Z__/;
109             my $constant_name = "HTTP_".$message;
110             $mnemonicCode .= "sub $constant_name () { $code }\n";
111             $mnemonicCode .= "*RC_$message = \\&HTTP_$message;\n"; # legacy
112             $mnemonicCode .= "push(\@EXPORT_OK, 'HTTP_$message');\n";
113             $mnemonicCode .= "push(\@EXPORT, 'RC_$message');\n";
114             $StatusCodeName{$code} = $constant_name
115             }
116             eval $mnemonicCode; # only one eval for speed
117             die if $@;
118              
119             # backwards compatibility
120             *RC_MOVED_TEMPORARILY = \&RC_FOUND; # 302 was renamed in the standard
121             push(@EXPORT, "RC_MOVED_TEMPORARILY");
122              
123             my %compat = (
124             REQUEST_ENTITY_TOO_LARGE => \&HTTP_PAYLOAD_TOO_LARGE,
125             REQUEST_URI_TOO_LARGE => \&HTTP_URI_TOO_LONG,
126             REQUEST_RANGE_NOT_SATISFIABLE => \&HTTP_RANGE_NOT_SATISFIABLE,
127             NO_CODE => \&HTTP_TOO_EARLY,
128             UNORDERED_COLLECTION => \&HTTP_TOO_EARLY,
129             );
130              
131             foreach my $name (keys %compat) {
132             push(@EXPORT, "RC_$name");
133             push(@EXPORT_OK, "HTTP_$name");
134 13     13   146 no strict 'refs';
  13         23  
  13         7927  
135             *{"RC_$name"} = $compat{$name};
136             *{"HTTP_$name"} = $compat{$name};
137             }
138              
139             our %EXPORT_TAGS = (
140             constants => [grep /^HTTP_/, @EXPORT_OK],
141             is => [grep /^is_/, @EXPORT, @EXPORT_OK],
142             );
143              
144              
145 33     33 1 175 sub status_message ($) { $StatusCode{$_[0]}; }
146             sub status_constant_name ($) {
147 3 100   3 1 404 exists($StatusCodeName{$_[0]}) ? $StatusCodeName{$_[0]} : undef;
148             }
149              
150 5 100 100 5 1 3714 sub is_info ($) { $_[0] && $_[0] >= 100 && $_[0] < 200; }
151 10 100 100 10 1 98 sub is_success ($) { $_[0] && $_[0] >= 200 && $_[0] < 300; }
152 6 100 100 6 1 56 sub is_redirect ($) { $_[0] && $_[0] >= 300 && $_[0] < 400; }
153 13 100 100 13 1 128 sub is_error ($) { $_[0] && $_[0] >= 400 && $_[0] < 600; }
154 3 100 100 3 1 26 sub is_client_error ($) { $_[0] && $_[0] >= 400 && $_[0] < 500; }
155 3 100 100 3 1 29 sub is_server_error ($) { $_[0] && $_[0] >= 500 && $_[0] < 600; }
156 18 50 100 18 1 6886 sub is_cacheable_by_default ($) { $_[0] && ( $_[0] == 200 # OK
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
      100        
157             || $_[0] == 203 # Non-Authoritative Information
158             || $_[0] == 204 # No Content
159             || $_[0] == 206 # Not Acceptable
160             || $_[0] == 300 # Multiple Choices
161             || $_[0] == 301 # Moved Permanently
162             || $_[0] == 308 # Permanent Redirect
163             || $_[0] == 404 # Not Found
164             || $_[0] == 405 # Method Not Allowed
165             || $_[0] == 410 # Gone
166             || $_[0] == 414 # Request-URI Too Large
167             || $_[0] == 451 # Unavailable For Legal Reasons
168             || $_[0] == 501 # Not Implemented
169             );
170             }
171              
172 1     1 1 34 sub status_codes { %StatusCode; }
173              
174             1;
175              
176             =pod
177              
178             =encoding UTF-8
179              
180             =head1 NAME
181              
182             HTTP::Status - HTTP Status code processing
183              
184             =head1 VERSION
185              
186             version 6.45
187              
188             =head1 SYNOPSIS
189              
190             use HTTP::Status qw(:constants :is status_message);
191              
192             if ($rc != HTTP_OK) {
193             print status_message($rc), "\n";
194             }
195              
196             if (is_success($rc)) { ... }
197             if (is_error($rc)) { ... }
198             if (is_redirect($rc)) { ... }
199              
200             =head1 DESCRIPTION
201              
202             I is a library of routines for defining and
203             classifying HTTP status codes for libwww-perl. Status codes are
204             used to encode the overall outcome of an HTTP response message. Codes
205             correspond to those defined in RFC 2616 and RFC 2518.
206              
207             =head1 CONSTANTS
208              
209             The following constant functions can be used as mnemonic status code
210             names. None of these are exported by default. Use the C<:constants>
211             tag to import them all.
212              
213             HTTP_CONTINUE (100)
214             HTTP_SWITCHING_PROTOCOLS (101)
215             HTTP_PROCESSING (102)
216             HTTP_EARLY_HINTS (103)
217              
218             HTTP_OK (200)
219             HTTP_CREATED (201)
220             HTTP_ACCEPTED (202)
221             HTTP_NON_AUTHORITATIVE_INFORMATION (203)
222             HTTP_NO_CONTENT (204)
223             HTTP_RESET_CONTENT (205)
224             HTTP_PARTIAL_CONTENT (206)
225             HTTP_MULTI_STATUS (207)
226             HTTP_ALREADY_REPORTED (208)
227              
228             HTTP_IM_USED (226)
229              
230             HTTP_MULTIPLE_CHOICES (300)
231             HTTP_MOVED_PERMANENTLY (301)
232             HTTP_FOUND (302)
233             HTTP_SEE_OTHER (303)
234             HTTP_NOT_MODIFIED (304)
235             HTTP_USE_PROXY (305)
236             HTTP_TEMPORARY_REDIRECT (307)
237             HTTP_PERMANENT_REDIRECT (308)
238              
239             HTTP_BAD_REQUEST (400)
240             HTTP_UNAUTHORIZED (401)
241             HTTP_PAYMENT_REQUIRED (402)
242             HTTP_FORBIDDEN (403)
243             HTTP_NOT_FOUND (404)
244             HTTP_METHOD_NOT_ALLOWED (405)
245             HTTP_NOT_ACCEPTABLE (406)
246             HTTP_PROXY_AUTHENTICATION_REQUIRED (407)
247             HTTP_REQUEST_TIMEOUT (408)
248             HTTP_CONFLICT (409)
249             HTTP_GONE (410)
250             HTTP_LENGTH_REQUIRED (411)
251             HTTP_PRECONDITION_FAILED (412)
252             HTTP_PAYLOAD_TOO_LARGE (413)
253             HTTP_URI_TOO_LONG (414)
254             HTTP_UNSUPPORTED_MEDIA_TYPE (415)
255             HTTP_RANGE_NOT_SATISFIABLE (416)
256             HTTP_EXPECTATION_FAILED (417)
257             HTTP_MISDIRECTED REQUEST (421)
258             HTTP_UNPROCESSABLE_ENTITY (422)
259             HTTP_LOCKED (423)
260             HTTP_FAILED_DEPENDENCY (424)
261             HTTP_TOO_EARLY (425)
262             HTTP_UPGRADE_REQUIRED (426)
263             HTTP_PRECONDITION_REQUIRED (428)
264             HTTP_TOO_MANY_REQUESTS (429)
265             HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE (431)
266             HTTP_UNAVAILABLE_FOR_LEGAL_REASONS (451)
267              
268             HTTP_INTERNAL_SERVER_ERROR (500)
269             HTTP_NOT_IMPLEMENTED (501)
270             HTTP_BAD_GATEWAY (502)
271             HTTP_SERVICE_UNAVAILABLE (503)
272             HTTP_GATEWAY_TIMEOUT (504)
273             HTTP_HTTP_VERSION_NOT_SUPPORTED (505)
274             HTTP_VARIANT_ALSO_NEGOTIATES (506)
275             HTTP_INSUFFICIENT_STORAGE (507)
276             HTTP_LOOP_DETECTED (508)
277             HTTP_NOT_EXTENDED (510)
278             HTTP_NETWORK_AUTHENTICATION_REQUIRED (511)
279              
280             =head1 FUNCTIONS
281              
282             The following additional functions are provided. Most of them are
283             exported by default. The C<:is> import tag can be used to import all
284             the classification functions.
285              
286             =over 4
287              
288             =item status_message( $code )
289              
290             The status_message() function will translate status codes to human
291             readable strings. The string is the same as found in the constant
292             names above.
293             For example, C will return C<"Not Found">.
294              
295             If the $code is not registered in the L
296             Codes|https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml>
297             then C is returned.
298              
299             =item status_constant_name( $code )
300              
301             The status_constant_name() function will translate a status code
302             to a string which has the name of the constant for that status code.
303             For example, C will return C<"HTTP_NOT_FOUND">.
304              
305             If the C<$code> is not registered in the L
306             Codes|https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml>
307             then C is returned.
308              
309             =item is_info( $code )
310              
311             Return TRUE if C<$code> is an I status code (1xx). This
312             class of status code indicates a provisional response which can't have
313             any content.
314              
315             =item is_success( $code )
316              
317             Return TRUE if C<$code> is a I status code (2xx).
318              
319             =item is_redirect( $code )
320              
321             Return TRUE if C<$code> is a I status code (3xx). This class of
322             status code indicates that further action needs to be taken by the
323             user agent in order to fulfill the request.
324              
325             =item is_error( $code )
326              
327             Return TRUE if C<$code> is an I status code (4xx or 5xx). The function
328             returns TRUE for both client and server error status codes.
329              
330             =item is_client_error( $code )
331              
332             Return TRUE if C<$code> is a I status code (4xx). This class
333             of status code is intended for cases in which the client seems to have
334             erred.
335              
336             This function is B exported by default.
337              
338             =item is_server_error( $code )
339              
340             Return TRUE if C<$code> is a I status code (5xx). This class
341             of status codes is intended for cases in which the server is aware
342             that it has erred or is incapable of performing the request.
343              
344             This function is B exported by default.
345              
346             =item is_cacheable_by_default( $code )
347              
348             Return TRUE if C<$code> indicates that a response is cacheable by default, and
349             it can be reused by a cache with heuristic expiration. All other status codes
350             are not cacheable by default. See L
351             Section 6.1. Overview of Status Codes|https://tools.ietf.org/html/rfc7231#section-6.1>.
352              
353             This function is B exported by default.
354              
355             =item status_codes
356              
357             Returns a hash mapping numerical HTTP status code (e.g. 200) to text status messages (e.g. "OK")
358              
359             This function is B exported by default.
360              
361             =back
362              
363             =head1 SEE ALSO
364              
365             L
366              
367             =head1 BUGS
368              
369             For legacy reasons all the C constants are exported by default
370             with the prefix C. It's recommended to use explicit imports and
371             the C<:constants> tag instead of relying on this.
372              
373             =head1 AUTHOR
374              
375             Gisle Aas
376              
377             =head1 COPYRIGHT AND LICENSE
378              
379             This software is copyright (c) 1994 by Gisle Aas.
380              
381             This is free software; you can redistribute it and/or modify it under
382             the same terms as the Perl 5 programming language system itself.
383              
384             =cut
385              
386             __END__