File Coverage

blib/lib/Dancer2/Core/HTTP.pm
Criterion Covered Total %
statement 24 25 96.0
branch 11 12 91.6
condition 2 3 66.6
subroutine 9 9 100.0
pod 5 5 100.0
total 51 54 94.4


line stmt bran cond sub pod time code
1             # ABSTRACT: helper for rendering HTTP status codes for Dancer2
2              
3             package Dancer2::Core::HTTP;
4             $Dancer2::Core::HTTP::VERSION = '1.0.0';
5 148     148   66336 use strict;
  148         362  
  148         4591  
6 148     148   856 use warnings;
  148         325  
  148         4728  
7              
8 148     148   868 use List::Util qw/ pairmap pairgrep /;
  148         308  
  148         92400  
9              
10             my $HTTP_CODES = {
11              
12             # informational
13             100 => 'Continue', # only on HTTP 1.1
14             101 => 'Switching Protocols', # only on HTTP 1.1
15             102 => 'Processing', # WebDAV; RFC 2518
16              
17             # processed
18             200 => 'OK',
19             201 => 'Created',
20             202 => 'Accepted',
21             203 => 'Non-Authoritative Information', # only on HTTP 1.1
22             204 => 'No Content',
23             205 => 'Reset Content',
24             206 => 'Partial Content',
25             207 => 'Multi-Status', # WebDAV; RFC 4918
26             208 => 'Already Reported', # WebDAV; RFC 5842
27             # 226 => 'IM Used' # RFC 3229
28              
29             # redirections
30             301 => 'Moved Permanently',
31             302 => 'Found',
32             303 => 'See Other', # only on HTTP 1.1
33             304 => 'Not Modified',
34             305 => 'Use Proxy', # only on HTTP 1.1
35             306 => 'Switch Proxy',
36             307 => 'Temporary Redirect', # only on HTTP 1.1
37             # 308 => 'Permanent Redirect' # approved as experimental RFC
38              
39             # problems with request
40             400 => 'Bad Request',
41             401 => 'Unauthorized',
42             402 => 'Payment Required',
43             403 => 'Forbidden',
44             404 => 'Not Found',
45             405 => 'Method Not Allowed',
46             406 => 'Not Acceptable',
47             407 => 'Proxy Authentication Required',
48             408 => 'Request Timeout',
49             409 => 'Conflict',
50             410 => 'Gone',
51             411 => 'Length Required',
52             412 => 'Precondition Failed',
53             413 => 'Request Entity Too Large',
54             414 => 'Request-URI Too Long',
55             415 => 'Unsupported Media Type',
56             416 => 'Requested Range Not Satisfiable',
57             417 => 'Expectation Failed',
58             418 => "I'm a teapot", # RFC 2324
59             # 419 => 'Authentication Timeout', # not in RFC 2616
60             420 => 'Enhance Your Calm',
61             422 => 'Unprocessable Entity',
62             423 => 'Locked',
63             424 => 'Failed Dependency', # Also used for 'Method Failure'
64             425 => 'Unordered Collection',
65             426 => 'Upgrade Required',
66             428 => 'Precondition Required',
67             429 => 'Too Many Requests',
68             431 => 'Request Header Fields Too Large',
69             444 => 'No Response',
70             449 => 'Retry With',
71             450 => 'Blocked by Windows Parental Controls',
72             451 => 'Unavailable For Legal Reasons',
73             494 => 'Request Header Too Large',
74             495 => 'Cert Error',
75             496 => 'No Cert',
76             497 => 'HTTP to HTTPS',
77             499 => 'Client Closed Request',
78              
79             # problems with server
80             500 => 'Internal Server Error',
81             501 => 'Not Implemented',
82             502 => 'Bad Gateway',
83             503 => 'Service Unavailable',
84             504 => 'Gateway Timeout',
85             505 => 'HTTP Version Not Supported',
86             506 => 'Variant Also Negotiates',
87             507 => 'Insufficient Storage',
88             508 => 'Loop Detected',
89             509 => 'Bandwidth Limit Exceeded',
90             510 => 'Not Extended',
91             511 => 'Network Authentication Required',
92             598 => 'Network read timeout error',
93             599 => 'Network connect timeout error',
94             };
95              
96             $HTTP_CODES = {
97             %$HTTP_CODES,
98             ( reverse %$HTTP_CODES ),
99             pairmap { join( '_', split /\W/, lc $a ) => $b } reverse %$HTTP_CODES
100             };
101              
102             $HTTP_CODES->{error} = $HTTP_CODES->{internal_server_error};
103              
104             sub status {
105 797     797 1 7194 my ( $class, $status ) = @_;
106 797 100       3962 return if ! defined $status;
107 796 100       14708 return $status if $status =~ /^\d+$/;
108 7 50       21 if ( exists $HTTP_CODES->{$status} ) {
109 7         57 return $HTTP_CODES->{$status};
110             }
111 0         0 return;
112             }
113              
114             sub status_message {
115 137     137 1 6815 my ( $class, $status ) = @_;
116 137 100       461 return if ! defined $status;
117 136         383 my $code = $class->status($status);
118 136 100 66     2633 return if ! defined $code || ! exists $HTTP_CODES->{$code};
119 134         676 return $HTTP_CODES->{ $code };
120             }
121              
122             sub status_mapping {
123 422 100   422 1 1207 pairgrep { $b =~ /^\d+$/ and $a !~ /_/ } %$HTTP_CODES;
  2     2   1875  
124             }
125              
126             sub code_mapping {
127 1     1 1 3 my @result = reverse status_mapping();
128 1         68 return @result;
129             }
130              
131 1     1 1 872 sub all_mappings { %$HTTP_CODES }
132              
133             1;
134              
135             __END__
136              
137             =pod
138              
139             =encoding UTF-8
140              
141             =head1 NAME
142              
143             Dancer2::Core::HTTP - helper for rendering HTTP status codes for Dancer2
144              
145             =head1 VERSION
146              
147             version 1.0.0
148              
149             =head1 FUNCTIONS
150              
151             =head2 status(status_code)
152              
153             Dancer2::Core::HTTP->status(200); # returns 200
154              
155             Dancer2::Core::HTTP->status('Not Found'); # returns 404
156              
157             Dancer2::Core::HTTP->status('bad_request'); # 400
158              
159             Returns a HTTP status code. If given an integer, it will return the value it
160             received, else it will try to find the appropriate alias and return the correct
161             status.
162              
163             =head2 status_message(status_code)
164              
165             Dancer2::Core::HTTP->status_message(200); # returns 'OK'
166              
167             Dancer2::Core::HTTP->status_message('error'); # returns 'Internal Server Error'
168              
169             Returns the HTTP status message for the given status code.
170              
171             =head2 status_mapping()
172              
173             my %table = Dancer2::Core::HTTP->status_mapping;
174             # returns ( 'Ok' => 200, 'Created' => 201, ... )
175              
176             Returns the full table of status -> code mappings.
177              
178             =head2 code_mapping()
179              
180             my %table = Dancer2::Core::HTTP->code_mapping;
181             # returns ( 200 => 'Ok', 201 => 'Created', ... )
182              
183             Returns the full table of code -> status mappings.
184              
185             =head2 all_mappings()
186              
187             my %table = Dancer2::Core::HTTP->all_mappings;
188             # returns ( 418 => 'I'm a teapot', "I'm a teapot' => 418, 'i_m_a_teapot' => 418 )
189              
190             Returns the code-to-status, status-to-code and underscore-groomed status-to-code mappings
191             all mashed up in a single table. Mostly for internal uses.
192              
193             =head1 AUTHOR
194              
195             Dancer Core Developers
196              
197             =head1 COPYRIGHT AND LICENSE
198              
199             This software is copyright (c) 2023 by Alexis Sukrieh.
200              
201             This is free software; you can redistribute it and/or modify it under
202             the same terms as the Perl 5 programming language system itself.
203              
204             =cut