File Coverage

blib/lib/HTTP/Status.pm
Criterion Covered Total %
statement 21 21 100.0
branch 15 16 93.7
condition 54 54 100.0
subroutine 13 13 100.0
pod 9 9 100.0
total 112 113 99.1


line stmt bran cond sub pod time code
1             package HTTP::Status;
2              
3 13     13   140827 use strict;
  13         46  
  13         431  
4 13     13   75 use warnings;
  13         23  
  13         669  
5              
6             our $VERSION = '6.44';
7              
8 13     13   84 use Exporter 5.57 'import';
  13         289  
  13         5862  
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);
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   199 no strict 'refs';
  13         29  
  13         7867  
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 32     32 1 185 sub status_message ($) { $StatusCode{$_[0]}; }
146             sub status_constant_name ($) {
147 3 100   3 1 419 exists($StatusCodeName{$_[0]}) ? $StatusCodeName{$_[0]} : undef;
148             }
149              
150 5 100 100 5 1 4629 sub is_info ($) { $_[0] && $_[0] >= 100 && $_[0] < 200; }
151 10 100 100 10 1 99 sub is_success ($) { $_[0] && $_[0] >= 200 && $_[0] < 300; }
152 6 100 100 6 1 62 sub is_redirect ($) { $_[0] && $_[0] >= 300 && $_[0] < 400; }
153 13 100 100 13 1 116 sub is_error ($) { $_[0] && $_[0] >= 400 && $_[0] < 600; }
154 3 100 100 3 1 28 sub is_client_error ($) { $_[0] && $_[0] >= 400 && $_[0] < 500; }
155 3 100 100 3 1 47 sub is_server_error ($) { $_[0] && $_[0] >= 500 && $_[0] < 600; }
156 18 50 100 18 1 6916 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;
173              
174             =pod
175              
176             =encoding UTF-8
177              
178             =head1 NAME
179              
180             HTTP::Status - HTTP Status code processing
181              
182             =head1 VERSION
183              
184             version 6.44
185              
186             =head1 SYNOPSIS
187              
188             use HTTP::Status qw(:constants :is status_message);
189              
190             if ($rc != HTTP_OK) {
191             print status_message($rc), "\n";
192             }
193              
194             if (is_success($rc)) { ... }
195             if (is_error($rc)) { ... }
196             if (is_redirect($rc)) { ... }
197              
198             =head1 DESCRIPTION
199              
200             I is a library of routines for defining and
201             classifying HTTP status codes for libwww-perl. Status codes are
202             used to encode the overall outcome of an HTTP response message. Codes
203             correspond to those defined in RFC 2616 and RFC 2518.
204              
205             =head1 CONSTANTS
206              
207             The following constant functions can be used as mnemonic status code
208             names. None of these are exported by default. Use the C<:constants>
209             tag to import them all.
210              
211             HTTP_CONTINUE (100)
212             HTTP_SWITCHING_PROTOCOLS (101)
213             HTTP_PROCESSING (102)
214             HTTP_EARLY_HINTS (103)
215              
216             HTTP_OK (200)
217             HTTP_CREATED (201)
218             HTTP_ACCEPTED (202)
219             HTTP_NON_AUTHORITATIVE_INFORMATION (203)
220             HTTP_NO_CONTENT (204)
221             HTTP_RESET_CONTENT (205)
222             HTTP_PARTIAL_CONTENT (206)
223             HTTP_MULTI_STATUS (207)
224             HTTP_ALREADY_REPORTED (208)
225              
226             HTTP_IM_USED (226)
227              
228             HTTP_MULTIPLE_CHOICES (300)
229             HTTP_MOVED_PERMANENTLY (301)
230             HTTP_FOUND (302)
231             HTTP_SEE_OTHER (303)
232             HTTP_NOT_MODIFIED (304)
233             HTTP_USE_PROXY (305)
234             HTTP_TEMPORARY_REDIRECT (307)
235             HTTP_PERMANENT_REDIRECT (308)
236              
237             HTTP_BAD_REQUEST (400)
238             HTTP_UNAUTHORIZED (401)
239             HTTP_PAYMENT_REQUIRED (402)
240             HTTP_FORBIDDEN (403)
241             HTTP_NOT_FOUND (404)
242             HTTP_METHOD_NOT_ALLOWED (405)
243             HTTP_NOT_ACCEPTABLE (406)
244             HTTP_PROXY_AUTHENTICATION_REQUIRED (407)
245             HTTP_REQUEST_TIMEOUT (408)
246             HTTP_CONFLICT (409)
247             HTTP_GONE (410)
248             HTTP_LENGTH_REQUIRED (411)
249             HTTP_PRECONDITION_FAILED (412)
250             HTTP_PAYLOAD_TOO_LARGE (413)
251             HTTP_URI_TOO_LONG (414)
252             HTTP_UNSUPPORTED_MEDIA_TYPE (415)
253             HTTP_RANGE_NOT_SATISFIABLE (416)
254             HTTP_EXPECTATION_FAILED (417)
255             HTTP_MISDIRECTED REQUEST (421)
256             HTTP_UNPROCESSABLE_ENTITY (422)
257             HTTP_LOCKED (423)
258             HTTP_FAILED_DEPENDENCY (424)
259             HTTP_TOO_EARLY (425)
260             HTTP_UPGRADE_REQUIRED (426)
261             HTTP_PRECONDITION_REQUIRED (428)
262             HTTP_TOO_MANY_REQUESTS (429)
263             HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE (431)
264             HTTP_UNAVAILABLE_FOR_LEGAL_REASONS (451)
265              
266             HTTP_INTERNAL_SERVER_ERROR (500)
267             HTTP_NOT_IMPLEMENTED (501)
268             HTTP_BAD_GATEWAY (502)
269             HTTP_SERVICE_UNAVAILABLE (503)
270             HTTP_GATEWAY_TIMEOUT (504)
271             HTTP_HTTP_VERSION_NOT_SUPPORTED (505)
272             HTTP_VARIANT_ALSO_NEGOTIATES (506)
273             HTTP_INSUFFICIENT_STORAGE (507)
274             HTTP_LOOP_DETECTED (508)
275             HTTP_NOT_EXTENDED (510)
276             HTTP_NETWORK_AUTHENTICATION_REQUIRED (511)
277              
278             =head1 FUNCTIONS
279              
280             The following additional functions are provided. Most of them are
281             exported by default. The C<:is> import tag can be used to import all
282             the classification functions.
283              
284             =over 4
285              
286             =item status_message( $code )
287              
288             The status_message() function will translate status codes to human
289             readable strings. The string is the same as found in the constant
290             names above.
291             For example, C will return C<"Not Found">.
292              
293             If the $code is not registered in the L
294             Codes|https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml>
295             then C is returned.
296              
297             =item status_constant_name( $code )
298              
299             The status_constant_name() function will translate a status code
300             to a string which has the name of the constant for that status code.
301             For example, C will return C<"HTTP_NOT_FOUND">.
302              
303             If the C<$code> is not registered in the L
304             Codes|https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml>
305             then C is returned.
306              
307             =item is_info( $code )
308              
309             Return TRUE if C<$code> is an I status code (1xx). This
310             class of status code indicates a provisional response which can't have
311             any content.
312              
313             =item is_success( $code )
314              
315             Return TRUE if C<$code> is a I status code (2xx).
316              
317             =item is_redirect( $code )
318              
319             Return TRUE if C<$code> is a I status code (3xx). This class of
320             status code indicates that further action needs to be taken by the
321             user agent in order to fulfill the request.
322              
323             =item is_error( $code )
324              
325             Return TRUE if C<$code> is an I status code (4xx or 5xx). The function
326             returns TRUE for both client and server error status codes.
327              
328             =item is_client_error( $code )
329              
330             Return TRUE if C<$code> is a I status code (4xx). This class
331             of status code is intended for cases in which the client seems to have
332             erred.
333              
334             This function is B exported by default.
335              
336             =item is_server_error( $code )
337              
338             Return TRUE if C<$code> is a I status code (5xx). This class
339             of status codes is intended for cases in which the server is aware
340             that it has erred or is incapable of performing the request.
341              
342             This function is B exported by default.
343              
344             =item is_cacheable_by_default( $code )
345              
346             Return TRUE if C<$code> indicates that a response is cacheable by default, and
347             it can be reused by a cache with heuristic expiration. All other status codes
348             are not cacheable by default. See L
349             Section 6.1. Overview of Status Codes|https://tools.ietf.org/html/rfc7231#section-6.1>.
350              
351             This function is B exported by default.
352              
353             =back
354              
355             =head1 SEE ALSO
356              
357             L
358              
359             =head1 BUGS
360              
361             For legacy reasons all the C constants are exported by default
362             with the prefix C. It's recommended to use explicit imports and
363             the C<:constants> tag instead of relying on this.
364              
365             =head1 AUTHOR
366              
367             Gisle Aas
368              
369             =head1 COPYRIGHT AND LICENSE
370              
371             This software is copyright (c) 1994 by Gisle Aas.
372              
373             This is free software; you can redistribute it and/or modify it under
374             the same terms as the Perl 5 programming language system itself.
375              
376             =cut
377              
378             __END__