line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
##---------------------------------------------------------------------------- |
2
|
|
|
|
|
|
|
## Asynchronous HTTP Request and Promise - ~/lib/HTTP/Promise/Headers.pm |
3
|
|
|
|
|
|
|
## Version v0.2.0 |
4
|
|
|
|
|
|
|
## Copyright(c) 2022 DEGUEST Pte. Ltd. |
5
|
|
|
|
|
|
|
## Author: Jacques Deguest <jack@deguest.jp> |
6
|
|
|
|
|
|
|
## Created 2022/03/21 |
7
|
|
|
|
|
|
|
## Modified 2023/09/08 |
8
|
|
|
|
|
|
|
## All rights reserved. |
9
|
|
|
|
|
|
|
## |
10
|
|
|
|
|
|
|
## |
11
|
|
|
|
|
|
|
## This program is free software; you can redistribute it and/or modify it |
12
|
|
|
|
|
|
|
## under the same terms as Perl itself. |
13
|
|
|
|
|
|
|
##---------------------------------------------------------------------------- |
14
|
|
|
|
|
|
|
package HTTP::Promise::Headers; |
15
|
|
|
|
|
|
|
BEGIN |
16
|
|
|
|
|
|
|
{ |
17
|
14
|
|
|
14
|
|
367709
|
use strict; |
|
14
|
|
|
|
|
45
|
|
|
14
|
|
|
|
|
434
|
|
18
|
14
|
|
|
14
|
|
99
|
use warnings; |
|
14
|
|
|
|
|
38
|
|
|
14
|
|
|
|
|
502
|
|
19
|
14
|
|
|
14
|
|
83
|
use warnings::register; |
|
14
|
|
|
|
|
35
|
|
|
14
|
|
|
|
|
1610
|
|
20
|
14
|
|
|
14
|
|
539
|
use parent qw( HTTP::XSHeaders ); |
|
14
|
|
|
|
|
353
|
|
|
14
|
|
|
|
|
109
|
|
21
|
14
|
|
|
14
|
|
123547
|
use vars qw( $VERSION $EXCEPTION_CLASS $MOD_PERL $SUPPORTED $MOD_PATH ); |
|
14
|
|
|
|
|
34
|
|
|
14
|
|
|
|
|
988
|
|
22
|
14
|
|
|
14
|
|
116
|
use Config; |
|
14
|
|
|
|
|
27
|
|
|
14
|
|
|
|
|
585
|
|
23
|
14
|
|
|
14
|
|
91
|
use Cwd (); |
|
14
|
|
|
|
|
26
|
|
|
14
|
|
|
|
|
242
|
|
24
|
14
|
|
|
14
|
|
563
|
use Encode; |
|
14
|
|
|
|
|
14400
|
|
|
14
|
|
|
|
|
1195
|
|
25
|
14
|
|
|
14
|
|
2491
|
use HTTP::Promise::Exception; |
|
14
|
|
|
|
|
37
|
|
|
14
|
|
|
|
|
172
|
|
26
|
14
|
|
|
14
|
|
4434
|
use HTTP::XSHeaders 0.400004; |
|
14
|
|
|
|
|
272
|
|
|
14
|
|
|
|
|
361
|
|
27
|
14
|
|
|
14
|
|
85
|
use IO::File; |
|
14
|
|
|
|
|
26
|
|
|
14
|
|
|
|
|
1877
|
|
28
|
|
|
|
|
|
|
# use Nice::Try; |
29
|
14
|
|
|
14
|
|
86
|
use Scalar::Util; |
|
14
|
|
|
|
|
38
|
|
|
14
|
|
|
|
|
508
|
|
30
|
14
|
|
|
14
|
|
5893
|
use URI::Escape::XS (); |
|
14
|
|
|
|
|
1103447
|
|
|
14
|
|
|
|
|
483
|
|
31
|
14
|
|
|
14
|
|
117
|
use Want; |
|
14
|
|
|
|
|
28
|
|
|
14
|
|
|
|
|
3046
|
|
32
|
14
|
50
|
33
|
14
|
|
135
|
if( exists( $ENV{MOD_PERL} ) |
33
|
|
|
|
|
|
|
&& |
34
|
|
|
|
|
|
|
( $MOD_PERL = $ENV{MOD_PERL} =~ /^mod_perl\/(\d+\.[\d\.]+)/ ) ) |
35
|
|
|
|
|
|
|
{ |
36
|
0
|
|
|
|
|
0
|
select( ( select( STDOUT ), $| = 1 )[ 0 ] ); |
37
|
0
|
|
|
|
|
0
|
require Apache2::Log; |
38
|
|
|
|
|
|
|
# For _is_class_loaded method |
39
|
0
|
|
|
|
|
0
|
require Apache2::Module; |
40
|
0
|
|
|
|
|
0
|
require Apache2::ServerUtil; |
41
|
0
|
|
|
|
|
0
|
require Apache2::RequestUtil; |
42
|
0
|
|
|
|
|
0
|
require Apache2::ServerRec; |
43
|
0
|
|
|
|
|
0
|
require ModPerl::Util; |
44
|
0
|
|
|
|
|
0
|
require Apache2::Const; |
45
|
0
|
|
|
|
|
0
|
Apache2::Const->import( compile => qw( :log OK ) ); |
46
|
|
|
|
|
|
|
} |
47
|
14
|
|
|
14
|
|
112
|
use constant CRLF => "\015\012"; |
|
14
|
|
|
|
|
27
|
|
|
14
|
|
|
|
|
1515
|
|
48
|
14
|
|
33
|
14
|
|
87
|
use constant HAS_THREADS => ( $Config{useithreads} && $INC{'threads.pm'} ); |
|
14
|
|
|
|
|
23
|
|
|
14
|
|
|
|
|
1381
|
|
49
|
14
|
|
|
|
|
47
|
our $EXCEPTION_CLASS = 'HTTP::Promise::Exception'; |
50
|
14
|
|
|
|
|
29
|
our $SUPPORTED = {}; |
51
|
14
|
|
|
|
|
328
|
our $VERSION = 'v0.2.0'; |
52
|
|
|
|
|
|
|
}; |
53
|
|
|
|
|
|
|
|
54
|
14
|
|
|
14
|
|
84
|
use strict; |
|
14
|
|
|
|
|
43
|
|
|
14
|
|
|
|
|
391
|
|
55
|
14
|
|
|
14
|
|
72
|
use warnings; |
|
14
|
|
|
|
|
41
|
|
|
14
|
|
|
|
|
44358
|
|
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
my $stderr = IO::File->new; |
58
|
|
|
|
|
|
|
$stderr->fdopen( fileno( STDERR ), 'w' ); |
59
|
|
|
|
|
|
|
$stderr->binmode( ':utf8' ); |
60
|
|
|
|
|
|
|
$stderr->autoflush( 1 ); |
61
|
|
|
|
|
|
|
my $stderr_raw = IO::File->new; |
62
|
|
|
|
|
|
|
$stderr_raw->fdopen( fileno( STDERR ), 'w' ); |
63
|
|
|
|
|
|
|
$stderr_raw->binmode( ':raw' ); |
64
|
|
|
|
|
|
|
$stderr_raw->autoflush( 1 ); |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
our $MOD_PATH = Cwd::abs_path( $INC{ ( __PACKAGE__ =~ s{::}{/}gr ) . '.pm' } ); |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
# for mod in `ls -1 ./lib/HTTP/Promise/Headers`; do printf "%-32s => 'HTTP::Promise::Headers::%s',\n" $(echo $(basename $mod ".pm")|tr "[:upper:]" "[:lower:]") $(basename $mod ".pm"); done |
69
|
|
|
|
|
|
|
# or |
70
|
|
|
|
|
|
|
# perl -MModule::Generic::File=file -lE 'my $d=file("./lib/HTTP/Promise/Headers"); my $files=$d->content; $files->for(sub{ my$f=file($_); printf("%-32s => ''HTTP::Promise::Headers::%s'',\n", $f->basename(".pm")->lc, $f->basename(".pm")) })' |
71
|
|
|
|
|
|
|
our $SUPPORTED = |
72
|
|
|
|
|
|
|
{ |
73
|
|
|
|
|
|
|
accept => 'HTTP::Promise::Headers::Accept', |
74
|
|
|
|
|
|
|
acceptencoding => 'HTTP::Promise::Headers::AcceptEncoding', |
75
|
|
|
|
|
|
|
acceptlanguage => 'HTTP::Promise::Headers::AcceptLanguage', |
76
|
|
|
|
|
|
|
altsvc => 'HTTP::Promise::Headers::AltSvc', |
77
|
|
|
|
|
|
|
cachecontrol => 'HTTP::Promise::Headers::CacheControl', |
78
|
|
|
|
|
|
|
clearsitedata => 'HTTP::Promise::Headers::ClearSiteData', |
79
|
|
|
|
|
|
|
contentdisposition => 'HTTP::Promise::Headers::ContentDisposition', |
80
|
|
|
|
|
|
|
contentrange => 'HTTP::Promise::Headers::ContentRange', |
81
|
|
|
|
|
|
|
contentsecuritypolicy => 'HTTP::Promise::Headers::ContentSecurityPolicy', |
82
|
|
|
|
|
|
|
contentsecuritypolicyreportonly => 'HTTP::Promise::Headers::ContentSecurityPolicyReportOnly', |
83
|
|
|
|
|
|
|
contenttype => 'HTTP::Promise::Headers::ContentType', |
84
|
|
|
|
|
|
|
cookie => 'HTTP::Promise::Headers::Cookie', |
85
|
|
|
|
|
|
|
expectct => 'HTTP::Promise::Headers::ExpectCT', |
86
|
|
|
|
|
|
|
forwarded => 'HTTP::Promise::Headers::Forwarded', |
87
|
|
|
|
|
|
|
generic => 'HTTP::Promise::Headers::Generic', |
88
|
|
|
|
|
|
|
keepalive => 'HTTP::Promise::Headers::KeepAlive', |
89
|
|
|
|
|
|
|
link => 'HTTP::Promise::Headers::Link', |
90
|
|
|
|
|
|
|
range => 'HTTP::Promise::Headers::Range', |
91
|
|
|
|
|
|
|
servertiming => 'HTTP::Promise::Headers::ServerTiming', |
92
|
|
|
|
|
|
|
stricttransportsecurity => 'HTTP::Promise::Headers::StrictTransportSecurity', |
93
|
|
|
|
|
|
|
te => 'HTTP::Promise::Headers::TE', |
94
|
|
|
|
|
|
|
wantdigest => 'HTTP::Promise::Headers::WantDigest', |
95
|
|
|
|
|
|
|
}; |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
sub new |
98
|
|
|
|
|
|
|
{ |
99
|
188
|
|
|
188
|
1
|
21986
|
my $this = shift( @_ ); |
100
|
188
|
|
|
|
|
679
|
my $opts = {}; |
101
|
188
|
100
|
|
|
|
1084
|
$opts = pop( @_ ) if( ref( $_[-1] ) eq 'HASH' ); |
102
|
188
|
|
|
|
|
516
|
my $self; |
103
|
|
|
|
|
|
|
# try-catch |
104
|
188
|
|
|
|
|
547
|
local $@; |
105
|
|
|
|
|
|
|
eval |
106
|
188
|
|
|
|
|
548
|
{ |
107
|
188
|
|
|
|
|
2610
|
$self = $this->SUPER::new( @_ ); |
108
|
|
|
|
|
|
|
}; |
109
|
188
|
50
|
|
|
|
787
|
if( $@ ) |
110
|
|
|
|
|
|
|
{ |
111
|
0
|
|
|
|
|
0
|
return( $this->error( "Error instantiating an HTTP::Promise::Headers object: $@" ) ); |
112
|
|
|
|
|
|
|
} |
113
|
188
|
|
|
|
|
977
|
$self->{default_type} = undef; |
114
|
188
|
|
|
|
|
654
|
$self->{_init_strict_use_sub} = 1; |
115
|
188
|
|
|
|
|
989
|
$self->{_exception_class} = $EXCEPTION_CLASS; |
116
|
188
|
100
|
|
|
|
1072
|
$self->debug( $opts->{debug} ) if( CORE::exists( $opts->{debug} ) ); |
117
|
188
|
|
|
|
|
943
|
$self->{_ctype_cached} = ''; |
118
|
188
|
|
|
|
|
1175
|
return( $self ); |
119
|
|
|
|
|
|
|
} |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
# e.g. text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 |
122
|
|
|
|
|
|
|
sub accept |
123
|
|
|
|
|
|
|
{ |
124
|
0
|
|
|
0
|
1
|
0
|
my $self = shift( @_ ); |
125
|
0
|
0
|
|
|
|
0
|
if( @_ ) |
126
|
|
|
|
|
|
|
{ |
127
|
0
|
|
|
|
|
0
|
my $types = $self->_get_args_as_array( @_ ); |
128
|
0
|
|
|
|
|
0
|
$self->header( accept => $types ); |
129
|
0
|
|
|
|
|
0
|
CORE::delete( $self->{acceptables} ); |
130
|
|
|
|
|
|
|
} |
131
|
0
|
|
|
|
|
0
|
return( $self->_set_get_one( 'Accept' ) ); |
132
|
|
|
|
|
|
|
} |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
# Obsolete header that should not be used |
135
|
0
|
|
|
0
|
1
|
0
|
sub accept_charset { return( shift->_set_get_one( 'Accept-Charset', @_ ) ); } |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
# e.g. gzip, deflate, br |
138
|
0
|
|
|
0
|
1
|
0
|
sub accept_encoding { return( shift->_set_get_multi( 'Accept-Encoding', @_ ) ); } |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
# e.g.: en-GB,fr-FR;q=0.8,fr;q=0.6,ja;q=0.4,en;q=0.2 |
141
|
0
|
|
|
0
|
1
|
0
|
sub accept_language { return( shift->_set_get_multi( 'Accept-Language', @_ ) ); } |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
# NOTE: Accept-Patch is a response header |
144
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Patch> |
145
|
0
|
|
|
0
|
1
|
0
|
sub accept_patch { return( shift->_set_get_one( 'Accept-Patch', @_ ) ); } |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
# NOTE: Accept-Post is a response header |
148
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Post> |
149
|
0
|
|
|
0
|
1
|
0
|
sub accept_post { return( shift->_set_get_multi( 'Accept-Post', @_ ) ); } |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
# NOTE: Accept-Tanges is a response header |
152
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Ranges> |
153
|
0
|
|
|
0
|
1
|
0
|
sub accept_ranges { return( shift->_set_get_multi( 'Accept-Ranges', @_ ) ); } |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
sub acceptables |
156
|
|
|
|
|
|
|
{ |
157
|
0
|
|
|
0
|
1
|
0
|
my $self = shift( @_ ); |
158
|
0
|
0
|
|
|
|
0
|
return( $self->{acceptables} ) if( $self->{acceptables} ); |
159
|
0
|
|
|
|
|
0
|
my $accept_raw = $self->accept; |
160
|
0
|
0
|
|
|
|
0
|
if( $accept_raw ) |
161
|
|
|
|
|
|
|
{ |
162
|
0
|
|
0
|
|
|
0
|
my $f = $self->new_field( accept => $accept_raw ) || |
163
|
|
|
|
|
|
|
return( $self->pass_error ); |
164
|
0
|
|
|
|
|
0
|
$self->{acceptables} = $f; |
165
|
|
|
|
|
|
|
} |
166
|
0
|
|
|
|
|
0
|
return( $self->{acceptables} ); |
167
|
|
|
|
|
|
|
} |
168
|
|
|
|
|
|
|
|
169
|
1
|
|
|
1
|
1
|
106
|
sub add { return( shift->push_header( @_ ) ); } |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Age> |
172
|
0
|
|
|
0
|
1
|
0
|
sub age { return( shift->_set_get_one( 'Age', @_ ) ); } |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
# NOTE: Allow is a response header |
175
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Allow> |
176
|
0
|
|
|
0
|
1
|
0
|
sub allow { return( shift->_set_get_multi( 'Allow', @_ ) ); } |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
# Response header: <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials> |
179
|
0
|
|
|
0
|
1
|
0
|
sub allow_credentials { return( shift->_set_get_one( 'Access-Control-Allow-Credentials', @_ ) ); } |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
# Response header <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers> |
182
|
0
|
|
|
0
|
1
|
0
|
sub allow_headers { return( shift->_set_get_multi( 'Access-Control-Allow-Headers', @_ ) ); } |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods> |
185
|
0
|
|
|
0
|
1
|
0
|
sub allow_methods { return( shift->_set_get_one( 'Access-Control-Allow-Methods', @_ ) ); } |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin> |
188
|
0
|
|
|
0
|
1
|
0
|
sub allow_origin { return( shift->_set_get_one( 'Access-Control-Allow-Origin', @_ ) ); } |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Alt-Svc> |
191
|
0
|
|
|
0
|
1
|
0
|
sub alt_svc { return( shift->_set_get_multi( 'Alt-Svc', @_ ) ); } |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
sub alternate_server |
194
|
|
|
|
|
|
|
{ |
195
|
0
|
|
|
0
|
1
|
0
|
my $self = shift( @_ ); |
196
|
0
|
0
|
|
|
|
0
|
if( @_ ) |
197
|
|
|
|
|
|
|
{ |
198
|
|
|
|
|
|
|
# { name => 'h2', value => 'alt.example.com:443', ma => 2592000, persist => 1 |
199
|
0
|
|
|
|
|
0
|
my $def = $self->_get_args_as_hash( @_ ); |
200
|
0
|
|
|
|
|
0
|
my $name = CORE::delete( $def->{name} ); |
201
|
0
|
|
|
|
|
0
|
my $value = CORE::delete( $def->{value} ); |
202
|
0
|
|
0
|
|
|
0
|
my $f = $self->new_field( alt_svc => [$name => $value], $def ) || |
203
|
|
|
|
|
|
|
return( $self->pass_error ); |
204
|
0
|
|
|
|
|
0
|
$self->push_header( 'Alt-Svc' => "$f" ); |
205
|
|
|
|
|
|
|
} |
206
|
|
|
|
|
|
|
else |
207
|
|
|
|
|
|
|
{ |
208
|
0
|
|
|
|
|
0
|
my $all = $self->alt_svc; |
209
|
0
|
0
|
|
|
|
0
|
return( $all ) if( !$all->length ); |
210
|
0
|
|
|
|
|
0
|
my $a = $self->new_array; |
211
|
|
|
|
|
|
|
$all->foreach(sub |
212
|
|
|
|
|
|
|
{ |
213
|
0
|
|
0
|
0
|
|
0
|
my $f = $self->new_field( alt_svc => $_ ) || |
214
|
|
|
|
|
|
|
return( $self->pass_error ); |
215
|
0
|
|
|
|
|
0
|
$a->push( $f ); |
216
|
0
|
|
|
|
|
0
|
}); |
217
|
0
|
|
|
|
|
0
|
return( $a ); |
218
|
|
|
|
|
|
|
} |
219
|
|
|
|
|
|
|
} |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
# NOTE: as_string() is inherited |
222
|
|
|
|
|
|
|
# NOTE: unfortunately, HTTP::XSHeaders is not dealing with as_string properly |
223
|
|
|
|
|
|
|
# It takes the given eol and replace simply any instance in-between line of \n with it, |
224
|
|
|
|
|
|
|
# thus if you have something like: foo\r\nbar\r\n, it will end up with |
225
|
|
|
|
|
|
|
# foo\r\r\nbar\r\n instead of foot\r\nbar\r\n |
226
|
|
|
|
|
|
|
# Bug report #10 <https://github.com/p5pclub/http-xsheaders/issues/10> |
227
|
|
|
|
|
|
|
# sub as_string { return( shift->SUPER::as_string( @_ ? @_ : ( CRLF ) ) ); } |
228
|
|
|
|
|
|
|
sub as_string |
229
|
|
|
|
|
|
|
{ |
230
|
100
|
|
|
100
|
1
|
79776
|
my $self = shift( @_ ); |
231
|
100
|
|
|
|
|
391
|
my $type = $self->type; |
232
|
|
|
|
|
|
|
# If the type is multipart, ensure we have a boundary set. |
233
|
|
|
|
|
|
|
# This is a convenience for the user, who only needs to set the mime-type |
234
|
|
|
|
|
|
|
# without having to worry about generating a boundary. |
235
|
100
|
100
|
100
|
|
|
475
|
if( defined( $type ) && lc( [split( '/', $type, 2 )]->[0] ) eq 'multipart' ) |
236
|
|
|
|
|
|
|
{ |
237
|
8
|
|
|
|
|
353
|
my $boundary = $self->multipart_boundary; |
238
|
8
|
100
|
|
|
|
220
|
unless( $boundary ) |
239
|
|
|
|
|
|
|
{ |
240
|
2
|
|
|
|
|
37
|
$boundary = $self->make_boundary; |
241
|
2
|
|
|
|
|
21
|
my $ct = $self->new_field( 'Content-Type' => $type ); |
242
|
2
|
|
|
|
|
11
|
$ct->boundary( $boundary ); |
243
|
2
|
|
|
|
|
1122
|
$self->content_type( "$ct" ); |
244
|
|
|
|
|
|
|
} |
245
|
|
|
|
|
|
|
} |
246
|
100
|
100
|
|
|
|
2291
|
my $str = $self->SUPER::as_string( @_ ? @_ : ( CRLF ) ); |
247
|
100
|
100
|
|
|
|
40655
|
if( index( $str, "\r\r\n" ) != -1 ) |
248
|
|
|
|
|
|
|
{ |
249
|
1
|
|
|
|
|
9
|
$str =~ s/\r\r\n/\r\n/g; |
250
|
|
|
|
|
|
|
} |
251
|
100
|
|
|
|
|
583
|
return( $str ); |
252
|
|
|
|
|
|
|
} |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
# NOTE: authorization() is inherited |
255
|
1
|
|
|
1
|
1
|
559
|
sub authorization { return( shift->_set_get_one( 'Authorization', @_ ) ); } |
256
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
# NOTE: authorization_basic() is inherited |
258
|
7
|
|
|
7
|
1
|
3057
|
sub authorization_basic { return( shift->_basic_auth( 'Authorization', @_ ) ); } |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
sub boundary |
261
|
|
|
|
|
|
|
{ |
262
|
7
|
|
|
7
|
1
|
70
|
my $self = shift( @_ ); |
263
|
7
|
50
|
|
|
|
36
|
if( @_ ) |
264
|
|
|
|
|
|
|
{ |
265
|
0
|
|
|
|
|
0
|
my $boundary = shift( @_ ); |
266
|
0
|
|
|
|
|
0
|
my $ct = $self->content_type; |
267
|
0
|
|
|
|
|
0
|
$self->{boundary} = $boundary; |
268
|
|
|
|
|
|
|
# If there is a content type set, add the charset to it; otherwise, just return |
269
|
|
|
|
|
|
|
# User should set the content type before setting the charset |
270
|
0
|
0
|
|
|
|
0
|
return( '' ) if( !length( $ct ) ); |
271
|
0
|
|
0
|
|
|
0
|
my $f = $self->new_field( content_type => $ct ) || |
272
|
|
|
|
|
|
|
return( $self->pass_error ); |
273
|
0
|
|
|
|
|
0
|
$f->param( boundary => $boundary ); |
274
|
0
|
|
|
|
|
0
|
$self->{type} = $f->type; |
275
|
0
|
|
|
|
|
0
|
$self->content_type( $f ); |
276
|
0
|
|
|
|
|
0
|
$self->{_ctype_cached} = "$f"; |
277
|
|
|
|
|
|
|
} |
278
|
7
|
100
|
100
|
|
|
95
|
unless( length( $self->{boundary} ) && $self->{_ctype_cached} eq $self->content_type ) |
279
|
|
|
|
|
|
|
{ |
280
|
4
|
|
|
|
|
99
|
my $ct = $self->content_type; |
281
|
4
|
50
|
|
|
|
106
|
my $f = $self->new_field( content_type => ( defined( $ct ) ? "$ct" : () ) ); |
282
|
4
|
|
|
|
|
32
|
$self->{boundary} = $f->boundary; |
283
|
4
|
|
|
|
|
2232
|
$self->{type} = $f->type; |
284
|
4
|
|
|
|
|
151765
|
$self->{_ctype_cached} = $ct; |
285
|
|
|
|
|
|
|
} |
286
|
7
|
|
|
|
|
209
|
return( $self->{boundary} ); |
287
|
|
|
|
|
|
|
} |
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control> |
290
|
1
|
|
|
1
|
1
|
11
|
sub cache_control { return( shift->_set_get_one( 'Cache-Control', @_ ) ); } |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
sub charset |
293
|
|
|
|
|
|
|
{ |
294
|
0
|
|
|
0
|
1
|
0
|
my $self = shift( @_ ); |
295
|
0
|
0
|
|
|
|
0
|
if( @_ ) |
296
|
|
|
|
|
|
|
{ |
297
|
0
|
|
|
|
|
0
|
my $charset = shift( @_ ); |
298
|
0
|
|
|
|
|
0
|
my $ct = $self->content_type; |
299
|
0
|
|
|
|
|
0
|
$self->{charset} = $charset; |
300
|
|
|
|
|
|
|
# If there is a content type set, add the charset to it; otherwise, just return |
301
|
|
|
|
|
|
|
# User should set the content type before setting the charset |
302
|
0
|
0
|
|
|
|
0
|
return( '' ) if( !length( $ct ) ); |
303
|
0
|
|
0
|
|
|
0
|
my $f = $self->new_field( content_type => $ct ) || return( $self->pass_error ); |
304
|
0
|
|
|
|
|
0
|
$f->param( charset => $charset ); |
305
|
0
|
|
|
|
|
0
|
$self->content_type( $f ); |
306
|
|
|
|
|
|
|
} |
307
|
0
|
0
|
|
|
|
0
|
unless( length( $self->{charset} ) ) |
308
|
|
|
|
|
|
|
{ |
309
|
0
|
|
|
|
|
0
|
my $ct = $self->content_type; |
310
|
0
|
|
|
|
|
0
|
my $f = $self->new_field( content_type => $ct ); |
311
|
0
|
|
|
|
|
0
|
$self->{charset} = $f->charset; |
312
|
|
|
|
|
|
|
} |
313
|
0
|
|
|
|
|
0
|
return( $self->{charset} ); |
314
|
|
|
|
|
|
|
} |
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
# NOTE: clear() is inherited |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Clear-Site-Data> |
319
|
0
|
|
|
0
|
1
|
0
|
sub clear_site_data { return( shift->_set_get_multi( 'Clear-Site-Data', @_ ) ); } |
320
|
|
|
|
|
|
|
|
321
|
36
|
|
|
36
|
0
|
89
|
sub client_date { return( shift->_date_header( 'Client-Date', @_ ) ); } |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
# NOTE: clone() is inherited |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Connection> |
326
|
0
|
|
|
0
|
1
|
0
|
sub connection { return( shift->_set_get_one( 'Connection', @_ ) ); } |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition> |
329
|
51
|
|
|
51
|
1
|
1109150
|
sub content_disposition { return( shift->_set_get_one( 'Content-Disposition', @_ ) ); } |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
# NOTE: content_encoding() is implemented in our parent class, but our implementation differs |
332
|
136
|
|
|
136
|
1
|
3336
|
sub content_encoding { return( shift->_set_get_one( 'Content-Encoding', @_ ) ); } |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
# NOTE: content_is_html() is already implemented by our parent class, but our implementation of content_type() differs |
335
|
|
|
|
|
|
|
sub content_is_html |
336
|
|
|
|
|
|
|
{ |
337
|
2
|
|
|
2
|
1
|
1806
|
my $self = shift( @_ ); |
338
|
2
|
|
|
|
|
8
|
my $type = $self->type; |
339
|
2
|
50
|
33
|
|
|
24
|
return(0) if( !defined( $type ) || !length( "$type" ) ); |
340
|
2
|
|
|
|
|
10
|
$type = lc( $type ); |
341
|
2
|
|
66
|
|
|
20
|
return( $type eq 'text/html' || $self->content_is_xhtml ); |
342
|
|
|
|
|
|
|
} |
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
sub content_is_json |
345
|
|
|
|
|
|
|
{ |
346
|
0
|
|
|
0
|
1
|
0
|
my $self = shift( @_ ); |
347
|
0
|
|
|
|
|
0
|
my $type = $self->type; |
348
|
0
|
0
|
0
|
|
|
0
|
return(0) if( !defined( $type ) || !length( "$type" ) ); |
349
|
0
|
|
|
|
|
0
|
$type = lc( $type ); |
350
|
0
|
|
|
|
|
0
|
return( $type eq 'application/json' ); |
351
|
|
|
|
|
|
|
} |
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
sub content_is_text |
354
|
|
|
|
|
|
|
{ |
355
|
16
|
|
|
16
|
1
|
57
|
my $self = shift( @_ ); |
356
|
16
|
|
|
|
|
89
|
my $type = $self->content_type; |
357
|
16
|
100
|
66
|
|
|
345
|
return(0) if( !defined( $type ) || !length( "$type" ) ); |
358
|
14
|
|
|
|
|
286
|
return( $$type =~ m,^text/,i ); |
359
|
|
|
|
|
|
|
} |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
# NOTE: content_is_xhtml() is already implemented by our parent class, but our implementation of content_type() differs |
362
|
|
|
|
|
|
|
sub content_is_xhtml |
363
|
|
|
|
|
|
|
{ |
364
|
3
|
|
|
3
|
1
|
9
|
my $self = shift( @_ ); |
365
|
3
|
|
|
|
|
61
|
my $type = $self->type; |
366
|
3
|
50
|
33
|
|
|
9
|
return(0) if( !defined( $type ) || !length( "$type" ) ); |
367
|
3
|
|
|
|
|
68
|
$type = lc( $type ); |
368
|
3
|
|
66
|
|
|
31
|
return( $type eq 'application/xhtml+xml' || $type eq 'application/vnd.wap.xhtml+xml' ); |
369
|
|
|
|
|
|
|
} |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
# NOTE: content_is_xml() is already implemented by our parent class, but our implementation of content_type() differs |
372
|
|
|
|
|
|
|
sub content_is_xml |
373
|
|
|
|
|
|
|
{ |
374
|
28
|
|
|
28
|
1
|
123
|
my $self = shift( @_ ); |
375
|
28
|
|
|
|
|
282
|
my $type = $self->type; |
376
|
28
|
100
|
66
|
|
|
214
|
return(0) if( !defined( $type ) || !length( "$type" ) ); |
377
|
24
|
|
|
|
|
504
|
$type = lc( $type ); |
378
|
24
|
50
|
|
|
|
198
|
return(1) if( $type eq 'text/xml' ); |
379
|
24
|
100
|
|
|
|
122
|
return(1) if( $type eq 'application/xml' ); |
380
|
21
|
100
|
|
|
|
177
|
return(1) if( $type =~ /\+xml$/ ); |
381
|
20
|
|
|
|
|
172
|
return(0); |
382
|
|
|
|
|
|
|
} |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
# NOTE: content_language() is implemented in our parent class, but our implementation differs |
385
|
3
|
|
|
3
|
1
|
1144
|
sub content_language { return( shift->_set_get_multi( 'Content-Language', @_ ) ); } |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
# NOTE: content_length() is implemented in our parent class, but our implementation differs |
388
|
24
|
|
|
24
|
1
|
271
|
sub content_length { return( shift->_set_get_one_number( 'Content-Length', @_ ) ); } |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Location> |
391
|
0
|
|
|
0
|
1
|
0
|
sub content_location { return( shift->_set_get_one( 'Content-Location', @_ ) ); } |
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Range> |
394
|
0
|
|
|
0
|
1
|
0
|
sub content_range { return( shift->_set_get_one( 'Content-Range', @_ ) ); } |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy> |
397
|
0
|
|
|
0
|
1
|
0
|
sub content_security_policy { return( shift->_set_get_one( 'Content-Security-Policy', @_ ) ); } |
398
|
|
|
|
|
|
|
|
399
|
0
|
|
|
0
|
1
|
0
|
sub content_security_policy_report_only { return( shift->_set_get_one( 'Content-Security-Policy-Report-Only', @_ ) ); } |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
# NOTE: content_type() is already implemented by our parent class, but we our implementation is more straightforward in line with the idea of setting and getting exactly the header field value. |
402
|
|
|
|
|
|
|
# Arguably, it is wrong to expect the return value of content_type to be only the mime_type, thus there is the type() method for that |
403
|
|
|
|
|
|
|
sub content_type |
404
|
|
|
|
|
|
|
{ |
405
|
403
|
|
|
403
|
1
|
557542
|
my $self = shift( @_ ); |
406
|
403
|
|
|
|
|
574
|
my $v; |
407
|
403
|
100
|
|
|
|
906
|
if( @_ ) |
408
|
|
|
|
|
|
|
{ |
409
|
16
|
|
|
|
|
59
|
$v = shift( @_ ); |
410
|
16
|
|
|
|
|
189
|
$self->header( content_type => $v ); |
411
|
|
|
|
|
|
|
# Simple value, set the type() cache |
412
|
16
|
100
|
|
|
|
87
|
if( index( $v, ';' ) == -1 ) |
413
|
|
|
|
|
|
|
{ |
414
|
8
|
|
|
|
|
36
|
$self->{type} = $v; |
415
|
|
|
|
|
|
|
} |
416
|
|
|
|
|
|
|
# Force type() to find the mime-type |
417
|
|
|
|
|
|
|
else |
418
|
|
|
|
|
|
|
{ |
419
|
8
|
|
|
|
|
536985
|
$self->{type} = ''; |
420
|
|
|
|
|
|
|
} |
421
|
|
|
|
|
|
|
|
422
|
16
|
100
|
|
|
|
143
|
return( $self->new_scalar( ref( $v ) ? "$v" : \$v ) ); |
423
|
|
|
|
|
|
|
} |
424
|
|
|
|
|
|
|
else |
425
|
|
|
|
|
|
|
{ |
426
|
387
|
|
|
|
|
1895
|
$v = $self->header( 'Content-Type' ); |
427
|
|
|
|
|
|
|
} |
428
|
|
|
|
|
|
|
|
429
|
387
|
100
|
|
|
|
1101
|
if( defined( $v ) ) |
|
|
50
|
|
|
|
|
|
430
|
|
|
|
|
|
|
{ |
431
|
241
|
100
|
|
|
|
1384
|
return( $self->new_scalar( ref( $v ) ? "$v" : \$v ) ); |
432
|
|
|
|
|
|
|
} |
433
|
|
|
|
|
|
|
elsif( want( 'OBJECT' ) ) |
434
|
|
|
|
|
|
|
{ |
435
|
0
|
|
|
|
|
0
|
return( Module::Generic::Null->new ); |
436
|
|
|
|
|
|
|
} |
437
|
|
|
|
|
|
|
else |
438
|
|
|
|
|
|
|
{ |
439
|
146
|
|
|
|
|
8213
|
return; |
440
|
|
|
|
|
|
|
} |
441
|
|
|
|
|
|
|
} |
442
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
# NOTE: content_type_charset() is inherited |
444
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy> |
446
|
0
|
|
|
0
|
1
|
0
|
sub cross_origin_embedder_policy { return( shift->_set_get_one( 'Cross-Origin-Embedder-Policy', @_ ) ); } |
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy> |
449
|
0
|
|
|
0
|
1
|
0
|
sub cross_origin_opener_policy { return( shift->_set_get_one( 'Cross-Origin-Opener-Policy', @_ ) ); } |
450
|
|
|
|
|
|
|
|
451
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Resource-Policy> |
452
|
0
|
|
|
0
|
1
|
0
|
sub cross_origin_resource_policy { return( shift->_set_get_one( 'Cross-Origin-Resource-Policy', @_ ) ); } |
453
|
|
|
|
|
|
|
|
454
|
0
|
|
|
0
|
1
|
0
|
sub cspro { return( shift->content_security_policy_report_only( @_ ) ); } |
455
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
# NOTE: date() is already implemented by our parent class, but our implementation is more versatile and better |
457
|
51
|
|
|
51
|
1
|
3255
|
sub date { return( shift->_date_header( 'Date', @_ ) ); } |
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
# rfc2231 <https://datatracker.ietf.org/doc/html/rfc2231> |
460
|
|
|
|
|
|
|
sub decode_filename |
461
|
|
|
|
|
|
|
{ |
462
|
11
|
|
|
11
|
1
|
29
|
my $self = shift( @_ ); |
463
|
11
|
|
|
|
|
27
|
my $fname = shift( @_ ); |
464
|
11
|
50
|
33
|
|
|
75
|
return( $fname ) if( !defined( $fname ) || !length( $fname ) ); |
465
|
11
|
|
|
|
|
26
|
my( $charset, $lang ); |
466
|
11
|
100
|
|
|
|
138
|
if( $fname =~ /^(.*?)\'([^\']*)\'(.*?)$/ ) |
|
|
100
|
|
|
|
|
|
467
|
|
|
|
|
|
|
{ |
468
|
1
|
|
|
|
|
9
|
( $charset, $lang, my $encoded_fname ) = ( $1, $2, $3 ); |
469
|
1
|
50
|
33
|
|
|
10
|
unless( lc( $charset ) eq 'utf8' || lc( $charset ) eq 'utf-8' ) |
470
|
|
|
|
|
|
|
{ |
471
|
0
|
|
|
|
|
0
|
return( $self->error( "Character set '$charset' is not supported for file name '$encoded_fname'" ) ); |
472
|
|
|
|
|
|
|
} |
473
|
|
|
|
|
|
|
# The language parameter, if any, is discarded |
474
|
1
|
|
|
|
|
6
|
$fname = Encode::decode_utf8( URI::Escape::XS::uri_unescape( $encoded_fname ) ); |
475
|
|
|
|
|
|
|
} |
476
|
|
|
|
|
|
|
# rfc2047 encoded? |
477
|
|
|
|
|
|
|
elsif( $fname =~ /^=\?(.+?)\?(.+?)\?(.+)\?=$/ ) |
478
|
|
|
|
|
|
|
{ |
479
|
4
|
|
|
|
|
11
|
$charset = $1; |
480
|
4
|
|
|
|
|
11
|
my $encoding = uc( $2 ); |
481
|
4
|
|
|
|
|
9
|
my $encfile = $3; |
482
|
|
|
|
|
|
|
|
483
|
4
|
100
|
100
|
|
|
32
|
if( $encoding eq 'Q' || $encoding eq 'B' ) |
484
|
|
|
|
|
|
|
{ |
485
|
|
|
|
|
|
|
eval |
486
|
3
|
|
|
|
|
5
|
{ |
487
|
3
|
100
|
|
|
|
11
|
if( $encoding eq 'Q' ) |
488
|
|
|
|
|
|
|
{ |
489
|
1
|
|
|
|
|
13
|
$encfile =~ s/_/ /g; |
490
|
1
|
50
|
|
|
|
4
|
$self->_load_class( 'HTTP::Promise::Stream' ) || return( $self->pass_error ); |
491
|
1
|
|
50
|
|
|
34
|
my $s = HTTP::Promise::Stream->new( \$encfile, { decoding => 'quoted-printable' } ) || |
492
|
|
|
|
|
|
|
return( $self->pass_error( HTTP::Promise::Stream->error ) ); |
493
|
1
|
|
|
|
|
21
|
my $decoded = $s->decode; |
494
|
1
|
50
|
|
|
|
20
|
return( $self->pass_error( $s->error ) ) if( !defined( $decoded ) ); |
495
|
1
|
|
|
|
|
6
|
$encfile = $decoded; |
496
|
|
|
|
|
|
|
} |
497
|
|
|
|
|
|
|
# $encoding eq 'B' |
498
|
|
|
|
|
|
|
else |
499
|
|
|
|
|
|
|
{ |
500
|
2
|
50
|
|
|
|
7
|
$self->_load_class( 'Crypt::Misc' ) || return( $self->pass_error ); |
501
|
2
|
|
|
|
|
42
|
$encfile = Crypt::Misc::decode_b64( $encfile ); |
502
|
|
|
|
|
|
|
} |
503
|
|
|
|
|
|
|
}; |
504
|
|
|
|
|
|
|
|
505
|
3
|
50
|
|
|
|
27
|
if( $@ ) |
506
|
|
|
|
|
|
|
{ |
507
|
|
|
|
|
|
|
# return( $self->error( "Error decoding content disposition file name: $e" ) ); |
508
|
0
|
|
|
|
|
0
|
warnings::warnif( "Error decoding content disposition file name: $@" ); |
509
|
|
|
|
|
|
|
} |
510
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
eval |
512
|
3
|
|
|
|
|
4
|
{ |
513
|
3
|
50
|
|
|
|
13
|
$self->_load_class( 'Encode' ) || return( $self->pass_error ); |
514
|
3
|
50
|
|
|
|
20
|
$self->_load_class( 'Encode::Locale' ) || return( $self->pass_error ); |
515
|
3
|
|
|
|
|
37
|
Encode::from_to( $encfile, $charset, 'locale_fs' ); |
516
|
2
|
|
|
|
|
801
|
$fname = $encfile; |
517
|
|
|
|
|
|
|
}; |
518
|
|
|
|
|
|
|
|
519
|
3
|
100
|
|
|
|
1758
|
if( $@ ) |
520
|
|
|
|
|
|
|
{ |
521
|
|
|
|
|
|
|
# return( $self->error( "Error encoding content disposition file name: $e" ) ); |
522
|
1
|
|
|
|
|
306
|
warnings::warnif( "Error encoding content disposition file name from '$charset' to 'locale_fs': $@" ); |
523
|
|
|
|
|
|
|
} |
524
|
|
|
|
|
|
|
} |
525
|
|
|
|
|
|
|
} |
526
|
11
|
100
|
|
|
|
132
|
return( wantarray() ? ( $fname, $charset, $lang ) : $fname ); |
527
|
|
|
|
|
|
|
} |
528
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
sub debug |
530
|
|
|
|
|
|
|
{ |
531
|
114
|
|
|
114
|
1
|
1940
|
my $self = shift( @_ ); |
532
|
114
|
|
33
|
|
|
438
|
my $class = ( ref( $self ) || $self ); |
533
|
14
|
|
|
14
|
|
129
|
no strict 'refs'; |
|
14
|
|
|
|
|
41
|
|
|
14
|
|
|
|
|
6200
|
|
534
|
114
|
50
|
|
|
|
386
|
if( @_ ) |
535
|
|
|
|
|
|
|
{ |
536
|
114
|
|
|
|
|
204
|
my $flag = shift( @_ ); |
537
|
114
|
|
|
|
|
307
|
$self->{debug} = $flag; |
538
|
114
|
50
|
33
|
|
|
472
|
if( $self->{debug} && |
539
|
|
|
|
|
|
|
!$self->{debug_level} ) |
540
|
|
|
|
|
|
|
{ |
541
|
0
|
|
|
|
|
0
|
$self->{debug_level} = $self->{debug}; |
542
|
|
|
|
|
|
|
} |
543
|
|
|
|
|
|
|
} |
544
|
114
|
|
33
|
|
|
357
|
return( $self->{debug} || ${"$class\:\:DEBUG"} ); |
545
|
|
|
|
|
|
|
} |
546
|
|
|
|
|
|
|
|
547
|
104
|
|
|
104
|
1
|
584
|
sub default_type { return( shift->_set_get( 'default_type', @_ ) ); } |
548
|
|
|
|
|
|
|
|
549
|
0
|
|
|
0
|
1
|
0
|
sub delete { return( shift->remove_header( @_ ) ); } |
550
|
|
|
|
|
|
|
|
551
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Device-Memory> |
552
|
0
|
|
|
0
|
1
|
0
|
sub device_memory { return( shift->_set_get_one( 'Device-Memory', @_ ) ); } |
553
|
|
|
|
|
|
|
|
554
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Digest> |
555
|
0
|
|
|
0
|
1
|
0
|
sub digest { return( shift->_set_get_multi( 'Digest', @_ ) ); } |
556
|
|
|
|
|
|
|
|
557
|
|
|
|
|
|
|
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/DNT |
558
|
0
|
|
|
0
|
1
|
0
|
sub dnt { return( shift->_set_get_one( dnt => @_ ) ); } |
559
|
|
|
|
|
|
|
|
560
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Early-Data> |
561
|
0
|
|
|
0
|
1
|
0
|
sub early_data { return( shift->_set_get_one( 'Early-Data', @_ ) ); } |
562
|
|
|
|
|
|
|
|
563
|
|
|
|
|
|
|
# rfc2231 <https://datatracker.ietf.org/doc/html/rfc2231> |
564
|
|
|
|
|
|
|
sub encode_filename |
565
|
|
|
|
|
|
|
{ |
566
|
3
|
|
|
3
|
1
|
130
|
my $self = shift( @_ ); |
567
|
3
|
|
|
|
|
15
|
my $fname = shift( @_ ); |
568
|
3
|
|
|
|
|
12
|
my $lang = shift( @_ ); |
569
|
3
|
50
|
|
|
|
52
|
if( $fname =~ /[^\w\.]+/ ) |
570
|
|
|
|
|
|
|
{ |
571
|
3
|
50
|
|
|
|
25
|
$lang = '' if( !defined( $lang ) ); |
572
|
3
|
|
|
|
|
61
|
return( sprintf( "UTF-8'${lang}'%s", $self->uri_escape_utf8( $fname ) ) ); |
573
|
|
|
|
|
|
|
} |
574
|
|
|
|
|
|
|
# Nothing to be done. We return undef on purpose to indicate nothing was done |
575
|
0
|
|
|
|
|
0
|
return; |
576
|
|
|
|
|
|
|
} |
577
|
|
|
|
|
|
|
|
578
|
|
|
|
|
|
|
# Copied here from Module::Generic |
579
|
|
|
|
|
|
|
sub error |
580
|
|
|
|
|
|
|
{ |
581
|
2
|
|
|
2
|
1
|
583
|
my $self = shift( @_ ); |
582
|
2
|
|
33
|
|
|
9
|
my $class = ref( $self ) || $self; |
583
|
14
|
|
|
14
|
|
117
|
no warnings; |
|
14
|
|
|
|
|
31
|
|
|
14
|
|
|
|
|
741
|
|
584
|
2
|
|
|
|
|
2
|
our $MOD_PERL; |
585
|
2
|
|
|
|
|
5
|
my $o; |
586
|
14
|
|
|
14
|
|
79
|
no strict 'refs'; |
|
14
|
|
|
|
|
25
|
|
|
14
|
|
|
|
|
19503
|
|
587
|
2
|
100
|
|
|
|
5
|
if( @_ ) |
588
|
|
|
|
|
|
|
{ |
589
|
1
|
|
|
|
|
3
|
my $args = {}; |
590
|
|
|
|
|
|
|
# We got an object as first argument. It could be a child from our exception package or from another package |
591
|
|
|
|
|
|
|
# Either way, we use it as it is |
592
|
1
|
50
|
33
|
|
|
16
|
if( ( Scalar::Util::blessed( $_[0] ) && $_[0]->isa( 'Module::Generic::Exception' ) ) || |
|
|
50
|
33
|
|
|
|
|
593
|
|
|
|
|
|
|
Scalar::Util::blessed( $_[0] ) ) |
594
|
|
|
|
|
|
|
{ |
595
|
0
|
|
|
|
|
0
|
$o = shift( @_ ); |
596
|
|
|
|
|
|
|
} |
597
|
|
|
|
|
|
|
elsif( ref( $_[0] ) eq 'HASH' ) |
598
|
|
|
|
|
|
|
{ |
599
|
0
|
|
|
|
|
0
|
$args = shift( @_ ); |
600
|
|
|
|
|
|
|
} |
601
|
|
|
|
|
|
|
else |
602
|
|
|
|
|
|
|
{ |
603
|
1
|
50
|
33
|
|
|
12
|
$args->{message} = join( '', map( ( ref( $_ ) eq 'CODE' && !$self->{_msg_no_exec_sub} ) ? $_->() : $_, @_ ) ); |
604
|
|
|
|
|
|
|
} |
605
|
1
|
|
50
|
|
|
9
|
$args->{class} //= ''; |
606
|
|
|
|
|
|
|
my $max_len = ( CORE::exists( $self->{error_max_length} ) && $self->{error_max_length} =~ /^[-+]?\d+$/ ) |
607
|
|
|
|
|
|
|
? $self->{error_max_length} |
608
|
1
|
50
|
33
|
|
|
7
|
: 0; |
609
|
1
|
50
|
33
|
|
|
4
|
$args->{message} = substr( $args->{message}, 0, $self->{error_max_length} ) if( $max_len > 0 && length( $args->{message} ) > $max_len ); |
610
|
|
|
|
|
|
|
# Reset it |
611
|
1
|
|
|
|
|
3
|
$self->{_msg_no_exec_sub} = 0; |
612
|
|
|
|
|
|
|
# Note Taken from Carp to find the right point in the stack to start from |
613
|
1
|
|
|
|
|
3
|
my $caller_func; |
614
|
1
|
50
|
|
|
|
2
|
$caller_func = \&{"CORE::GLOBAL::caller"} if( defined( &{"CORE::GLOBAL::caller"} ) ); |
|
0
|
|
|
|
|
0
|
|
|
1
|
|
|
|
|
8
|
|
615
|
1
|
50
|
|
|
|
5
|
if( defined( $o ) ) |
616
|
|
|
|
|
|
|
{ |
617
|
0
|
|
|
|
|
0
|
$self->{error} = ${ $class . '::ERROR' } = $o; |
|
0
|
|
|
|
|
0
|
|
618
|
|
|
|
|
|
|
} |
619
|
|
|
|
|
|
|
else |
620
|
|
|
|
|
|
|
{ |
621
|
|
|
|
|
|
|
my $ex_class = CORE::length( $args->{class} ) |
622
|
|
|
|
|
|
|
? $args->{class} |
623
|
|
|
|
|
|
|
: ( CORE::exists( $self->{_exception_class} ) && CORE::length( $self->{_exception_class} ) ) |
624
|
|
|
|
|
|
|
? $self->{_exception_class} |
625
|
1
|
50
|
33
|
|
|
19
|
: 'Module::Generic::Exception'; |
|
|
50
|
|
|
|
|
|
626
|
1
|
0
|
50
|
|
|
5
|
unless( $self->_is_class_loaded( $ex_class ) || scalar( keys( %{"${ex_class}\::"} ) ) ) |
|
0
|
|
|
|
|
0
|
|
627
|
|
|
|
|
|
|
{ |
628
|
0
|
|
|
|
|
0
|
my $pl = "use $ex_class;"; |
629
|
0
|
|
|
0
|
|
0
|
local $SIG{__DIE__} = sub{}; |
630
|
0
|
|
|
|
|
0
|
eval( $pl ); |
631
|
|
|
|
|
|
|
# We have to die, because we have an error within another error |
632
|
0
|
0
|
|
|
|
0
|
die( __PACKAGE__ . "::error() is unable to load exception class \"$ex_class\": $@" ) if( $@ ); |
633
|
|
|
|
|
|
|
} |
634
|
1
|
|
|
|
|
22
|
$o = $self->{error} = ${ $class . '::ERROR' } = $ex_class->new( $args ); |
|
1
|
|
|
|
|
1140
|
|
635
|
|
|
|
|
|
|
} |
636
|
|
|
|
|
|
|
|
637
|
1
|
|
|
|
|
3
|
my $r; |
638
|
1
|
50
|
|
|
|
5
|
if( $MOD_PERL ) |
639
|
|
|
|
|
|
|
{ |
640
|
|
|
|
|
|
|
# try-catch |
641
|
0
|
|
|
|
|
0
|
local $@; |
642
|
|
|
|
|
|
|
eval |
643
|
0
|
|
|
|
|
0
|
{ |
644
|
0
|
|
|
|
|
0
|
$r = Apache2::RequestUtil->request; |
645
|
0
|
0
|
|
|
|
0
|
$r->warn( $o->as_string ) if( $r ); |
646
|
|
|
|
|
|
|
}; |
647
|
0
|
0
|
|
|
|
0
|
if( $@ ) |
648
|
|
|
|
|
|
|
{ |
649
|
0
|
|
|
|
|
0
|
print( STDERR "Error trying to get the global Apache2::ApacheRec: $@\n" ); |
650
|
|
|
|
|
|
|
} |
651
|
|
|
|
|
|
|
} |
652
|
|
|
|
|
|
|
|
653
|
1
|
50
|
33
|
|
|
7
|
if( $r ) |
|
|
50
|
33
|
|
|
|
|
|
|
50
|
|
|
|
|
|
654
|
|
|
|
|
|
|
{ |
655
|
0
|
0
|
|
|
|
0
|
if( my $log_handler = $r->get_handlers( 'PerlPrivateErrorHandler' ) ) |
656
|
|
|
|
|
|
|
{ |
657
|
0
|
|
|
|
|
0
|
$log_handler->( $o ); |
658
|
|
|
|
|
|
|
} |
659
|
|
|
|
|
|
|
else |
660
|
|
|
|
|
|
|
{ |
661
|
0
|
0
|
|
|
|
0
|
$r->warn( $o->as_string ) if( warnings::enabled() ); |
662
|
|
|
|
|
|
|
} |
663
|
|
|
|
|
|
|
} |
664
|
1
|
|
|
|
|
133
|
elsif( $self->{fatal} || ( defined( ${"${class}\::FATAL_ERROR"} ) && ${"${class}\::FATAL_ERROR"} ) ) |
|
0
|
|
|
|
|
0
|
|
665
|
|
|
|
|
|
|
{ |
666
|
|
|
|
|
|
|
# my $enc_str = eval{ Encode::encode( 'UTF-8', "$o", Encode::FB_CROAK ) }; |
667
|
|
|
|
|
|
|
# die( $@ ? $o : $enc_str ); |
668
|
0
|
|
|
|
|
0
|
die( $o ); |
669
|
|
|
|
|
|
|
} |
670
|
|
|
|
|
|
|
elsif( warnings::enabled() ) |
671
|
|
|
|
|
|
|
{ |
672
|
1
|
50
|
|
|
|
5
|
if( $r ) |
673
|
|
|
|
|
|
|
{ |
674
|
0
|
|
|
|
|
0
|
$r->warn( $o->as_string ); |
675
|
|
|
|
|
|
|
} |
676
|
|
|
|
|
|
|
else |
677
|
|
|
|
|
|
|
{ |
678
|
1
|
|
|
|
|
2
|
my $enc_str = eval{ Encode::encode( 'UTF-8', "$o", Encode::FB_CROAK ) }; |
|
1
|
|
|
|
|
7
|
|
679
|
|
|
|
|
|
|
# Display warnings if warnings for this class is registered and enabled or if not registered |
680
|
1
|
50
|
|
|
|
3085
|
warn( $@ ? $o : $enc_str ); |
681
|
|
|
|
|
|
|
} |
682
|
|
|
|
|
|
|
} |
683
|
|
|
|
|
|
|
|
684
|
|
|
|
|
|
|
# https://metacpan.org/pod/Perl::Critic::Policy::Subroutines::ProhibitExplicitReturnUndef |
685
|
|
|
|
|
|
|
# https://perlmonks.org/index.pl?node_id=741847 |
686
|
|
|
|
|
|
|
# Because in list context this would create a lit with one element undef() |
687
|
|
|
|
|
|
|
# A bare return will return an empty list or an undef scalar |
688
|
|
|
|
|
|
|
# return( undef() ); |
689
|
|
|
|
|
|
|
# return; |
690
|
|
|
|
|
|
|
# As of 2019-10-13, Module::Generic version 0.6, we use this special package Module::Generic::Null to be returned in chain without perl causing the error that a method was called on an undefined value |
691
|
|
|
|
|
|
|
# 2020-05-12: Added the no_return_null_object to instruct not to return a null object |
692
|
|
|
|
|
|
|
# This is especially needed when an error is called from TIEHASH that returns a special object. |
693
|
|
|
|
|
|
|
# A Null object would trigger a fatal perl segmentation fault |
694
|
1
|
50
|
33
|
|
|
16
|
if( !$args->{no_return_null_object} && want( 'OBJECT' ) ) |
695
|
|
|
|
|
|
|
{ |
696
|
0
|
|
|
|
|
0
|
require Module::Generic::Null; |
697
|
0
|
|
|
|
|
0
|
my $null = Module::Generic::Null->new( $o, { debug => $self->{debug}, has_error => 1 }); |
698
|
0
|
|
|
|
|
0
|
rreturn( $null ); |
699
|
|
|
|
|
|
|
} |
700
|
1
|
|
|
|
|
109
|
return; |
701
|
|
|
|
|
|
|
} |
702
|
|
|
|
|
|
|
# To avoid the perl error of 'called on undefined value' and so the user can do |
703
|
|
|
|
|
|
|
# $o->error->message for example without concerning himself/herself whether an exception object is actually set |
704
|
1
|
50
|
33
|
|
|
57
|
if( !$self->{error} && want( 'OBJECT' ) ) |
705
|
|
|
|
|
|
|
{ |
706
|
0
|
|
|
|
|
0
|
require Module::Generic::Null; |
707
|
0
|
|
|
|
|
0
|
my $null = Module::Generic::Null->new( $o, { debug => $self->{debug}, wants => 'object' }); |
708
|
0
|
|
|
|
|
0
|
rreturn( $null ); |
709
|
|
|
|
|
|
|
} |
710
|
1
|
50
|
|
|
|
16
|
return( ref( $self ) ? $self->{error} : ${ $class . '::ERROR' } ); |
|
0
|
|
|
|
|
0
|
|
711
|
|
|
|
|
|
|
} |
712
|
|
|
|
|
|
|
|
713
|
0
|
|
|
0
|
1
|
0
|
sub etag { return( shift->_set_get_one( 'Etag', @_ ) ); } |
714
|
|
|
|
|
|
|
|
715
|
|
|
|
|
|
|
sub exists |
716
|
|
|
|
|
|
|
{ |
717
|
66
|
|
|
66
|
1
|
239
|
my $self = shift( @_ ); |
718
|
66
|
|
50
|
|
|
362
|
my $field = shift( @_ ) || return(0); |
719
|
66
|
|
|
|
|
423
|
my $rv = $self->header( $field ); |
720
|
66
|
50
|
|
|
|
688
|
return( defined( $rv ) ? 1 : 0 ); |
721
|
|
|
|
|
|
|
} |
722
|
|
|
|
|
|
|
|
723
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expect> |
724
|
0
|
|
|
0
|
1
|
0
|
sub expect { return( shift->_set_get_one( 'Expect', @_ ) ); } |
725
|
|
|
|
|
|
|
|
726
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expect-CT> |
727
|
0
|
|
|
0
|
1
|
0
|
sub expect_ct { return( shift->_set_get_multi( 'Expect-CT', @_ ) ); } |
728
|
|
|
|
|
|
|
|
729
|
|
|
|
|
|
|
# NOTE: expires() is inherited |
730
|
25
|
|
|
25
|
1
|
7713
|
sub expires { return( shift->_date_header( 'Expires', @_ ) ); } |
731
|
|
|
|
|
|
|
|
732
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers> |
733
|
|
|
|
|
|
|
# e.g.: Access-Control-Expose-Headers: Content-Encoding, X-Kuma-Revision |
734
|
0
|
|
|
0
|
1
|
0
|
sub expose_headers { return( shift->_set_get_multi( 'Access-Control-Expose-Headers', @_ ) ); } |
735
|
|
|
|
|
|
|
|
736
|
|
|
|
|
|
|
# NOTE: flatten() is inherited |
737
|
|
|
|
|
|
|
|
738
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded> |
739
|
0
|
|
|
0
|
1
|
0
|
sub forwarded { return( shift->_set_get_one( 'Forwarded', @_ ) ); } |
740
|
|
|
|
|
|
|
|
741
|
|
|
|
|
|
|
# NOTE: from() is inherited |
742
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/From> |
743
|
1
|
|
|
1
|
1
|
593
|
sub from { return( shift->_set_get_one( 'From', @_ ) ); } |
744
|
|
|
|
|
|
|
|
745
|
0
|
|
|
0
|
1
|
0
|
sub get { return( shift->header( shift( @_ ) ) ); } |
746
|
|
|
|
|
|
|
|
747
|
|
|
|
|
|
|
# NOTE: header() is inherited |
748
|
|
|
|
|
|
|
|
749
|
|
|
|
|
|
|
# NOTE: header_field_names() is inherited |
750
|
|
|
|
|
|
|
|
751
|
0
|
|
|
0
|
1
|
0
|
sub host { return( shift->_set_get_one( 'Host', @_ ) ); } |
752
|
|
|
|
|
|
|
|
753
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Match> |
754
|
0
|
|
|
0
|
1
|
0
|
sub if_match { return( shift->_set_get_one( 'If-Match', @_ ) ); } |
755
|
|
|
|
|
|
|
|
756
|
|
|
|
|
|
|
# NOTE: if_modified_since() is inherited |
757
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Modified-Since> |
758
|
4
|
|
|
4
|
1
|
3749
|
sub if_modified_since { return( shift->_date_header( 'If-Modified-Since', @_ ) ); } |
759
|
|
|
|
|
|
|
|
760
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-None-Match> |
761
|
0
|
|
|
0
|
1
|
0
|
sub if_none_match { return( shift->_set_get_one( 'If-None-Match', @_ ) ); } |
762
|
|
|
|
|
|
|
|
763
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Range> |
764
|
0
|
|
|
0
|
1
|
0
|
sub if_range { return( shift->_set_get_one( 'If-Range', @_ ) ); } |
765
|
|
|
|
|
|
|
|
766
|
|
|
|
|
|
|
# NOTE: if_unmodified_since() is inherited |
767
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Unmodified-Since> |
768
|
3
|
|
|
3
|
1
|
3683
|
sub if_unmodified_since { return( shift->_date_header( 'If-Unmodified-Since', @_ ) ); } |
769
|
|
|
|
|
|
|
|
770
|
|
|
|
|
|
|
# NOTE: init_header() is inherited |
771
|
|
|
|
|
|
|
|
772
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Keep-Alive> |
773
|
0
|
|
|
0
|
1
|
0
|
sub keep_alive { return( shift->_set_get_one( 'Keep-Alive', @_ ) ); } |
774
|
|
|
|
|
|
|
|
775
|
|
|
|
|
|
|
# NOTE: last_modified() is inherited |
776
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified> |
777
|
22
|
|
|
22
|
1
|
3970
|
sub last_modified { return( shift->_date_header( 'Last-Modified', @_ ) ); } |
778
|
|
|
|
|
|
|
|
779
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Link> |
780
|
0
|
|
|
0
|
1
|
0
|
sub link { return( shift->_set_get_multi( 'Link', @_ ) ); } |
781
|
|
|
|
|
|
|
|
782
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Location> |
783
|
0
|
|
|
0
|
1
|
0
|
sub location { return( shift->_set_get_one( 'Location', @_ ) ); } |
784
|
|
|
|
|
|
|
|
785
|
|
|
|
|
|
|
sub make_boundary |
786
|
|
|
|
|
|
|
{ |
787
|
2
|
|
|
2
|
1
|
8
|
my $self = shift( @_ ); |
788
|
2
|
50
|
|
|
|
9
|
$self->_load_class( 'Data::UUID' ) || return( $self->pass_error ); |
789
|
2
|
|
|
|
|
3311
|
return( Data::UUID->new->create_str ); |
790
|
|
|
|
|
|
|
} |
791
|
|
|
|
|
|
|
|
792
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age> |
793
|
0
|
|
|
0
|
1
|
0
|
sub max_age { return( shift->_set_get_number( 'Access-Control-Max-Age', @_ ) ); } |
794
|
|
|
|
|
|
|
|
795
|
|
|
|
|
|
|
sub message |
796
|
|
|
|
|
|
|
{ |
797
|
0
|
|
|
0
|
0
|
0
|
my $self = shift( @_ ); |
798
|
0
|
|
0
|
|
|
0
|
my $class = ref( $self ) || $self; |
799
|
14
|
|
|
14
|
|
140
|
no strict 'refs'; |
|
14
|
|
|
|
|
30
|
|
|
14
|
|
|
|
|
6695
|
|
800
|
0
|
0
|
0
|
|
|
0
|
if( $self->{verbose} || $self->{debug} || ${ $class . '::DEBUG' } ) |
|
0
|
|
0
|
|
|
0
|
|
801
|
|
|
|
|
|
|
{ |
802
|
0
|
|
|
|
|
0
|
my $r; |
803
|
0
|
0
|
|
|
|
0
|
if( $MOD_PERL ) |
804
|
|
|
|
|
|
|
{ |
805
|
|
|
|
|
|
|
# try-catch |
806
|
0
|
|
|
|
|
0
|
local $@; |
807
|
|
|
|
|
|
|
eval |
808
|
0
|
|
|
|
|
0
|
{ |
809
|
0
|
|
|
|
|
0
|
$r = Apache2::RequestUtil->request; |
810
|
|
|
|
|
|
|
}; |
811
|
0
|
0
|
|
|
|
0
|
if( $@ ) |
812
|
|
|
|
|
|
|
{ |
813
|
0
|
|
|
|
|
0
|
$stderr_raw->print( "Error trying to get the global Apache2::ApacheRec: $@\n" ); |
814
|
|
|
|
|
|
|
} |
815
|
|
|
|
|
|
|
} |
816
|
|
|
|
|
|
|
|
817
|
0
|
|
|
|
|
0
|
my $ref; |
818
|
0
|
|
|
|
|
0
|
$ref = $self->message_check( @_ ); |
819
|
0
|
0
|
|
|
|
0
|
return(1) if( !$ref ); |
820
|
|
|
|
|
|
|
|
821
|
0
|
|
|
|
|
0
|
my $opts = {}; |
822
|
0
|
0
|
|
|
|
0
|
$opts = pop( @$ref ) if( ref( $ref->[-1] ) eq 'HASH' ); |
823
|
|
|
|
|
|
|
|
824
|
0
|
|
0
|
|
|
0
|
my $stackFrame = $self->message_frame( (caller(1))[3] ) || 1; |
825
|
0
|
0
|
|
|
|
0
|
$stackFrame = 1 unless( $stackFrame =~ /^\d+$/ ); |
826
|
0
|
0
|
|
|
|
0
|
$stackFrame-- if( $stackFrame ); |
827
|
0
|
0
|
0
|
|
|
0
|
$stackFrame++ if( ( (caller(1))[3] // '' ) eq 'HTTP::Promise::Headers::messagef' ); |
828
|
0
|
|
|
|
|
0
|
my( $pkg, $file, $line, @otherInfo ) = caller( $stackFrame ); |
829
|
0
|
|
0
|
|
|
0
|
my $sub = ( caller( $stackFrame + 1 ) )[3] // ''; |
830
|
0
|
|
|
|
|
0
|
my $sub2 = substr( $sub, rindex( $sub, '::' ) + 2 ); |
831
|
0
|
0
|
|
|
|
0
|
if( ref( $self->{_message_frame} ) eq 'HASH' ) |
832
|
|
|
|
|
|
|
{ |
833
|
0
|
0
|
|
|
|
0
|
if( exists( $self->{_message_frame}->{ $sub2 } ) ) |
834
|
|
|
|
|
|
|
{ |
835
|
0
|
|
|
|
|
0
|
my $frameNo = int( $self->{_message_frame}->{ $sub2 } ); |
836
|
0
|
0
|
|
|
|
0
|
if( $frameNo > 0 ) |
837
|
|
|
|
|
|
|
{ |
838
|
0
|
|
|
|
|
0
|
( $pkg, $file, $line, $sub ) = caller( $frameNo ); |
839
|
0
|
|
|
|
|
0
|
$sub2 = substr( $sub, rindex( $sub, '::' ) + 2 ); |
840
|
|
|
|
|
|
|
} |
841
|
|
|
|
|
|
|
} |
842
|
|
|
|
|
|
|
} |
843
|
0
|
0
|
|
|
|
0
|
if( $sub2 eq 'message' ) |
844
|
|
|
|
|
|
|
{ |
845
|
0
|
|
|
|
|
0
|
$stackFrame++; |
846
|
0
|
|
|
|
|
0
|
( $pkg, $file, $line, @otherInfo ) = caller( $stackFrame ); |
847
|
0
|
|
0
|
|
|
0
|
my $sub = ( caller( $stackFrame + 1 ) )[3] // ''; |
848
|
0
|
|
|
|
|
0
|
$sub2 = substr( $sub, rindex( $sub, '::' ) + 2 ); |
849
|
|
|
|
|
|
|
} |
850
|
0
|
|
|
|
|
0
|
my $txt; |
851
|
0
|
0
|
|
|
|
0
|
if( $opts->{message} ) |
852
|
|
|
|
|
|
|
{ |
853
|
0
|
0
|
|
|
|
0
|
if( ref( $opts->{message} ) eq 'ARRAY' ) |
854
|
|
|
|
|
|
|
{ |
855
|
0
|
0
|
0
|
|
|
0
|
$txt = join( '', map( ( ref( $_ ) eq 'CODE' && !$self->{_msg_no_exec_sub} ) ? $_->() : ( $_ // '' ), @{$opts->{message}} ) ); |
|
0
|
|
0
|
|
|
0
|
|
856
|
|
|
|
|
|
|
} |
857
|
|
|
|
|
|
|
else |
858
|
|
|
|
|
|
|
{ |
859
|
0
|
|
|
|
|
0
|
$txt = $opts->{message}; |
860
|
|
|
|
|
|
|
} |
861
|
|
|
|
|
|
|
} |
862
|
|
|
|
|
|
|
else |
863
|
|
|
|
|
|
|
{ |
864
|
0
|
0
|
0
|
|
|
0
|
$txt = join( '', map( ( ref( $_ ) eq 'CODE' && !$self->{_msg_no_exec_sub} ) ? $_->() : ( $_ // '' ), @$ref ) ); |
|
|
|
0
|
|
|
|
|
865
|
|
|
|
|
|
|
} |
866
|
|
|
|
|
|
|
# Reset it |
867
|
0
|
|
|
|
|
0
|
$self->{_msg_no_exec_sub} = 0; |
868
|
0
|
0
|
|
|
|
0
|
my $prefix = CORE::length( $opts->{prefix} ) ? $opts->{prefix} : '##'; |
869
|
14
|
|
|
14
|
|
113
|
no overloading; |
|
14
|
|
|
|
|
44
|
|
|
14
|
|
|
|
|
9305
|
|
870
|
0
|
0
|
0
|
|
|
0
|
$opts->{caller_info} = 1 if( !CORE::exists( $opts->{caller_info} ) || !CORE::length( $opts->{caller_info} ) ); |
871
|
0
|
|
|
|
|
0
|
my $proc_info = " [PID: $$]"; |
872
|
0
|
|
|
|
|
0
|
if( HAS_THREADS ) |
873
|
|
|
|
|
|
|
{ |
874
|
|
|
|
|
|
|
my $tid = threads->tid; |
875
|
|
|
|
|
|
|
$proc_info .= ' -> [thread id ' . $tid . ']' if( $tid ); |
876
|
|
|
|
|
|
|
} |
877
|
0
|
0
|
|
|
|
0
|
my $mesg_raw = $opts->{caller_info} ? ( "${pkg}::${sub2}( $self ) [$line]${proc_info}: " . $txt ) : $txt; |
878
|
0
|
|
|
|
|
0
|
$mesg_raw =~ s/\n$//gs; |
879
|
0
|
|
|
|
|
0
|
my $mesg = "${prefix} " . join( "\n${prefix} ", split( /\n/, $mesg_raw ) ); |
880
|
|
|
|
|
|
|
|
881
|
|
|
|
|
|
|
my $info = |
882
|
|
|
|
|
|
|
{ |
883
|
|
|
|
|
|
|
'formatted' => $mesg, |
884
|
|
|
|
|
|
|
'message' => $txt, |
885
|
|
|
|
|
|
|
'file' => $file, |
886
|
|
|
|
|
|
|
'line' => $line, |
887
|
|
|
|
|
|
|
'package' => $class, |
888
|
|
|
|
|
|
|
'sub' => $sub2, |
889
|
0
|
0
|
|
|
|
0
|
'level' => ( $_[0] =~ /^\d+$/ ? $_[0] : CORE::exists( $opts->{level} ) ? $opts->{level} : 0 ), |
|
|
0
|
|
|
|
|
|
890
|
|
|
|
|
|
|
}; |
891
|
0
|
0
|
|
|
|
0
|
$info->{type} = $opts->{type} if( $opts->{type} ); |
892
|
|
|
|
|
|
|
|
893
|
|
|
|
|
|
|
## If Mod perl is activated AND we are not using a private log |
894
|
0
|
0
|
0
|
|
|
0
|
if( $r && !${ "${class}::LOG_DEBUG" } ) |
|
0
|
0
|
0
|
|
|
0
|
|
|
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
895
|
|
|
|
|
|
|
{ |
896
|
0
|
0
|
0
|
|
|
0
|
if( my $log_handler = $r->get_handlers( 'PerlPrivateLogHandler' ) ) |
|
|
0
|
|
|
|
|
|
897
|
|
|
|
|
|
|
{ |
898
|
0
|
|
|
|
|
0
|
$log_handler->( $mesg_raw ); |
899
|
|
|
|
|
|
|
} |
900
|
|
|
|
|
|
|
elsif( $self->{_log_handler} && ref( $self->{_log_handler} ) eq 'CODE' ) |
901
|
|
|
|
|
|
|
{ |
902
|
0
|
|
|
|
|
0
|
$self->{_log_handler}->( $info ); |
903
|
|
|
|
|
|
|
} |
904
|
|
|
|
|
|
|
else |
905
|
|
|
|
|
|
|
{ |
906
|
0
|
|
|
|
|
0
|
$r->log->debug( $mesg_raw ); |
907
|
|
|
|
|
|
|
} |
908
|
|
|
|
|
|
|
} |
909
|
|
|
|
|
|
|
# Using ModPerl Server to log |
910
|
0
|
|
|
|
|
0
|
elsif( $MOD_PERL && !${ "${class}::LOG_DEBUG" } ) |
911
|
|
|
|
|
|
|
{ |
912
|
0
|
|
|
|
|
0
|
require Apache2::ServerUtil; |
913
|
0
|
|
|
|
|
0
|
my $s = Apache2::ServerUtil->server; |
914
|
0
|
|
|
|
|
0
|
$s->log->debug( $mesg ); |
915
|
|
|
|
|
|
|
} |
916
|
|
|
|
|
|
|
# e.g. in our package, we could set the handler using the curry module like $self->{_log_handler} = $self->curry::log |
917
|
|
|
|
|
|
|
elsif( !-t( STDIN ) && $self->{_log_handler} && ref( $self->{_log_handler} ) eq 'CODE' ) |
918
|
|
|
|
|
|
|
{ |
919
|
0
|
|
|
|
|
0
|
$self->{_log_handler}->( $info ); |
920
|
|
|
|
|
|
|
} |
921
|
0
|
|
|
|
|
0
|
elsif( !-t( STDIN ) && ${ $class . '::MESSAGE_HANDLER' } && ref( ${ $class . '::MESSAGE_HANDLER' } ) eq 'CODE' ) |
|
0
|
|
|
|
|
0
|
|
922
|
|
|
|
|
|
|
{ |
923
|
0
|
|
|
|
|
0
|
my $h = ${ $class . '::MESSAGE_HANDLER' }; |
|
0
|
|
|
|
|
0
|
|
924
|
0
|
|
|
|
|
0
|
$h->( $info ); |
925
|
|
|
|
|
|
|
} |
926
|
|
|
|
|
|
|
# Otherwise just on the stderr |
927
|
|
|
|
|
|
|
else |
928
|
|
|
|
|
|
|
{ |
929
|
0
|
0
|
|
|
|
0
|
if( $opts->{no_encoding} ) |
930
|
|
|
|
|
|
|
{ |
931
|
0
|
|
|
|
|
0
|
$stderr_raw->print( $mesg, "\n" ); |
932
|
|
|
|
|
|
|
} |
933
|
|
|
|
|
|
|
else |
934
|
|
|
|
|
|
|
{ |
935
|
0
|
|
|
|
|
0
|
$stderr->print( $mesg, "\n" ); |
936
|
|
|
|
|
|
|
} |
937
|
|
|
|
|
|
|
} |
938
|
|
|
|
|
|
|
} |
939
|
0
|
|
|
|
|
0
|
return(1); |
940
|
|
|
|
|
|
|
} |
941
|
|
|
|
|
|
|
|
942
|
|
|
|
|
|
|
sub message_check |
943
|
|
|
|
|
|
|
{ |
944
|
0
|
|
|
0
|
0
|
0
|
my $self = shift( @_ ); |
945
|
0
|
|
0
|
|
|
0
|
my $class = ref( $self ) || $self; |
946
|
14
|
|
|
14
|
|
119
|
no warnings 'uninitialized'; |
|
14
|
|
|
|
|
32
|
|
|
14
|
|
|
|
|
611
|
|
947
|
14
|
|
|
14
|
|
81
|
no strict 'refs'; |
|
14
|
|
|
|
|
29
|
|
|
14
|
|
|
|
|
26344
|
|
948
|
0
|
0
|
|
|
|
0
|
if( @_ ) |
949
|
|
|
|
|
|
|
{ |
950
|
0
|
0
|
|
|
|
0
|
if( $_[0] !~ /^\d/ ) |
951
|
|
|
|
|
|
|
{ |
952
|
|
|
|
|
|
|
# The last parameter is an options parameter which has the level property set |
953
|
0
|
0
|
0
|
|
|
0
|
if( ref( $_[-1] ) eq 'HASH' && CORE::exists( $_[-1]->{level} ) ) |
|
|
0
|
0
|
|
|
|
|
954
|
|
|
|
|
|
|
{ |
955
|
|
|
|
|
|
|
# Then let's use this |
956
|
|
|
|
|
|
|
} |
957
|
|
|
|
|
|
|
elsif( $self->{_message_default_level} =~ /^\d+$/ && |
958
|
|
|
|
|
|
|
$self->{_message_default_level} > 0 ) |
959
|
|
|
|
|
|
|
{ |
960
|
0
|
|
|
|
|
0
|
unshift( @_, $self->{_message_default_level} ); |
961
|
|
|
|
|
|
|
} |
962
|
|
|
|
|
|
|
else |
963
|
|
|
|
|
|
|
{ |
964
|
0
|
|
|
|
|
0
|
unshift( @_, 1 ); |
965
|
|
|
|
|
|
|
} |
966
|
|
|
|
|
|
|
} |
967
|
|
|
|
|
|
|
# If the first argument looks line a number, and there is more than 1 argument |
968
|
|
|
|
|
|
|
# and it is greater than 1, and greater than our current debug level |
969
|
|
|
|
|
|
|
# well, we do not output anything then... |
970
|
0
|
0
|
0
|
|
|
0
|
if( ( $_[0] =~ /^\d+$/ || |
|
|
|
0
|
|
|
|
|
971
|
|
|
|
|
|
|
( ref( $_[-1] ) eq 'HASH' && |
972
|
|
|
|
|
|
|
CORE::exists( $_[-1]->{level} ) && |
973
|
|
|
|
|
|
|
$_[-1]->{level} =~ /^\d+$/ |
974
|
|
|
|
|
|
|
) |
975
|
|
|
|
|
|
|
) && @_ > 1 ) |
976
|
|
|
|
|
|
|
{ |
977
|
0
|
|
|
|
|
0
|
my $message_level = 0; |
978
|
0
|
0
|
0
|
|
|
0
|
if( $_[0] =~ /^\d+$/ ) |
|
|
0
|
|
|
|
|
|
979
|
|
|
|
|
|
|
{ |
980
|
0
|
|
|
|
|
0
|
$message_level = shift( @_ ); |
981
|
|
|
|
|
|
|
} |
982
|
|
|
|
|
|
|
elsif( ref( $_[-1] ) eq 'HASH' && CORE::exists( $_[-1]->{level} ) ) |
983
|
|
|
|
|
|
|
{ |
984
|
0
|
|
|
|
|
0
|
$message_level = $_[-1]->{level}; |
985
|
|
|
|
|
|
|
} |
986
|
0
|
|
|
|
|
0
|
my $target_re = ''; |
987
|
0
|
0
|
|
|
|
0
|
if( ref( ${ "${class}::DEBUG_TARGET" } ) eq 'ARRAY' ) |
|
0
|
|
|
|
|
0
|
|
988
|
|
|
|
|
|
|
{ |
989
|
0
|
0
|
|
|
|
0
|
$target_re = scalar( @${ "${class}::DEBUG_TARGET" } ) ? join( '|', @${ "${class}::DEBUG_TARGET" } ) : ''; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
990
|
|
|
|
|
|
|
} |
991
|
0
|
0
|
0
|
|
|
0
|
if( int( $self->{debug} ) >= $message_level || |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
992
|
|
|
|
|
|
|
int( $self->{verbose} ) >= $message_level || |
993
|
0
|
|
|
|
|
0
|
( defined( ${ $class . '::DEBUG' } ) && ${ $class . '::DEBUG' } >= $message_level ) || |
|
0
|
|
|
|
|
0
|
|
994
|
|
|
|
|
|
|
int( $self->{debug_level} ) >= $message_level || |
995
|
|
|
|
|
|
|
int( $self->{debug} ) >= 100 || |
996
|
0
|
|
|
|
|
0
|
( length( $target_re ) && $class =~ /^$target_re$/ && ${ $class . '::GLOBAL_DEBUG' } >= $message_level ) ) |
997
|
|
|
|
|
|
|
{ |
998
|
0
|
|
|
|
|
0
|
return( [ @_ ] ); |
999
|
|
|
|
|
|
|
} |
1000
|
|
|
|
|
|
|
else |
1001
|
|
|
|
|
|
|
{ |
1002
|
0
|
|
|
|
|
0
|
return(0); |
1003
|
|
|
|
|
|
|
} |
1004
|
|
|
|
|
|
|
} |
1005
|
|
|
|
|
|
|
} |
1006
|
0
|
|
|
|
|
0
|
return(0); |
1007
|
|
|
|
|
|
|
} |
1008
|
|
|
|
|
|
|
|
1009
|
|
|
|
|
|
|
sub message_frame |
1010
|
|
|
|
|
|
|
{ |
1011
|
0
|
|
|
0
|
0
|
0
|
my $self = shift( @_ ); |
1012
|
0
|
0
|
|
|
|
0
|
$self->{_message_frame } = {} if( !exists( $self->{_message_frame} ) ); |
1013
|
0
|
|
|
|
|
0
|
my $mf = $self->{_message_frame}; |
1014
|
0
|
0
|
|
|
|
0
|
if( @_ ) |
1015
|
|
|
|
|
|
|
{ |
1016
|
0
|
|
|
|
|
0
|
my $args = {}; |
1017
|
0
|
0
|
|
|
|
0
|
if( ref( $_[0] ) eq 'HASH' ) |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1018
|
|
|
|
|
|
|
{ |
1019
|
0
|
|
|
|
|
0
|
$args = shift( @_ ); |
1020
|
0
|
|
|
|
|
0
|
my @k = keys( %$args ); |
1021
|
0
|
|
|
|
|
0
|
@$mf{ @k } = @$args{ @k }; |
1022
|
|
|
|
|
|
|
} |
1023
|
|
|
|
|
|
|
elsif( !( @_ % 2 ) ) |
1024
|
|
|
|
|
|
|
{ |
1025
|
0
|
|
|
|
|
0
|
$args = { @_ }; |
1026
|
0
|
|
|
|
|
0
|
my @k = keys( %$args ); |
1027
|
0
|
|
|
|
|
0
|
@$mf{ @k } = @$args{ @k }; |
1028
|
|
|
|
|
|
|
} |
1029
|
|
|
|
|
|
|
elsif( scalar( @_ ) == 1 ) |
1030
|
|
|
|
|
|
|
{ |
1031
|
0
|
|
|
|
|
0
|
my $sub = shift( @_ ); |
1032
|
0
|
0
|
|
|
|
0
|
$sub = substr( $sub, rindex( $sub, '::' ) + 2 ) if( index( $sub, '::' ) != -1 ); |
1033
|
0
|
|
|
|
|
0
|
return( $mf->{ $sub } ); |
1034
|
|
|
|
|
|
|
} |
1035
|
|
|
|
|
|
|
else |
1036
|
|
|
|
|
|
|
{ |
1037
|
0
|
|
|
|
|
0
|
return( $self->error( "I was expecting a key => value pair such as routine => stack frame (integer)" ) ); |
1038
|
|
|
|
|
|
|
} |
1039
|
|
|
|
|
|
|
} |
1040
|
0
|
|
|
|
|
0
|
return( $mf ); |
1041
|
|
|
|
|
|
|
} |
1042
|
|
|
|
|
|
|
|
1043
|
|
|
|
|
|
|
# For compatibility for MIME::Decoder->head, itself used by HTTP::Promise::Entity |
1044
|
|
|
|
|
|
|
# "some decoders need to know a little about the file they are encoding/decoding; e.g., x-uu likes to have the filename. The HEAD is any object which responds to messages like: |
1045
|
|
|
|
|
|
|
# $head->mime_attr( 'content-disposition.filename' ); |
1046
|
|
|
|
|
|
|
sub mime_attr |
1047
|
|
|
|
|
|
|
{ |
1048
|
10
|
|
|
10
|
1
|
446
|
my $self = shift( @_ ); |
1049
|
10
|
|
|
|
|
55
|
my( $attr, $value ) = @_; |
1050
|
10
|
50
|
33
|
|
|
130
|
return if( !defined( $attr ) || !length( $attr ) ); |
1051
|
|
|
|
|
|
|
# Break attribute name up |
1052
|
10
|
|
|
|
|
75
|
my( $tag, $subtag ) = split( /\./, $attr, 2 ); |
1053
|
10
|
|
|
|
|
59
|
my $v = $self->header( $tag ); |
1054
|
10
|
|
|
|
|
99
|
require Module::Generic::HeaderValue; |
1055
|
10
|
|
|
|
|
28
|
my $hv; |
1056
|
10
|
50
|
33
|
|
|
63
|
if( defined( $v ) && length( $v ) ) |
1057
|
|
|
|
|
|
|
{ |
1058
|
10
|
|
|
|
|
65
|
$hv = Module::Generic::HeaderValue->new_from_header( $v ); |
1059
|
10
|
50
|
|
|
|
61015
|
return( $self->pass_error( Module::Generic::HeaderValue->error ) ) if( !defined( $hv ) ); |
1060
|
|
|
|
|
|
|
} |
1061
|
10
|
50
|
|
|
|
54
|
if( scalar( @_ ) > 1 ) |
1062
|
|
|
|
|
|
|
{ |
1063
|
0
|
0
|
|
|
|
0
|
if( defined( $subtag ) ) |
1064
|
|
|
|
|
|
|
{ |
1065
|
0
|
0
|
|
|
|
0
|
return( $self->error( "There is no header field '$tag' currently set, so you cannot assign a value for '$subtag'." ) ) if( !defined( $hv ) ); |
1066
|
0
|
|
|
|
|
0
|
$hv->param( $subtag => $value ); |
1067
|
|
|
|
|
|
|
} |
1068
|
|
|
|
|
|
|
else |
1069
|
|
|
|
|
|
|
{ |
1070
|
0
|
0
|
|
|
|
0
|
if( defined( $hv ) ) |
1071
|
|
|
|
|
|
|
{ |
1072
|
0
|
|
|
|
|
0
|
$hv->value( $value ); |
1073
|
|
|
|
|
|
|
} |
1074
|
|
|
|
|
|
|
else |
1075
|
|
|
|
|
|
|
{ |
1076
|
0
|
|
0
|
|
|
0
|
$hv = Module::Generic::HeaderValue->new( $value ) || |
1077
|
|
|
|
|
|
|
return( $self->pass_error( Module::Generic::HeaderValue->error ) ); |
1078
|
|
|
|
|
|
|
} |
1079
|
|
|
|
|
|
|
} |
1080
|
0
|
|
|
|
|
0
|
$self->replace( $tag => "$hv" ); |
1081
|
0
|
|
|
|
|
0
|
return( $value ); |
1082
|
|
|
|
|
|
|
} |
1083
|
|
|
|
|
|
|
else |
1084
|
|
|
|
|
|
|
{ |
1085
|
10
|
50
|
|
|
|
40
|
return( '' ) if( !defined( $hv ) ); |
1086
|
10
|
100
|
|
|
|
59
|
return( defined( $subtag ) ? $hv->param( $subtag ) : $hv->value_data ); |
1087
|
|
|
|
|
|
|
} |
1088
|
|
|
|
|
|
|
} |
1089
|
|
|
|
|
|
|
|
1090
|
|
|
|
|
|
|
# In HTTP parlance, the request may contain a Content-Encoding in multipart/form-data, |
1091
|
|
|
|
|
|
|
# and the server response may contain Transfer-Encoding to indicate in which encoding the |
1092
|
|
|
|
|
|
|
# response is provided. |
1093
|
|
|
|
|
|
|
sub mime_encoding |
1094
|
|
|
|
|
|
|
{ |
1095
|
2
|
|
|
2
|
1
|
58
|
my $self = shift( @_ ); |
1096
|
2
|
|
33
|
|
|
25
|
my $te = $self->header( 'Content-Encoding' ) || $self->header( 'Transfer-Encoding' ); |
1097
|
2
|
50
|
33
|
|
|
22
|
return( '' ) if( !defined( $te ) || !length( $te ) ); |
1098
|
0
|
|
|
|
|
0
|
my $enc = lc( $te ); |
1099
|
|
|
|
|
|
|
# 7-bit, 7_bit -> 7bit. Same for 8-bit, 8_bit |
1100
|
0
|
|
|
|
|
0
|
$enc =~ s{^([78])[ _-]bit\Z}{$1bit}; |
1101
|
0
|
|
|
|
|
0
|
return( $enc ); |
1102
|
|
|
|
|
|
|
} |
1103
|
|
|
|
|
|
|
|
1104
|
|
|
|
|
|
|
sub mime_type |
1105
|
|
|
|
|
|
|
{ |
1106
|
115
|
|
|
115
|
1
|
469
|
my $self = shift( @_ ); |
1107
|
115
|
|
66
|
|
|
1011
|
my $default = shift( @_ ) || $self->default_type; |
1108
|
115
|
|
|
|
|
535
|
my $ct = $self->type; |
1109
|
115
|
100
|
66
|
|
|
544
|
if( !defined( $ct ) || !length( $ct ) ) |
1110
|
|
|
|
|
|
|
{ |
1111
|
52
|
100
|
|
|
|
179
|
return( $default ) if( defined( $default ) ); |
1112
|
49
|
|
|
|
|
241
|
return( '' ); |
1113
|
|
|
|
|
|
|
} |
1114
|
63
|
|
|
|
|
1597
|
return( $ct ); |
1115
|
|
|
|
|
|
|
} |
1116
|
|
|
|
|
|
|
|
1117
|
|
|
|
|
|
|
sub multipart_boundary |
1118
|
|
|
|
|
|
|
{ |
1119
|
17
|
|
|
17
|
1
|
278
|
my $self = shift( @_ ); |
1120
|
17
|
|
|
|
|
76
|
my $ct = $self->content_type; |
1121
|
17
|
50
|
33
|
|
|
403
|
return( '' ) unless( defined( $ct ) && length( "$ct" ) ); |
1122
|
|
|
|
|
|
|
# There is no attributes to this Content-Type, so no need to go further. |
1123
|
17
|
100
|
66
|
|
|
183
|
return( '' ) if( index( $ct, ';' ) == -1 || index( $ct, 'boundary' ) == -1 ); |
1124
|
15
|
|
|
|
|
389
|
require Module::Generic::HeaderValue; |
1125
|
15
|
|
50
|
|
|
179
|
my $hv = Module::Generic::HeaderValue->new_from_header( $ct ) || |
1126
|
|
|
|
|
|
|
return( $self->pass_error( Module::Generic::HeaderValue->error ) ); |
1127
|
15
|
|
|
|
|
96551
|
my $boundary = $hv->param( 'boundary' ); |
1128
|
15
|
|
|
|
|
8506
|
return( $boundary ); |
1129
|
|
|
|
|
|
|
} |
1130
|
|
|
|
|
|
|
|
1131
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/NEL> |
1132
|
0
|
|
|
0
|
1
|
0
|
sub nel { return( shift->_set_get_one( 'NEL', @_ ) ); } |
1133
|
|
|
|
|
|
|
|
1134
|
|
|
|
|
|
|
sub new_array |
1135
|
|
|
|
|
|
|
{ |
1136
|
59
|
|
|
59
|
0
|
120
|
my $self = shift( @_ ); |
1137
|
59
|
|
|
|
|
400
|
require Module::Generic::Array; |
1138
|
59
|
|
|
|
|
231
|
return( Module::Generic::Array->new( @_ ) ); |
1139
|
|
|
|
|
|
|
} |
1140
|
|
|
|
|
|
|
|
1141
|
|
|
|
|
|
|
sub new_field |
1142
|
|
|
|
|
|
|
{ |
1143
|
94
|
|
|
94
|
0
|
10676
|
my $self = shift( @_ ); |
1144
|
94
|
|
|
|
|
361
|
my $field = shift( @_ ); |
1145
|
94
|
50
|
33
|
|
|
959
|
return( $self->error( "No header field name was provided." ) ) if( !defined( $field ) || !length( "$field" ) ); |
1146
|
94
|
50
|
|
|
|
467
|
unless( scalar( keys( %$SUPPORTED ) ) ) |
1147
|
|
|
|
|
|
|
{ |
1148
|
0
|
0
|
|
|
|
0
|
$self->_load_class( 'Module::Generic::File' ) || return( $self->pass_error ); |
1149
|
0
|
|
0
|
|
|
0
|
my $dir = Module::Generic::File->new( ( $MOD_PATH || __FILE__ ) )->extension( undef ); |
1150
|
0
|
0
|
|
|
|
0
|
$dir->open || return( $self->error( "Unable to open directory \"$dir\": ", $dir->error ) ); |
1151
|
0
|
|
|
|
|
0
|
my $f; |
1152
|
0
|
|
|
|
|
0
|
while( defined( $f = $dir->read( exclude_invisible => 1, as_object => 1 ) ) ) |
1153
|
|
|
|
|
|
|
{ |
1154
|
0
|
0
|
|
|
|
0
|
next if( $f->extension ne 'pm' ); |
1155
|
0
|
|
|
|
|
0
|
my $base = $f->basename( '.pm' ); |
1156
|
0
|
|
|
|
|
0
|
$SUPPORTED->{ lc( $base ) } = "HTTP\::Promise\::Headers\::${base}"; |
1157
|
|
|
|
|
|
|
} |
1158
|
|
|
|
|
|
|
} |
1159
|
94
|
|
|
|
|
839
|
( my $name = $field ) =~ s/[\-_]+//g; |
1160
|
94
|
|
|
|
|
304
|
$name = lc( $name ); |
1161
|
94
|
50
|
|
|
|
399
|
return( $self->error( "Unsupported field \"$field\"." ) ) if( !exists( $SUPPORTED->{ $name } ) ); |
1162
|
94
|
|
|
|
|
359
|
my $class = $SUPPORTED->{ $name }; |
1163
|
94
|
50
|
|
|
|
484
|
$self->_load_class( $class ) || return( $self->pass_error ); |
1164
|
94
|
|
50
|
|
|
681
|
my $o = $class->new( @_ ) || |
1165
|
|
|
|
|
|
|
return( $self->pass_error( $class->error ) ); |
1166
|
94
|
|
|
|
|
316
|
return( $o ); |
1167
|
|
|
|
|
|
|
} |
1168
|
|
|
|
|
|
|
|
1169
|
|
|
|
|
|
|
sub new_number |
1170
|
|
|
|
|
|
|
{ |
1171
|
1
|
|
|
1
|
0
|
2
|
my $self = shift( @_ ); |
1172
|
1
|
|
|
|
|
7
|
require Module::Generic::Number; |
1173
|
1
|
|
|
|
|
6
|
return( Module::Generic::Number->new( @_ ) ); |
1174
|
|
|
|
|
|
|
} |
1175
|
|
|
|
|
|
|
|
1176
|
|
|
|
|
|
|
sub new_scalar |
1177
|
|
|
|
|
|
|
{ |
1178
|
346
|
|
|
346
|
0
|
428730
|
my $self = shift( @_ ); |
1179
|
346
|
|
|
|
|
3206
|
require Module::Generic::Scalar; |
1180
|
346
|
|
|
|
|
48594
|
return( Module::Generic::Scalar->new( @_ ) ); |
1181
|
|
|
|
|
|
|
} |
1182
|
|
|
|
|
|
|
|
1183
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin> |
1184
|
0
|
|
|
0
|
1
|
0
|
sub origin { return( shift->_set_get_one_uri( 'Origin', @_ ) ); } |
1185
|
|
|
|
|
|
|
|
1186
|
|
|
|
|
|
|
# Copied from Module::Generic to avoid loading it |
1187
|
|
|
|
|
|
|
sub pass_error |
1188
|
|
|
|
|
|
|
{ |
1189
|
0
|
|
|
0
|
0
|
0
|
my $self = shift( @_ ); |
1190
|
0
|
|
0
|
|
|
0
|
my $pack = ref( $self ) || $self; |
1191
|
0
|
|
|
|
|
0
|
my $opts = {}; |
1192
|
0
|
|
|
|
|
0
|
my $err; |
1193
|
|
|
|
|
|
|
my $class; |
1194
|
14
|
|
|
14
|
|
161
|
no strict 'refs'; |
|
14
|
|
|
|
|
39
|
|
|
14
|
|
|
|
|
44072
|
|
1195
|
0
|
0
|
|
|
|
0
|
if( scalar( @_ ) ) |
1196
|
|
|
|
|
|
|
{ |
1197
|
|
|
|
|
|
|
# Either an hash defining a new error and this will be passed along to error(); or |
1198
|
|
|
|
|
|
|
# an hash with a single property: { class => 'Some::ExceptionClass' } |
1199
|
0
|
0
|
0
|
|
|
0
|
if( scalar( @_ ) == 1 && ref( $_[0] ) eq 'HASH' ) |
1200
|
|
|
|
|
|
|
{ |
1201
|
0
|
|
|
|
|
0
|
$opts = $_[0]; |
1202
|
|
|
|
|
|
|
} |
1203
|
|
|
|
|
|
|
else |
1204
|
|
|
|
|
|
|
{ |
1205
|
|
|
|
|
|
|
# $self->pass_error( $error_object, { class => 'Some::ExceptionClass' } ); |
1206
|
0
|
0
|
0
|
|
|
0
|
if( scalar( @_ ) > 1 && ref( $_[-1] ) eq 'HASH' ) |
1207
|
|
|
|
|
|
|
{ |
1208
|
0
|
|
|
|
|
0
|
$opts = pop( @_ ); |
1209
|
|
|
|
|
|
|
} |
1210
|
0
|
|
|
|
|
0
|
$err = $_[0]; |
1211
|
|
|
|
|
|
|
} |
1212
|
|
|
|
|
|
|
} |
1213
|
|
|
|
|
|
|
# We set $class only if the hash provided is a one-element hash and not an error-defining hash |
1214
|
0
|
0
|
0
|
|
|
0
|
$class = CORE::delete( $opts->{class} ) if( scalar( keys( %$opts ) ) == 1 && [keys( %$opts )]->[0] eq 'class' ); |
1215
|
|
|
|
|
|
|
|
1216
|
|
|
|
|
|
|
# called with no argument, most likely from the same class to pass on an error |
1217
|
|
|
|
|
|
|
# set up earlier by another method; or |
1218
|
|
|
|
|
|
|
# with an hash containing just one argument class => 'Some::ExceptionClass' |
1219
|
0
|
0
|
0
|
|
|
0
|
if( !defined( $err ) && ( !scalar( @_ ) || defined( $class ) ) ) |
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
1220
|
|
|
|
|
|
|
{ |
1221
|
0
|
0
|
|
|
|
0
|
if( !defined( $self->{error} ) ) |
1222
|
|
|
|
|
|
|
{ |
1223
|
0
|
|
|
|
|
0
|
warn( "No error object provided and no previous error set either! It seems the previous method call returned a simple undef\n" ); |
1224
|
|
|
|
|
|
|
} |
1225
|
|
|
|
|
|
|
else |
1226
|
|
|
|
|
|
|
{ |
1227
|
0
|
0
|
|
|
|
0
|
$err = ( defined( $class ) ? bless( $self->{error} => $class ) : $self->{error} ); |
1228
|
|
|
|
|
|
|
} |
1229
|
|
|
|
|
|
|
} |
1230
|
|
|
|
|
|
|
elsif( defined( $err ) && |
1231
|
|
|
|
|
|
|
Scalar::Util::blessed( $err ) && |
1232
|
|
|
|
|
|
|
( scalar( @_ ) == 1 || |
1233
|
|
|
|
|
|
|
( scalar( @_ ) == 2 && defined( $class ) ) |
1234
|
|
|
|
|
|
|
) ) |
1235
|
|
|
|
|
|
|
{ |
1236
|
0
|
0
|
|
|
|
0
|
$self->{error} = ${ $pack . '::ERROR' } = ( defined( $class ) ? bless( $err => $class ) : $err ); |
|
0
|
|
|
|
|
0
|
|
1237
|
|
|
|
|
|
|
} |
1238
|
|
|
|
|
|
|
# If the error provided is not an object, we call error to create one |
1239
|
|
|
|
|
|
|
else |
1240
|
|
|
|
|
|
|
{ |
1241
|
0
|
|
|
|
|
0
|
return( $self->error( @_ ) ); |
1242
|
|
|
|
|
|
|
} |
1243
|
|
|
|
|
|
|
|
1244
|
0
|
0
|
|
|
|
0
|
if( want( 'OBJECT' ) ) |
1245
|
|
|
|
|
|
|
{ |
1246
|
0
|
|
|
|
|
0
|
require Module::Generic::Null; |
1247
|
0
|
|
|
|
|
0
|
my $null = Module::Generic::Null->new( $err, { debug => $self->{debug}, has_error => 1 }); |
1248
|
0
|
|
|
|
|
0
|
rreturn( $null ); |
1249
|
|
|
|
|
|
|
} |
1250
|
0
|
|
|
|
|
0
|
my $wantarray = wantarray(); |
1251
|
0
|
0
|
|
|
|
0
|
if( $self->debug ) |
1252
|
|
|
|
|
|
|
{ |
1253
|
0
|
|
|
|
|
0
|
my $caller = [caller(1)]; |
1254
|
|
|
|
|
|
|
} |
1255
|
0
|
|
|
|
|
0
|
return; |
1256
|
|
|
|
|
|
|
} |
1257
|
|
|
|
|
|
|
|
1258
|
|
|
|
|
|
|
sub print |
1259
|
|
|
|
|
|
|
{ |
1260
|
59
|
|
|
59
|
1
|
1716
|
my $self = shift( @_ ); |
1261
|
59
|
|
|
|
|
136
|
my $fh = shift( @_ ); |
1262
|
59
|
|
|
|
|
363
|
my $opts = $self->_get_args_as_hash( @_ ); |
1263
|
59
|
|
50
|
|
|
1300
|
my $eol = $opts->{eol} || CRLF; |
1264
|
59
|
|
33
|
|
|
193
|
$fh ||= select; |
1265
|
59
|
50
|
33
|
|
|
338
|
return( $self->error( "Filehandle provided ($fh) is not a proper filehandle and its not a HTTP::Promise::IO object." ) ) if( !$self->_is_glob( $fh ) && !$self->_is_a( $fh => 'HTTP::Promise::IO' ) ); |
1266
|
59
|
|
|
|
|
431
|
return( $fh->print( $self->as_string( $eol ) ) ); |
1267
|
|
|
|
|
|
|
} |
1268
|
|
|
|
|
|
|
|
1269
|
0
|
|
|
0
|
1
|
0
|
sub proxy { return( shift->_set_get_uri( 'proxy', @_ ) ); } |
1270
|
|
|
|
|
|
|
|
1271
|
|
|
|
|
|
|
# NOTE: proxy_authenticate() is inherited |
1272
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Proxy-Authenticate> |
1273
|
3
|
|
|
3
|
1
|
653
|
sub proxy_authenticate { return( shift->_set_get_one( 'Proxy-Authenticate', @_ ) ); } |
1274
|
|
|
|
|
|
|
|
1275
|
|
|
|
|
|
|
# NOTE: proxy_authorization() is inherited |
1276
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Proxy-Authorization> |
1277
|
1
|
|
|
1
|
1
|
549
|
sub proxy_authorization { return( shift->_set_get_one( 'Proxy-Authorization', @_ ) ); } |
1278
|
|
|
|
|
|
|
|
1279
|
|
|
|
|
|
|
# NOTE: proxy_authorization_basic() is inherited |
1280
|
|
|
|
|
|
|
|
1281
|
|
|
|
|
|
|
# NOTE: push_header() is inherited |
1282
|
|
|
|
|
|
|
|
1283
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range> |
1284
|
0
|
|
|
0
|
1
|
0
|
sub range { return( shift->_set_get_multi( 'Range', @_ ) ); } |
1285
|
|
|
|
|
|
|
|
1286
|
|
|
|
|
|
|
sub recommended_filename |
1287
|
|
|
|
|
|
|
{ |
1288
|
1
|
|
|
1
|
1
|
42
|
my $self = shift( @_ ); |
1289
|
1
|
|
|
|
|
9
|
foreach my $attr_name ( qw( content-disposition.filename* content-disposition.filename content-type.name ) ) |
1290
|
|
|
|
|
|
|
{ |
1291
|
2
|
|
|
|
|
13
|
my $value = $self->mime_attr( $attr_name ); |
1292
|
2
|
50
|
66
|
|
|
1069
|
if( defined( $value ) && |
|
|
|
66
|
|
|
|
|
1293
|
|
|
|
|
|
|
$value ne '' && |
1294
|
|
|
|
|
|
|
$value =~ /\S/ ) |
1295
|
|
|
|
|
|
|
{ |
1296
|
1
|
|
|
|
|
19
|
return( $self->decode_filename( $value ) ); |
1297
|
|
|
|
|
|
|
} |
1298
|
|
|
|
|
|
|
} |
1299
|
0
|
|
|
|
|
0
|
return; |
1300
|
|
|
|
|
|
|
} |
1301
|
|
|
|
|
|
|
|
1302
|
|
|
|
|
|
|
# NOTE: referer() and referrer() are inherited |
1303
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer> |
1304
|
9
|
|
|
9
|
1
|
661
|
sub referer { return( shift->_set_get_one_uri( 'Referer', @_ ) ); } |
1305
|
|
|
|
|
|
|
|
1306
|
3
|
|
|
3
|
1
|
587
|
sub referrer { return( shift->referer( @_ ) ); } |
1307
|
|
|
|
|
|
|
|
1308
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy> |
1309
|
0
|
|
|
0
|
1
|
0
|
sub referrer_policy { return( shift->_set_get_one( 'Referrer-Policy', @_ ) ); } |
1310
|
|
|
|
|
|
|
|
1311
|
18
|
|
|
18
|
1
|
639
|
sub remove { return( shift->remove_header( @_ ) ); } |
1312
|
|
|
|
|
|
|
|
1313
|
|
|
|
|
|
|
# NOTE: remove_header() is inherited |
1314
|
|
|
|
|
|
|
|
1315
|
|
|
|
|
|
|
# NOTE: remove_content_headers() is inherited |
1316
|
|
|
|
|
|
|
|
1317
|
|
|
|
|
|
|
sub replace |
1318
|
|
|
|
|
|
|
{ |
1319
|
30
|
|
|
30
|
1
|
6901042
|
my $self = shift( @_ ); |
1320
|
30
|
|
|
|
|
249
|
my( $field, $value ) = @_; |
1321
|
30
|
|
|
|
|
650
|
$self->header( $field => $value ); |
1322
|
30
|
|
|
|
|
146
|
return( $self ); |
1323
|
|
|
|
|
|
|
} |
1324
|
|
|
|
|
|
|
|
1325
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Request-Headers> |
1326
|
0
|
|
|
0
|
1
|
0
|
sub request_headers { return( shift->_set_get_one( 'Access-Control-Request-Headers', @_ ) ); } |
1327
|
|
|
|
|
|
|
|
1328
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Request-Method> |
1329
|
0
|
|
|
0
|
1
|
0
|
sub request_method { return( shift->_set_get_one( 'Access-Control-Request-Method', @_ ) ); } |
1330
|
|
|
|
|
|
|
|
1331
|
0
|
|
|
0
|
1
|
0
|
sub request_timeout { return( shift->_set_get_number( 'request_timeout', @_ ) ); } |
1332
|
|
|
|
|
|
|
|
1333
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After> |
1334
|
0
|
|
|
0
|
1
|
0
|
sub retry_after { return( shift->_set_get_one( 'Retry-After', @_ ) ); } |
1335
|
|
|
|
|
|
|
|
1336
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Save-Data> |
1337
|
0
|
|
|
0
|
1
|
0
|
sub save_data { return( shift->_set_get_one( 'Save-Data', @_ ) ); } |
1338
|
|
|
|
|
|
|
|
1339
|
|
|
|
|
|
|
# NOTE: scan() is inherited |
1340
|
|
|
|
|
|
|
|
1341
|
|
|
|
|
|
|
# NOTE: server() is inherited |
1342
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server> |
1343
|
3
|
|
|
3
|
1
|
623
|
sub server { return( shift->_set_get_one( 'Server', @_ ) ); } |
1344
|
|
|
|
|
|
|
|
1345
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server-Timing> |
1346
|
0
|
|
|
0
|
1
|
0
|
sub server_timing { return( shift->_set_get_one( 'Server-Timing', @_ ) ); } |
1347
|
|
|
|
|
|
|
|
1348
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie> |
1349
|
0
|
|
|
0
|
1
|
0
|
sub set_cookie { return( shift->_set_get_one( 'Set-Cookie', @_ ) ); } |
1350
|
|
|
|
|
|
|
|
1351
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/SourceMap> |
1352
|
0
|
|
|
0
|
1
|
0
|
sub sourcemap { return( shift->_set_get_one( 'SourceMap', @_ ) ); } |
1353
|
|
|
|
|
|
|
|
1354
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security> |
1355
|
0
|
|
|
0
|
1
|
0
|
sub strict_transport_security { return( shift->_set_get_one( 'Strict-Transport-Security', @_ ) ); } |
1356
|
|
|
|
|
|
|
|
1357
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/TE> |
1358
|
0
|
|
|
0
|
1
|
0
|
sub te { return( shift->_set_get_one( 'TE', @_ ) ); } |
1359
|
|
|
|
|
|
|
|
1360
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Timing-Allow-Origin> |
1361
|
0
|
|
|
0
|
1
|
0
|
sub timing_allow_origin { return( shift->_set_get_multi( 'Timing-Allow-Origin', @_ ) ); } |
1362
|
|
|
|
|
|
|
|
1363
|
|
|
|
|
|
|
# NOTE: title() is inherited and sucks really |
1364
|
3
|
|
|
3
|
1
|
622
|
sub title { return( shift->_set_get_one( 'Title', @_ ) ); } |
1365
|
|
|
|
|
|
|
|
1366
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Tk> |
1367
|
0
|
|
|
0
|
1
|
0
|
sub tk { return( shift->_set_get_one( 'Tk', @_ ) ); } |
1368
|
|
|
|
|
|
|
|
1369
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Trailer> |
1370
|
0
|
|
|
0
|
1
|
0
|
sub trailer { return( shift->_set_get_one( 'Trailer', @_ ) ); } |
1371
|
|
|
|
|
|
|
|
1372
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding> |
1373
|
0
|
|
|
0
|
1
|
0
|
sub transfer_encoding { return( shift->_set_get_one( 'Transfer-Encoding', @_ ) ); } |
1374
|
|
|
|
|
|
|
|
1375
|
|
|
|
|
|
|
sub type |
1376
|
|
|
|
|
|
|
{ |
1377
|
280
|
|
|
280
|
1
|
802
|
my $self = shift( @_ ); |
1378
|
280
|
50
|
100
|
|
|
1868
|
if( @_ ) |
|
|
100
|
|
|
|
|
|
1379
|
|
|
|
|
|
|
{ |
1380
|
|
|
|
|
|
|
# mime-type like text/html, text/plain or application/json, etc... |
1381
|
0
|
|
|
|
|
0
|
my $type = shift( @_ ); |
1382
|
0
|
|
|
|
|
0
|
$self->{type} = $type; |
1383
|
|
|
|
|
|
|
# We are being provided with content type parameters, such as charset=utf8, or version=1 |
1384
|
0
|
|
|
|
|
0
|
my $ct = $self->new_field( 'Content-Type' => $type, @_ ); |
1385
|
0
|
|
|
|
|
0
|
$self->header( 'Content-Type' => "$ct" ); |
1386
|
0
|
|
|
|
|
0
|
$self->{_ctype_cached} = "$ct"; |
1387
|
0
|
0
|
|
|
|
0
|
$self->{boundary} = $ct->boundary if( $ct->boundary ); |
1388
|
|
|
|
|
|
|
} |
1389
|
|
|
|
|
|
|
# Cached |
1390
|
|
|
|
|
|
|
elsif( CORE::length( $self->{type} ) && $self->{_ctype_cached} eq $self->content_type ) |
1391
|
|
|
|
|
|
|
{ |
1392
|
97
|
|
|
|
|
3688
|
return( $self->{type} ); |
1393
|
|
|
|
|
|
|
} |
1394
|
|
|
|
|
|
|
else |
1395
|
|
|
|
|
|
|
{ |
1396
|
183
|
|
|
|
|
951
|
my $ctype_raw = $self->content_type; |
1397
|
183
|
100
|
66
|
|
|
1923
|
return if( !defined( $ctype_raw ) || !length( "$ctype_raw" ) ); |
1398
|
51
|
|
|
|
|
818
|
$self->{_ctype_cached} = $ctype_raw; |
1399
|
|
|
|
|
|
|
# There is nothing, but the mime-type itself, so no need to bother |
1400
|
51
|
100
|
|
|
|
194
|
if( index( $ctype_raw, ';' ) == -1 ) |
1401
|
|
|
|
|
|
|
{ |
1402
|
30
|
|
|
|
|
346
|
$self->{type} = $ctype_raw; |
1403
|
30
|
|
|
|
|
251
|
$self->{boundary} = ''; |
1404
|
|
|
|
|
|
|
} |
1405
|
|
|
|
|
|
|
else |
1406
|
|
|
|
|
|
|
{ |
1407
|
|
|
|
|
|
|
# Content-Type: application/json; encoding=utf-8 |
1408
|
21
|
|
|
|
|
355
|
my $ct = $self->new_field( 'Content-Type' => $ctype_raw ); |
1409
|
21
|
50
|
|
|
|
87
|
return( $self->pass_error ) if( !defined( $ct ) ); |
1410
|
|
|
|
|
|
|
# Accept: application/json; version=1.0; charset=utf-8 |
1411
|
21
|
|
|
|
|
86
|
$self->{type} = lc( $ct->type ); |
1412
|
21
|
|
|
|
|
789363
|
my $charset = $ct->charset; |
1413
|
21
|
100
|
|
|
|
12137
|
$charset = lc( $charset ) if( defined( $charset ) ); |
1414
|
21
|
|
|
|
|
120
|
$self->{charset} = $charset; |
1415
|
21
|
100
|
|
|
|
113
|
$self->{boundary} = $ct->boundary if( $ct->boundary ); |
1416
|
|
|
|
|
|
|
} |
1417
|
|
|
|
|
|
|
} |
1418
|
51
|
|
|
|
|
12016
|
return( $self->{type} ); |
1419
|
|
|
|
|
|
|
} |
1420
|
|
|
|
|
|
|
|
1421
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Upgrade> |
1422
|
0
|
|
|
0
|
1
|
0
|
sub upgrade { return( shift->_set_get_multi( 'Upgrade', @_ ) ); } |
1423
|
|
|
|
|
|
|
|
1424
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Upgrade-Insecure-Requests> |
1425
|
0
|
|
|
0
|
1
|
0
|
sub upgrade_insecure_requests { return( shift->_set_get_one( 'Upgrade-Insecure-Requests', @_ ) ); } |
1426
|
|
|
|
|
|
|
|
1427
|
3
|
|
|
3
|
1
|
115
|
sub uri_escape_utf8 { return( URI::Escape::XS::uri_escape( Encode::encode( 'UTF-8', $_[1] ) ) ); } |
1428
|
|
|
|
|
|
|
|
1429
|
|
|
|
|
|
|
# NOTE: user_agent() is inherited |
1430
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent> |
1431
|
4
|
|
|
4
|
1
|
606
|
sub user_agent { return( shift->_set_get_one( 'user_agent', @_ ) ); } |
1432
|
|
|
|
|
|
|
|
1433
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Vary> |
1434
|
0
|
|
|
0
|
1
|
0
|
sub vary { return( shift->_set_get_multi( 'Vary', @_ ) ); } |
1435
|
|
|
|
|
|
|
|
1436
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Via> |
1437
|
0
|
|
|
0
|
1
|
0
|
sub via { return( shift->_set_get_multi( 'Via', @_ ) ); } |
1438
|
|
|
|
|
|
|
|
1439
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Want-Digest> |
1440
|
0
|
|
|
0
|
1
|
0
|
sub want_digest { return( shift->_set_get_multi( 'Want-Digest', @_ ) ); } |
1441
|
|
|
|
|
|
|
|
1442
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Warning> |
1443
|
0
|
|
|
0
|
1
|
0
|
sub warning { return( shift->_set_get_one( 'Warning', @_ ) ); } |
1444
|
|
|
|
|
|
|
|
1445
|
|
|
|
|
|
|
# NOTE: www_authenticate() is superseded |
1446
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/WWW-Authenticate> |
1447
|
3
|
|
|
3
|
1
|
12
|
sub www_authenticate { return( shift->_set_get_one( 'WWW-Authenticate', @_ ) ); } |
1448
|
|
|
|
|
|
|
|
1449
|
0
|
|
|
0
|
1
|
0
|
sub x { return( shift->_set_get_one( 'X-' . $_[0], @_ ) ); } |
1450
|
|
|
|
|
|
|
|
1451
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options> |
1452
|
0
|
|
|
0
|
1
|
0
|
sub x_content_type_options { return( shift->_set_get_one( 'X-Content-Type-Options', @_ ) ); } |
1453
|
|
|
|
|
|
|
|
1454
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-DNS-Prefetch-Control> |
1455
|
0
|
|
|
0
|
1
|
0
|
sub x_dns_prefetch_control { return( shift->_set_get_one( 'X-DNS-Prefetch-Control', @_ ) ); } |
1456
|
|
|
|
|
|
|
|
1457
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For> |
1458
|
0
|
|
|
0
|
1
|
0
|
sub x_forwarded_for { return( shift->_set_get_one( 'X-Forwarded-For', @_ ) ); } |
1459
|
|
|
|
|
|
|
|
1460
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host> |
1461
|
0
|
|
|
0
|
1
|
0
|
sub x_forwarded_host { return( shift->_set_get_one( 'X-Forwarded-Host', @_ ) ); } |
1462
|
|
|
|
|
|
|
|
1463
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto> |
1464
|
0
|
|
|
0
|
1
|
0
|
sub x_forwarded_proto { return( shift->_set_get_one( 'X-Forwarded-Proto', @_ ) ); } |
1465
|
|
|
|
|
|
|
|
1466
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options> |
1467
|
0
|
|
|
0
|
1
|
0
|
sub x_frame_options { return( shift->_set_get_one( 'X-Frame-Options', @_ ) ); } |
1468
|
|
|
|
|
|
|
|
1469
|
|
|
|
|
|
|
# <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection> |
1470
|
0
|
|
|
0
|
1
|
0
|
sub x_xss_protection { return( shift->_set_get_one( 'X-XSS-Protection', @_ ) ); } |
1471
|
|
|
|
|
|
|
|
1472
|
|
|
|
|
|
|
sub _basic_auth |
1473
|
|
|
|
|
|
|
{ |
1474
|
9
|
|
|
9
|
|
609
|
my $self = shift( @_ ); |
1475
|
9
|
|
|
|
|
14
|
my $field = shift( @_ ); |
1476
|
9
|
50
|
33
|
|
|
48
|
return( $self->error( "No field provided to get its basic authentication value." ) ) if( !defined( $field ) || !length( $field ) ); |
1477
|
9
|
50
|
|
|
|
25
|
$self->_load_class( 'Crypt::Misc' ) || return( $self->pass_error ); |
1478
|
9
|
100
|
|
|
|
26
|
if( @_ ) |
1479
|
|
|
|
|
|
|
{ |
1480
|
4
|
|
|
|
|
10
|
my( $user, $pwd ) = @_; |
1481
|
4
|
100
|
|
|
|
19
|
return( $self->error( "Basic authorisation user name cannot contain ':'." ) ) if( index( $user, ':' ) != -1 ); |
1482
|
3
|
100
|
|
|
|
8
|
$pwd = '' if( !defined( $pwd ) ); |
1483
|
3
|
|
|
|
|
64
|
$self->header( $field => sprintf( 'Basic %s', Crypt::Misc::encode_b64( "${user}:${pwd}" ) ) ); |
1484
|
3
|
|
|
|
|
23
|
return( "${user}:${pwd}" ); |
1485
|
|
|
|
|
|
|
} |
1486
|
|
|
|
|
|
|
else |
1487
|
|
|
|
|
|
|
{ |
1488
|
5
|
|
|
|
|
24
|
my $v = $self->header( $field ); |
1489
|
5
|
50
|
66
|
|
|
17
|
return( $v ) if( !defined( $v ) && !want( 'OBJECT' ) ); |
1490
|
4
|
50
|
33
|
|
|
34
|
if( defined( $v ) && $v =~ /^[[:blank:]\h]*Basic[[:blank:]\h]+(.+?)$/ ) |
1491
|
|
|
|
|
|
|
{ |
1492
|
4
|
|
|
|
|
35
|
$v = Crypt::Misc::decode_b64( $1 ); |
1493
|
|
|
|
|
|
|
} |
1494
|
4
|
100
|
|
|
|
30
|
return( wantarray() ? split( /:/, "$v" ) : $self->new_scalar( $v ) ); |
1495
|
|
|
|
|
|
|
} |
1496
|
|
|
|
|
|
|
} |
1497
|
|
|
|
|
|
|
|
1498
|
|
|
|
|
|
|
sub _date_header |
1499
|
|
|
|
|
|
|
{ |
1500
|
141
|
|
|
141
|
|
194
|
my $self = shift( @_ ); |
1501
|
141
|
|
|
|
|
196
|
my $f = shift( @_ ); |
1502
|
141
|
50
|
33
|
|
|
542
|
return( $self->error( "No field was provided to get or set its value." ) ) if( !defined( $f ) || !length( "$f" ) ); |
1503
|
141
|
100
|
|
|
|
296
|
if( @_ ) |
1504
|
|
|
|
|
|
|
{ |
1505
|
15
|
|
|
|
|
33
|
my $this = shift( @_ ); |
1506
|
15
|
50
|
|
|
|
33
|
return( $self->remove_header( "$f" ) ) if( !defined( $this ) ); |
1507
|
15
|
|
|
|
|
41
|
my $opts = $self->_get_args_as_hash( @_ ); |
1508
|
15
|
50
|
33
|
|
|
69
|
$opts->{time_zone} = 'GMT' if( !defined( $opts->{time_zone} ) || !length( $opts->{time_zone} ) ); |
1509
|
15
|
|
|
|
|
860
|
require Module::Generic::DateTime; |
1510
|
15
|
|
|
|
|
929657
|
require DateTime::Format::Strptime; |
1511
|
15
|
50
|
0
|
|
|
88
|
if( $this =~ /^\d+$/ ) |
|
|
0
|
0
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1512
|
|
|
|
|
|
|
{ |
1513
|
|
|
|
|
|
|
# try-catch |
1514
|
15
|
|
|
|
|
22
|
local $@; |
1515
|
|
|
|
|
|
|
eval |
1516
|
15
|
|
|
|
|
25
|
{ |
1517
|
15
|
|
|
|
|
82
|
$this = Module::Generic::DateTime->from_epoch( epoch => $this, time_zone => $opts->{time_zone} ); |
1518
|
|
|
|
|
|
|
}; |
1519
|
15
|
50
|
|
|
|
11578
|
if( $@ ) |
1520
|
|
|
|
|
|
|
{ |
1521
|
0
|
|
|
|
|
0
|
return( $self->error( "An error occurred while trying to get the DateTime object for epoch value '$this': $@" ) ); |
1522
|
|
|
|
|
|
|
} |
1523
|
|
|
|
|
|
|
} |
1524
|
|
|
|
|
|
|
elsif( Scalar::Util::blessed( $this ) && $this->isa( 'DateTime' ) ) |
1525
|
|
|
|
|
|
|
{ |
1526
|
0
|
|
|
|
|
0
|
$this = Module::Generic::DateTime->new( $this ); |
1527
|
|
|
|
|
|
|
} |
1528
|
|
|
|
|
|
|
elsif( Scalar::Util::blessed( $this ) && $this->isa( 'Module::Generic::DateTime' ) ) |
1529
|
|
|
|
|
|
|
{ |
1530
|
|
|
|
|
|
|
# Ok, pass through |
1531
|
|
|
|
|
|
|
} |
1532
|
|
|
|
|
|
|
else |
1533
|
|
|
|
|
|
|
{ |
1534
|
0
|
|
|
|
|
0
|
return( $self->error( "I was expecting an integer representing a unix time or a DateTime object, but instead got '$this'." ) ); |
1535
|
|
|
|
|
|
|
} |
1536
|
|
|
|
|
|
|
|
1537
|
|
|
|
|
|
|
# try-catch |
1538
|
15
|
|
|
|
|
28
|
local $@; |
1539
|
|
|
|
|
|
|
eval |
1540
|
15
|
|
|
|
|
24
|
{ |
1541
|
15
|
|
|
|
|
115
|
$this->set_time_zone( 'GMT' ); |
1542
|
15
|
|
|
|
|
3541
|
my $fmt = DateTime::Format::Strptime->new( |
1543
|
|
|
|
|
|
|
pattern => '%a, %d %b %Y %H:%M:%S GMT', |
1544
|
|
|
|
|
|
|
locale => 'en_GB', |
1545
|
|
|
|
|
|
|
time_zone => 'GMT', |
1546
|
|
|
|
|
|
|
); |
1547
|
15
|
|
|
|
|
30468
|
$this->set_formatter( $fmt ); |
1548
|
15
|
|
|
|
|
1477
|
$self->header( $f => $this ); |
1549
|
|
|
|
|
|
|
}; |
1550
|
15
|
50
|
|
|
|
48
|
if( $@ ) |
1551
|
|
|
|
|
|
|
{ |
1552
|
0
|
|
|
|
|
0
|
return( $self->error( "An error occurred while trying to format the datetime '$this': $@" ) ); |
1553
|
|
|
|
|
|
|
} |
1554
|
15
|
|
|
|
|
100
|
return( $this ); |
1555
|
|
|
|
|
|
|
} |
1556
|
|
|
|
|
|
|
else |
1557
|
|
|
|
|
|
|
{ |
1558
|
126
|
|
|
|
|
447
|
my $v = $self->header( "$f" ); |
1559
|
126
|
100
|
66
|
|
|
1449
|
return( $v ) if( !defined( $v ) || !length( "${v}" ) ); |
1560
|
64
|
50
|
66
|
|
|
16566
|
if( !length( "$v" ) || ( ref( $v ) && !overload::Method( $v, '""' ) ) ) |
|
|
|
33
|
|
|
|
|
1561
|
|
|
|
|
|
|
{ |
1562
|
0
|
0
|
|
|
|
0
|
warnings::warn( "I do not know what to do with this supposedly datetime header value '$v'\n" ) if( length( "$v" ) ); |
1563
|
|
|
|
|
|
|
# if( want( 'OBJECT' ) ) |
1564
|
|
|
|
|
|
|
# { |
1565
|
|
|
|
|
|
|
# require Module::Generic::Null; |
1566
|
|
|
|
|
|
|
# rreturn( Module::Generic::Null->new ); |
1567
|
|
|
|
|
|
|
# } |
1568
|
0
|
|
|
|
|
0
|
return( '' ); |
1569
|
|
|
|
|
|
|
} |
1570
|
|
|
|
|
|
|
|
1571
|
|
|
|
|
|
|
# try-catch |
1572
|
64
|
|
|
|
|
17976
|
local $@; |
1573
|
|
|
|
|
|
|
eval |
1574
|
64
|
|
|
|
|
115
|
{ |
1575
|
64
|
100
|
66
|
|
|
412
|
unless( Scalar::Util::blessed( $v ) && $v->isa( 'Module::Generic::DateTime' ) ) |
1576
|
|
|
|
|
|
|
{ |
1577
|
|
|
|
|
|
|
# IE6 appends "; length = NNNN" on If-Modified-Since (can we handle it) |
1578
|
|
|
|
|
|
|
# e.g.: Sat, 29 Oct 1994 19:43:31 GMT; length=34343 |
1579
|
1
|
50
|
|
|
|
8
|
if( index( $v, ';' ) != -1 ) |
1580
|
|
|
|
|
|
|
{ |
1581
|
1
|
|
|
|
|
14
|
$v = [split( /[[:blank:]\h]*;[[:blank:]\h]*/, "${v}", 2 )]->[0]; |
1582
|
|
|
|
|
|
|
} |
1583
|
1
|
|
|
|
|
10
|
require Module::Generic; |
1584
|
1
|
|
|
|
|
9
|
my $dt = Module::Generic->_parse_timestamp( "$v" ); |
1585
|
1
|
50
|
|
|
|
1969339
|
return( $self->pass_error( Module::Generic->error ) ) if( !defined( $dt ) ); |
1586
|
1
|
|
|
|
|
8
|
my $fmt = DateTime::Format::Strptime->new( pattern => '%s' ); |
1587
|
1
|
|
|
|
|
1185
|
$dt->set_formatter( $fmt ); |
1588
|
1
|
|
|
|
|
96
|
$v = Module::Generic::DateTime->new( $dt ); |
1589
|
|
|
|
|
|
|
} |
1590
|
|
|
|
|
|
|
}; |
1591
|
64
|
50
|
|
|
|
552
|
if( $@ ) |
1592
|
|
|
|
|
|
|
{ |
1593
|
0
|
|
|
|
|
0
|
return( $self->error( "An error occurred while parsing datetime '$v': $@" ) ); |
1594
|
|
|
|
|
|
|
} |
1595
|
64
|
|
|
|
|
1129
|
return( $v ); |
1596
|
|
|
|
|
|
|
} |
1597
|
|
|
|
|
|
|
} |
1598
|
|
|
|
|
|
|
|
1599
|
|
|
|
|
|
|
sub _get_args_as_array |
1600
|
|
|
|
|
|
|
{ |
1601
|
0
|
|
|
0
|
|
0
|
my $self = shift( @_ ); |
1602
|
0
|
0
|
|
|
|
0
|
return( [] ) if( !scalar( @_ ) ); |
1603
|
0
|
|
|
|
|
0
|
my $ref = []; |
1604
|
0
|
0
|
0
|
|
|
0
|
if( scalar( @_ ) == 1 && |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
1605
|
|
|
|
|
|
|
defined( $_[0] ) && |
1606
|
|
|
|
|
|
|
# Scalar::Util::reftype returns undef if the value is not a reference, which |
1607
|
|
|
|
|
|
|
# causes a warning to pop up since we then compare an undefined value. |
1608
|
|
|
|
|
|
|
ref( $_[0] ) && |
1609
|
|
|
|
|
|
|
Scalar::Util::reftype( $_[0] ) eq 'ARRAY' ) |
1610
|
|
|
|
|
|
|
{ |
1611
|
0
|
|
|
|
|
0
|
$ref = shift( @_ ); |
1612
|
|
|
|
|
|
|
} |
1613
|
|
|
|
|
|
|
else |
1614
|
|
|
|
|
|
|
{ |
1615
|
0
|
|
|
|
|
0
|
$ref = [ @_ ]; |
1616
|
|
|
|
|
|
|
} |
1617
|
0
|
|
|
|
|
0
|
return( $ref ); |
1618
|
|
|
|
|
|
|
} |
1619
|
|
|
|
|
|
|
|
1620
|
|
|
|
|
|
|
sub _get_args_as_hash |
1621
|
|
|
|
|
|
|
{ |
1622
|
74
|
|
|
74
|
|
167
|
my $self = shift( @_ ); |
1623
|
74
|
100
|
|
|
|
217
|
return( {} ) if( !scalar( @_ ) ); |
1624
|
14
|
|
|
14
|
|
126
|
no warnings 'uninitialized'; |
|
14
|
|
|
|
|
58
|
|
|
14
|
|
|
|
|
7811
|
|
1625
|
59
|
|
|
|
|
171
|
my $ref = {}; |
1626
|
59
|
|
|
|
|
285
|
my $order = $self->new_array; |
1627
|
59
|
50
|
|
|
|
594
|
my $need_list = Want::want( 'LIST' ) ? 1 : 0; |
1628
|
59
|
50
|
33
|
|
|
3930
|
if( scalar( @_ ) == 1 && Scalar::Util::reftype( $_[0] ) eq 'HASH' ) |
|
|
0
|
|
|
|
|
|
1629
|
|
|
|
|
|
|
{ |
1630
|
59
|
|
|
|
|
198
|
$ref = shift( @_ ); |
1631
|
59
|
50
|
|
|
|
181
|
$order = $self->new_array( [sort( keys( %$ref ) )] ) if( $need_list ); |
1632
|
|
|
|
|
|
|
} |
1633
|
|
|
|
|
|
|
elsif( !( scalar( @_ ) % 2 ) ) |
1634
|
|
|
|
|
|
|
{ |
1635
|
0
|
|
|
|
|
0
|
$ref = { @_ }; |
1636
|
0
|
0
|
|
|
|
0
|
if( $need_list ) |
1637
|
|
|
|
|
|
|
{ |
1638
|
0
|
|
|
|
|
0
|
for( my $i = 0; $i < scalar( @_ ); $i += 2 ) |
1639
|
|
|
|
|
|
|
{ |
1640
|
0
|
|
|
|
|
0
|
$order->push( $_[$i] ); |
1641
|
|
|
|
|
|
|
} |
1642
|
|
|
|
|
|
|
} |
1643
|
|
|
|
|
|
|
} |
1644
|
59
|
50
|
|
|
|
310
|
return( $need_list ? ( $ref, $order ) : $ref ); |
1645
|
|
|
|
|
|
|
} |
1646
|
|
|
|
|
|
|
|
1647
|
|
|
|
|
|
|
sub _header_get |
1648
|
|
|
|
|
|
|
{ |
1649
|
0
|
|
|
0
|
|
0
|
my $self = shift( @_ ); |
1650
|
0
|
|
|
|
|
0
|
my $f = shift( @_ ); |
1651
|
0
|
0
|
0
|
|
|
0
|
return( $self->error( "No header field was provided." ) ) if( !defined( $f ) || !length( "$f" ) ); |
1652
|
0
|
|
|
|
|
0
|
my @values = (); |
1653
|
0
|
0
|
|
|
|
0
|
if( wantarray() ) |
1654
|
|
|
|
|
|
|
{ |
1655
|
0
|
|
|
|
|
0
|
@values = $self->header( "$f" ); |
1656
|
0
|
0
|
|
|
|
0
|
return if( !@values ); |
1657
|
0
|
|
|
|
|
0
|
return( @values ); |
1658
|
|
|
|
|
|
|
} |
1659
|
|
|
|
|
|
|
else |
1660
|
|
|
|
|
|
|
{ |
1661
|
0
|
|
|
|
|
0
|
return( $self->header( "$f" ) ); |
1662
|
|
|
|
|
|
|
} |
1663
|
|
|
|
|
|
|
} |
1664
|
|
|
|
|
|
|
|
1665
|
|
|
|
|
|
|
sub _header_set |
1666
|
|
|
|
|
|
|
{ |
1667
|
0
|
|
|
0
|
|
0
|
my $self = shift( @_ ); |
1668
|
0
|
0
|
|
|
|
0
|
return( $self->SUPER::error( "Uneven number of parameters provided. I was expecting field-value pairs." ) ) if( @_ % 2 ); |
1669
|
0
|
|
|
|
|
0
|
my @args = (); |
1670
|
0
|
|
|
|
|
0
|
for( my $i = 0; $i < scalar( @_ ); $i += 2 ) |
1671
|
|
|
|
|
|
|
{ |
1672
|
0
|
|
|
|
|
0
|
my( $f, $v ) = @_[$i..$i+1]; |
1673
|
0
|
0
|
|
|
|
0
|
next if( !defined( $v ) ); |
1674
|
0
|
0
|
|
|
|
0
|
if( $self->_is_array( $v ) ) |
1675
|
|
|
|
|
|
|
{ |
1676
|
0
|
0
|
|
|
|
0
|
my $ref = $self->_is_object( $v ) ? [@$v] : $v; |
1677
|
0
|
|
|
|
|
0
|
push( @args, "$f" => $ref ); |
1678
|
|
|
|
|
|
|
} |
1679
|
|
|
|
|
|
|
else |
1680
|
|
|
|
|
|
|
{ |
1681
|
0
|
|
|
|
|
0
|
push( @args, "$f" => $v ); |
1682
|
|
|
|
|
|
|
} |
1683
|
|
|
|
|
|
|
} |
1684
|
|
|
|
|
|
|
|
1685
|
|
|
|
|
|
|
# try-catch |
1686
|
0
|
|
|
|
|
0
|
local $@; |
1687
|
|
|
|
|
|
|
eval |
1688
|
0
|
|
|
|
|
0
|
{ |
1689
|
0
|
|
|
|
|
0
|
$self->header( @args ); |
1690
|
|
|
|
|
|
|
}; |
1691
|
0
|
0
|
|
|
|
0
|
if( $@ ) |
1692
|
|
|
|
|
|
|
{ |
1693
|
0
|
|
|
|
|
0
|
return( $self->error( "Error trying to set headers with values: $@" ) ); |
1694
|
|
|
|
|
|
|
} |
1695
|
0
|
|
|
|
|
0
|
return( $self ); |
1696
|
|
|
|
|
|
|
} |
1697
|
|
|
|
|
|
|
|
1698
|
|
|
|
|
|
|
sub _is_a |
1699
|
|
|
|
|
|
|
{ |
1700
|
59
|
|
|
59
|
|
143
|
my $self = shift( @_ ); |
1701
|
59
|
|
|
|
|
105
|
my $obj = shift( @_ ); |
1702
|
59
|
|
|
|
|
122
|
my $pkg = shift( @_ ); |
1703
|
14
|
|
|
14
|
|
119
|
no overloading; |
|
14
|
|
|
|
|
29
|
|
|
14
|
|
|
|
|
29672
|
|
1704
|
59
|
50
|
33
|
|
|
384
|
return if( !$obj || !$pkg ); |
1705
|
59
|
50
|
|
|
|
258
|
return if( !Scalar::Util::blessed( $obj ) ); |
1706
|
59
|
|
|
|
|
382
|
return( $obj->isa( $pkg ) ); |
1707
|
|
|
|
|
|
|
} |
1708
|
|
|
|
|
|
|
|
1709
|
|
|
|
|
|
|
sub _is_class_loaded |
1710
|
|
|
|
|
|
|
{ |
1711
|
1
|
|
|
1
|
|
3
|
my $self = shift( @_ ); |
1712
|
1
|
|
|
|
|
2
|
my $class = shift( @_ ); |
1713
|
1
|
|
|
|
|
7
|
( my $pm = $class ) =~ s{::}{/}gs; |
1714
|
1
|
|
|
|
|
3
|
$pm .= '.pm'; |
1715
|
1
|
|
|
|
|
5
|
return( CORE::exists( $INC{ $pm } ) ); |
1716
|
|
|
|
|
|
|
} |
1717
|
|
|
|
|
|
|
|
1718
|
|
|
|
|
|
|
sub _is_glob |
1719
|
|
|
|
|
|
|
{ |
1720
|
59
|
50
|
|
59
|
|
229
|
return(0) if( scalar( @_ < 2 ) ); |
1721
|
59
|
50
|
|
|
|
162
|
return(0) if( !defined( $_[1] ) ); |
1722
|
59
|
|
|
|
|
209
|
my $type = Scalar::Util::reftype( $_[1] ); |
1723
|
59
|
50
|
|
|
|
156
|
return(0) if( !defined( $type ) ); |
1724
|
59
|
|
|
|
|
507
|
return( $type eq 'GLOB' ); |
1725
|
|
|
|
|
|
|
} |
1726
|
|
|
|
|
|
|
|
1727
|
|
|
|
|
|
|
sub _load_class |
1728
|
|
|
|
|
|
|
{ |
1729
|
114
|
|
|
114
|
|
251
|
my $self = shift( @_ ); |
1730
|
114
|
|
50
|
|
|
344
|
my $class = shift( @_ ) || return( $self->error( "No class to load was provided." ) ); |
1731
|
114
|
|
|
|
|
7922
|
eval( "require $class;" ); |
1732
|
114
|
50
|
|
|
|
16877
|
return( $self->error( "Unable to load class \"$class\": $@" ) ) if( $@ ); |
1733
|
114
|
|
|
|
|
471
|
return( $class ); |
1734
|
|
|
|
|
|
|
} |
1735
|
|
|
|
|
|
|
|
1736
|
|
|
|
|
|
|
sub _set_get |
1737
|
|
|
|
|
|
|
{ |
1738
|
104
|
|
|
104
|
|
263
|
my $self = shift( @_ ); |
1739
|
104
|
|
|
|
|
262
|
my $prop = shift( @_ ); |
1740
|
104
|
50
|
|
|
|
304
|
$self->{ $prop } = shift( @_ ) if( @_ ); |
1741
|
104
|
|
|
|
|
412
|
return( $self->{ $prop } ); |
1742
|
|
|
|
|
|
|
} |
1743
|
|
|
|
|
|
|
|
1744
|
|
|
|
|
|
|
# If there can be multiple instance of the given header |
1745
|
|
|
|
|
|
|
sub _set_get_multi |
1746
|
|
|
|
|
|
|
{ |
1747
|
3
|
|
|
3
|
|
6
|
my $self = shift( @_ ); |
1748
|
3
|
|
|
|
|
5
|
my $f = shift( @_ ); |
1749
|
3
|
50
|
33
|
|
|
18
|
return( $self->error( "No field was provided to get or set its value." ) ) if( !defined( $f ) || !length( "$f" ) ); |
1750
|
3
|
100
|
|
|
|
9
|
if( @_ ) |
1751
|
|
|
|
|
|
|
{ |
1752
|
1
|
|
|
|
|
2
|
my $v = shift( @_ ); |
1753
|
1
|
50
|
|
|
|
4
|
return( $self->remove_header( "$f" ) ) if( !defined( $v ) ); |
1754
|
|
|
|
|
|
|
# Too dangerous and unnecessary. The value type the user provides us defines how it will be set in the HTTP headers |
1755
|
|
|
|
|
|
|
# An array reference means there will be possibly multiple instance of the header |
1756
|
|
|
|
|
|
|
# A string, means there will be only one instance. |
1757
|
|
|
|
|
|
|
# my $ref = Scalar::Util::reftype( $v ) eq 'ARRAY' ? $v : [split( /\,[[:blank:]\h]*/, $v)]; |
1758
|
|
|
|
|
|
|
# $self->header( "$f" => $ref ); |
1759
|
1
|
|
|
|
|
10
|
$self->header( "$f" => $v ); |
1760
|
1
|
|
|
|
|
5
|
return( $v ); |
1761
|
|
|
|
|
|
|
} |
1762
|
|
|
|
|
|
|
else |
1763
|
|
|
|
|
|
|
{ |
1764
|
2
|
|
|
|
|
12
|
my @vals = $self->header( "$f" ); |
1765
|
2
|
|
|
|
|
4
|
my $ref; |
1766
|
2
|
50
|
|
|
|
9
|
if( @vals > 1 ) |
|
|
100
|
|
|
|
|
|
1767
|
|
|
|
|
|
|
{ |
1768
|
0
|
|
|
|
|
0
|
$ref = \@vals; |
1769
|
|
|
|
|
|
|
} |
1770
|
|
|
|
|
|
|
elsif( !defined( $vals[0] ) ) |
1771
|
|
|
|
|
|
|
{ |
1772
|
1
|
50
|
|
|
|
5
|
if( want( 'OBJECT' ) ) |
1773
|
|
|
|
|
|
|
{ |
1774
|
0
|
|
|
|
|
0
|
return( Module::Generic::Null->new ); |
1775
|
|
|
|
|
|
|
} |
1776
|
|
|
|
|
|
|
else |
1777
|
|
|
|
|
|
|
{ |
1778
|
1
|
|
|
|
|
63
|
return; |
1779
|
|
|
|
|
|
|
} |
1780
|
|
|
|
|
|
|
} |
1781
|
|
|
|
|
|
|
else |
1782
|
|
|
|
|
|
|
{ |
1783
|
1
|
|
|
|
|
6
|
$vals[0] =~ s/^[[:blank:]\h]+|[[:blank:]\h]+$//g; |
1784
|
1
|
|
|
|
|
6
|
$ref = [split( /\,[[:blank:]\h]*/, $vals[0] )]; |
1785
|
|
|
|
|
|
|
} |
1786
|
|
|
|
|
|
|
# Thi is not such a good idea after all. It is better to return a list in list |
1787
|
|
|
|
|
|
|
# context or a scalar object otherwise |
1788
|
|
|
|
|
|
|
# return( $self->new_array( $ref ) ); |
1789
|
1
|
50
|
|
|
|
6
|
return( wantarray() ? @$ref : $self->new_scalar( join( ', ', @$ref ) ) ); |
1790
|
|
|
|
|
|
|
} |
1791
|
|
|
|
|
|
|
} |
1792
|
|
|
|
|
|
|
|
1793
|
|
|
|
|
|
|
# If there can be only one instance of the given header |
1794
|
|
|
|
|
|
|
sub _set_get_one |
1795
|
|
|
|
|
|
|
{ |
1796
|
207
|
|
|
207
|
|
583
|
my $self = shift( @_ ); |
1797
|
207
|
|
|
|
|
832
|
my $f = shift( @_ ); |
1798
|
207
|
50
|
33
|
|
|
1729
|
return( $self->error( "No field was provided to get or set its value." ) ) if( !defined( $f ) || !length( "$f" ) ); |
1799
|
207
|
100
|
|
|
|
668
|
if( @_ ) |
1800
|
|
|
|
|
|
|
{ |
1801
|
21
|
|
|
|
|
98
|
my $v = shift( @_ ); |
1802
|
21
|
50
|
|
|
|
175
|
return( $self->remove_header( "$f" ) ) if( !defined( $v ) ); |
1803
|
21
|
|
|
|
|
357
|
$self->header( "$f" => $v ); |
1804
|
21
|
|
|
|
|
140
|
return( $v ); |
1805
|
|
|
|
|
|
|
} |
1806
|
|
|
|
|
|
|
else |
1807
|
|
|
|
|
|
|
{ |
1808
|
186
|
|
|
|
|
1512
|
my @vals = $self->header( "$f" ); |
1809
|
186
|
50
|
|
|
|
963
|
if( @vals > 1 ) |
|
|
100
|
|
|
|
|
|
1810
|
|
|
|
|
|
|
{ |
1811
|
|
|
|
|
|
|
# return( $self->new_array( \@vals ) ); |
1812
|
0
|
|
|
|
|
0
|
return( $self->new_scalar( join( ', ', @vals ) ) ); |
1813
|
|
|
|
|
|
|
} |
1814
|
|
|
|
|
|
|
elsif( !defined( $vals[0] ) ) |
1815
|
|
|
|
|
|
|
{ |
1816
|
99
|
100
|
|
|
|
337
|
if( want( 'OBJECT' ) ) |
1817
|
|
|
|
|
|
|
{ |
1818
|
30
|
|
|
|
|
2459
|
return( Module::Generic::Null->new ); |
1819
|
|
|
|
|
|
|
} |
1820
|
|
|
|
|
|
|
else |
1821
|
|
|
|
|
|
|
{ |
1822
|
69
|
|
|
|
|
4443
|
return; |
1823
|
|
|
|
|
|
|
} |
1824
|
|
|
|
|
|
|
} |
1825
|
|
|
|
|
|
|
else |
1826
|
|
|
|
|
|
|
{ |
1827
|
87
|
|
|
|
|
858
|
$vals[0] =~ s/^[[:blank:]\h]+|[[:blank:]\h]+$//g; |
1828
|
87
|
|
|
|
|
635
|
return( $self->new_scalar( $vals[0] ) ); |
1829
|
|
|
|
|
|
|
} |
1830
|
|
|
|
|
|
|
} |
1831
|
|
|
|
|
|
|
} |
1832
|
|
|
|
|
|
|
|
1833
|
|
|
|
|
|
|
sub _set_get_one_number |
1834
|
|
|
|
|
|
|
{ |
1835
|
24
|
|
|
24
|
|
106
|
my $self = shift( @_ ); |
1836
|
24
|
|
|
|
|
121
|
my $f = shift( @_ ); |
1837
|
24
|
50
|
33
|
|
|
342
|
return( $self->error( "No field was provided to get or set its value." ) ) if( !defined( $f ) || !length( "$f" ) ); |
1838
|
24
|
100
|
|
|
|
123
|
if( @_ ) |
1839
|
|
|
|
|
|
|
{ |
1840
|
1
|
|
|
|
|
12
|
my $v = shift( @_ ); |
1841
|
1
|
50
|
|
|
|
5
|
return( $self->remove_header( "$f" ) ) if( !defined( $v ) ); |
1842
|
1
|
|
|
|
|
25
|
$self->header( "$f" => $v ); |
1843
|
1
|
|
|
|
|
8
|
return( $v ); |
1844
|
|
|
|
|
|
|
} |
1845
|
|
|
|
|
|
|
else |
1846
|
|
|
|
|
|
|
{ |
1847
|
23
|
|
|
|
|
227
|
my $v = $self->header( "$f" ); |
1848
|
23
|
100
|
66
|
|
|
219
|
if( !defined( $v ) || !length( $v ) ) |
1849
|
|
|
|
|
|
|
{ |
1850
|
22
|
50
|
|
|
|
89
|
if( want( 'OBJECT' ) ) |
1851
|
|
|
|
|
|
|
{ |
1852
|
0
|
|
|
|
|
0
|
require Module::Generic::Null; |
1853
|
0
|
|
|
|
|
0
|
my $null = Module::Generic::Null->new( '', { debug => $self->debug }); |
1854
|
0
|
|
|
|
|
0
|
rreturn( $null ); |
1855
|
|
|
|
|
|
|
} |
1856
|
|
|
|
|
|
|
else |
1857
|
|
|
|
|
|
|
{ |
1858
|
22
|
|
|
|
|
1461
|
return( $v ); |
1859
|
|
|
|
|
|
|
} |
1860
|
|
|
|
|
|
|
} |
1861
|
|
|
|
|
|
|
# Ignore overflow values |
1862
|
|
|
|
|
|
|
# 16 digits corresponding to 2^53-1 or 9007199254740991 |
1863
|
1
|
50
|
|
|
|
17
|
if( $v =~ /^[[:blank:]\h]*(\d{1,16})[[:blank:]\h]*$/ ) |
1864
|
|
|
|
|
|
|
{ |
1865
|
1
|
|
|
|
|
7
|
$v = $1; |
1866
|
|
|
|
|
|
|
} |
1867
|
|
|
|
|
|
|
else |
1868
|
|
|
|
|
|
|
{ |
1869
|
0
|
|
|
|
|
0
|
return( '' ); |
1870
|
|
|
|
|
|
|
} |
1871
|
1
|
50
|
33
|
|
|
6
|
return( $v ) if( ref( $v ) && !overload::Method( $v, '""' ) ); |
1872
|
1
|
|
|
|
|
6
|
return( $self->new_number( "$v" ) ); |
1873
|
|
|
|
|
|
|
} |
1874
|
|
|
|
|
|
|
} |
1875
|
|
|
|
|
|
|
|
1876
|
|
|
|
|
|
|
sub _set_get_one_uri |
1877
|
|
|
|
|
|
|
{ |
1878
|
9
|
|
|
9
|
|
17
|
my $self = shift( @_ ); |
1879
|
9
|
|
|
|
|
16
|
my $f = shift( @_ ); |
1880
|
9
|
50
|
33
|
|
|
58
|
return( $self->error( "No field was provided to get or set its value." ) ) if( !defined( $f ) || !length( "$f" ) ); |
1881
|
9
|
100
|
|
|
|
26
|
if( @_ ) |
1882
|
|
|
|
|
|
|
{ |
1883
|
3
|
|
|
|
|
6
|
my $v = shift( @_ ); |
1884
|
3
|
50
|
|
|
|
7
|
return( $self->remove_header( "$f" ) ) if( !defined( $v ) ); |
1885
|
3
|
|
|
|
|
24
|
$self->header( "$f" => $v ); |
1886
|
3
|
|
|
|
|
13
|
return( $v ); |
1887
|
|
|
|
|
|
|
} |
1888
|
|
|
|
|
|
|
else |
1889
|
|
|
|
|
|
|
{ |
1890
|
6
|
|
|
|
|
37
|
my $v = $self->header( "$f" ); |
1891
|
6
|
|
|
|
|
17
|
my $uri; |
1892
|
|
|
|
|
|
|
# try-catch |
1893
|
6
|
|
|
|
|
10
|
local $@; |
1894
|
|
|
|
|
|
|
eval |
1895
|
6
|
|
|
|
|
8
|
{ |
1896
|
6
|
|
|
|
|
752
|
require URI; |
1897
|
6
|
|
|
|
|
3449
|
$uri = URI->new( $v ); |
1898
|
|
|
|
|
|
|
}; |
1899
|
6
|
50
|
|
|
|
13032
|
if( $@ ) |
1900
|
|
|
|
|
|
|
{ |
1901
|
0
|
|
|
|
|
0
|
return( $self->error( "Unable to create an URI object from the header value for \"$f\": $@" ) ); |
1902
|
|
|
|
|
|
|
} |
1903
|
6
|
|
|
|
|
42
|
return( $uri ); |
1904
|
|
|
|
|
|
|
} |
1905
|
|
|
|
|
|
|
} |
1906
|
|
|
|
|
|
|
|
1907
|
|
|
|
|
|
|
# NOTE: For CBOR and Sereal |
1908
|
|
|
|
|
|
|
sub FREEZE |
1909
|
|
|
|
|
|
|
{ |
1910
|
5
|
|
|
5
|
0
|
33
|
my $self = CORE::shift( @_ ); |
1911
|
5
|
|
50
|
|
|
45
|
my $serialiser = CORE::shift( @_ ) // ''; |
1912
|
5
|
|
|
|
|
25
|
my $class = CORE::ref( $self ); |
1913
|
5
|
|
|
|
|
29
|
my $h = {}; |
1914
|
5
|
|
|
|
|
22
|
my $headers = []; |
1915
|
5
|
|
|
|
|
26
|
my $order = []; |
1916
|
|
|
|
|
|
|
$self->scan(sub |
1917
|
|
|
|
|
|
|
{ |
1918
|
10
|
|
|
10
|
|
37
|
my( $f, $val ) = @_; |
1919
|
10
|
50
|
|
|
|
40
|
if( CORE::exists( $h->{ $f } ) ) |
1920
|
|
|
|
|
|
|
{ |
1921
|
0
|
0
|
|
|
|
0
|
$h->{ $f } = [ $h->{ $f } ] unless( CORE::ref( $h->{ $f } ) eq 'ARRAY' ); |
1922
|
0
|
|
|
|
|
0
|
CORE::push( @{$h->{ $f }}, $val ); |
|
0
|
|
|
|
|
0
|
|
1923
|
|
|
|
|
|
|
} |
1924
|
|
|
|
|
|
|
else |
1925
|
|
|
|
|
|
|
{ |
1926
|
10
|
|
|
|
|
67
|
$h->{ $f } = $val; |
1927
|
10
|
|
|
|
|
46
|
CORE::push( @$order, $f ); |
1928
|
|
|
|
|
|
|
} |
1929
|
5
|
|
|
|
|
182
|
}); |
1930
|
5
|
|
|
|
|
60
|
foreach my $f ( @$order ) |
1931
|
|
|
|
|
|
|
{ |
1932
|
10
|
|
|
|
|
36
|
CORE::push( @$headers, $f, $h->{ $f } ); |
1933
|
|
|
|
|
|
|
} |
1934
|
5
|
|
|
|
|
53
|
my %hash = %$self; |
1935
|
5
|
|
|
|
|
34
|
$hash{_headers_to_restore} = $headers; |
1936
|
|
|
|
|
|
|
# Return an array reference rather than a list so this works with Sereal and CBOR |
1937
|
5
|
50
|
33
|
|
|
47
|
CORE::return( [$class, \%hash] ) if( $serialiser eq 'Sereal' && Sereal::Encoder->VERSION <= version->parse( '4.023' ) ); |
1938
|
|
|
|
|
|
|
# But Storable want a list with the first element being the serialised element |
1939
|
5
|
|
|
|
|
275
|
CORE::return( $class, \%hash ); |
1940
|
|
|
|
|
|
|
} |
1941
|
|
|
|
|
|
|
|
1942
|
5
|
|
|
5
|
0
|
485
|
sub STORABLE_freeze { CORE::return( CORE::shift->FREEZE( @_ ) ); } |
1943
|
|
|
|
|
|
|
|
1944
|
|
|
|
|
|
|
# NOTE: Storable creates an instance of HTTP:::Promise::Headers. The only problem is that it does not work with XS module and that Storable discard whatever value is returned by STORABLE_thaw. See issue #19984 <https://github.com/Perl/perl5/issues/19984> |
1945
|
|
|
|
|
|
|
# So instead, we use this hook to store some data into the object created by Storable, and we call STORABLE_thaw_post_processing() with it and take what it returns. |
1946
|
|
|
|
|
|
|
sub STORABLE_thaw |
1947
|
|
|
|
|
|
|
{ |
1948
|
5
|
|
|
5
|
0
|
3889
|
my( $self, undef, $class, $hash ) = @_; |
1949
|
5
|
|
0
|
|
|
30
|
$class //= CORE::ref( $self ) || $self; |
|
|
|
33
|
|
|
|
|
1950
|
5
|
|
50
|
|
|
67
|
$hash //= {}; |
1951
|
5
|
|
|
|
|
46
|
$hash->{_class} = $class; |
1952
|
5
|
|
|
|
|
35
|
$self->{_deserialisation_params} = $hash; |
1953
|
|
|
|
|
|
|
# Useles to do more in STORABLE_thaw, because Storable anyway ignores the value returned |
1954
|
|
|
|
|
|
|
# so we just store our hash of parameters for STORABLE_thaw_post_processing to do its actual job |
1955
|
5
|
|
|
|
|
111
|
CORE::return( $self ); |
1956
|
|
|
|
|
|
|
} |
1957
|
|
|
|
|
|
|
|
1958
|
|
|
|
|
|
|
sub STORABLE_thaw_post_processing |
1959
|
|
|
|
|
|
|
{ |
1960
|
4
|
|
|
4
|
0
|
48
|
my $obj = CORE::shift( @_ ); |
1961
|
|
|
|
|
|
|
my $hash = ( CORE::exists( $obj->{_deserialisation_params} ) && CORE::ref( $obj->{_deserialisation_params} ) eq 'HASH' ) |
1962
|
|
|
|
|
|
|
? CORE::delete( $obj->{_deserialisation_params} ) |
1963
|
4
|
50
|
33
|
|
|
68
|
: {}; |
1964
|
4
|
|
33
|
|
|
40
|
my $class = CORE::delete( $hash->{_class} ) || CORE::ref( $obj ) || $obj; |
1965
|
|
|
|
|
|
|
my $headers = CORE::ref( $hash->{_headers_to_restore} ) eq 'ARRAY' |
1966
|
|
|
|
|
|
|
? CORE::delete( $hash->{_headers_to_restore} ) |
1967
|
4
|
50
|
|
|
|
37
|
: []; |
1968
|
4
|
|
|
|
|
34
|
my $new = $class->new( @$headers ); |
1969
|
4
|
|
|
|
|
19
|
foreach( CORE::keys( %$hash ) ) |
1970
|
|
|
|
|
|
|
{ |
1971
|
19
|
|
|
|
|
40
|
$new->{ $_ } = CORE::delete( $hash->{ $_ } ); |
1972
|
|
|
|
|
|
|
} |
1973
|
4
|
|
|
|
|
26
|
CORE::return( $new ); |
1974
|
|
|
|
|
|
|
} |
1975
|
|
|
|
|
|
|
|
1976
|
|
|
|
|
|
|
# NOTE: CBOR will call the THAW method with the stored classname as first argument, the constant string CBOR as second argument, and all values returned by FREEZE as remaining arguments. |
1977
|
|
|
|
|
|
|
# NOTE: Storable calls STORABLE_thaw with a blessed object it created followed with $cloning and any other arguments initially provided by STORABLE_freeze. Then, after receiving $self from STORABLE_thaw, we call THAW which return a useable object. The one generated by Storable triggers the exception: "hl is not an instance of HTTP::XSHeader" |
1978
|
|
|
|
|
|
|
sub THAW |
1979
|
|
|
|
|
|
|
{ |
1980
|
|
|
|
|
|
|
# STORABLE_thaw would issue $cloning as the 2nd argument, while CBOR would issue |
1981
|
|
|
|
|
|
|
# 'CBOR' as the second value. |
1982
|
0
|
|
|
0
|
0
|
|
my( $self, undef, @args ) = @_; |
1983
|
0
|
0
|
0
|
|
|
|
my $ref = ( CORE::scalar( @args ) == 1 && CORE::ref( $args[0] ) eq 'ARRAY' ) ? CORE::shift( @args ) : \@args; |
1984
|
0
|
0
|
0
|
|
|
|
my $class = ( CORE::defined( $ref ) && CORE::ref( $ref ) eq 'ARRAY' && CORE::scalar( @$ref ) > 1 ) ? CORE::shift( @$ref ) : ( CORE::ref( $self ) || $self ); |
|
|
|
0
|
|
|
|
|
1985
|
0
|
0
|
|
|
|
|
my $hash = CORE::ref( $ref ) eq 'ARRAY' ? CORE::shift( @$ref ) : {}; |
1986
|
|
|
|
|
|
|
my $headers = ( CORE::exists( $hash->{_headers_to_restore} ) && CORE::ref( $hash->{_headers_to_restore} ) eq 'ARRAY' ) |
1987
|
|
|
|
|
|
|
? CORE::delete( $hash->{_headers_to_restore} ) |
1988
|
0
|
0
|
0
|
|
|
|
: []; |
1989
|
|
|
|
|
|
|
|
1990
|
0
|
|
|
|
|
|
my $new = $class->new( @$headers ); |
1991
|
0
|
|
|
|
|
|
foreach( CORE::keys( %$hash ) ) |
1992
|
|
|
|
|
|
|
{ |
1993
|
0
|
0
|
|
|
|
|
next if( CORE::scalar( CORE::grep( $_, @$headers ) ) ); |
1994
|
0
|
|
|
|
|
|
$new->{ $_ } = CORE::delete( $hash->{ $_ } ); |
1995
|
|
|
|
|
|
|
} |
1996
|
0
|
|
|
|
|
|
CORE::return( $new ); |
1997
|
|
|
|
|
|
|
} |
1998
|
|
|
|
|
|
|
|
1999
|
|
|
|
|
|
|
sub TO_JSON |
2000
|
|
|
|
|
|
|
{ |
2001
|
0
|
|
|
0
|
0
|
|
my $self = shift( @_ ); |
2002
|
0
|
|
|
|
|
|
my $ref = []; |
2003
|
|
|
|
|
|
|
$self->scan(sub |
2004
|
|
|
|
|
|
|
{ |
2005
|
0
|
|
|
0
|
|
|
my( $header, $val ) = @_; |
2006
|
0
|
|
|
|
|
|
CORE::push( @$ref, [ $header, $val ] ); |
2007
|
0
|
|
|
|
|
|
}); |
2008
|
0
|
|
|
|
|
|
return( $ref ); |
2009
|
|
|
|
|
|
|
} |
2010
|
|
|
|
|
|
|
|
2011
|
|
|
|
|
|
|
1; |
2012
|
|
|
|
|
|
|
# NOTE: POD |
2013
|
|
|
|
|
|
|
__END__ |
2014
|
|
|
|
|
|
|
|
2015
|
|
|
|
|
|
|
=encoding utf-8 |
2016
|
|
|
|
|
|
|
|
2017
|
|
|
|
|
|
|
=head1 NAME |
2018
|
|
|
|
|
|
|
|
2019
|
|
|
|
|
|
|
HTTP::Promise::Headers - HTTP Headers Class |
2020
|
|
|
|
|
|
|
|
2021
|
|
|
|
|
|
|
=head1 SYNOPSIS |
2022
|
|
|
|
|
|
|
|
2023
|
|
|
|
|
|
|
use HTTP::Promise::Headers; |
2024
|
|
|
|
|
|
|
my $h = HTTP::Promise::Headers->new || |
2025
|
|
|
|
|
|
|
die( HTTP::Promise::Headers->error, "\n" ); |
2026
|
|
|
|
|
|
|
|
2027
|
|
|
|
|
|
|
=head1 VERSION |
2028
|
|
|
|
|
|
|
|
2029
|
|
|
|
|
|
|
v0.2.0 |
2030
|
|
|
|
|
|
|
|
2031
|
|
|
|
|
|
|
=head1 DESCRIPTION |
2032
|
|
|
|
|
|
|
|
2033
|
|
|
|
|
|
|
This class uses for the most part an XS module (L<HTTP::XSHeaders>) to be very fast, and yet provides a convenient and versatile interface to retrieve and manipulate HTTP headers. |
2034
|
|
|
|
|
|
|
|
2035
|
|
|
|
|
|
|
A number of classes has been created to have a more granular control on the creation of some header values. See L</SEE ALSO> |
2036
|
|
|
|
|
|
|
|
2037
|
|
|
|
|
|
|
All HTTP headers known today have their corresponding method that can be used to easily get or set their corresponding header value. |
2038
|
|
|
|
|
|
|
|
2039
|
|
|
|
|
|
|
=head1 CONSTRUCTOR |
2040
|
|
|
|
|
|
|
|
2041
|
|
|
|
|
|
|
=head2 new |
2042
|
|
|
|
|
|
|
|
2043
|
|
|
|
|
|
|
This instantiates a new L<HTTP::Promise::Headers> object. You might pass some initial |
2044
|
|
|
|
|
|
|
attribute-value pairs as parameters to the constructor. |
2045
|
|
|
|
|
|
|
|
2046
|
|
|
|
|
|
|
For example: |
2047
|
|
|
|
|
|
|
|
2048
|
|
|
|
|
|
|
$h = HTTP::Headers->new( |
2049
|
|
|
|
|
|
|
Date => 'Mon, 09 May 2022 09:00:00 GMT', |
2050
|
|
|
|
|
|
|
Content_Type => 'text/html; charset=utf-8; version=5.0', |
2051
|
|
|
|
|
|
|
Content_Base => 'http://www.example.org/' |
2052
|
|
|
|
|
|
|
); |
2053
|
|
|
|
|
|
|
|
2054
|
|
|
|
|
|
|
The constructor arguments are passed to the L</header> method described below. |
2055
|
|
|
|
|
|
|
|
2056
|
|
|
|
|
|
|
=head1 METHODS |
2057
|
|
|
|
|
|
|
|
2058
|
|
|
|
|
|
|
=head2 add |
2059
|
|
|
|
|
|
|
|
2060
|
|
|
|
|
|
|
This is an alias for L</push_header> |
2061
|
|
|
|
|
|
|
|
2062
|
|
|
|
|
|
|
=head2 as_string |
2063
|
|
|
|
|
|
|
|
2064
|
|
|
|
|
|
|
Provided with an optional C<EOL> to be used as End-Of-Line character, and this will return a string representation of the headers. C<EOL> defaults to C<\015\012>. Embedded "\n" characters in header field values will be substituted with this line ending sequence. |
2065
|
|
|
|
|
|
|
|
2066
|
|
|
|
|
|
|
This uses L</scan> internally and use header field case as suggested by HTTP specifications. It will also follow recommended "Good Practice" of ordering the header fields. Long header values are not folded. |
2067
|
|
|
|
|
|
|
|
2068
|
|
|
|
|
|
|
=head2 authorization_basic |
2069
|
|
|
|
|
|
|
|
2070
|
|
|
|
|
|
|
This is a convenience method around the L</authorization> method for the C<Authorization> header using the "Basic Authentication Scheme". |
2071
|
|
|
|
|
|
|
|
2072
|
|
|
|
|
|
|
To set the related header value, you provide a login and an optional password, and this will set the C<Authorization> header value and return the current headers object for chaining. |
2073
|
|
|
|
|
|
|
|
2074
|
|
|
|
|
|
|
$h->authorization_basic( $user, $password ); |
2075
|
|
|
|
|
|
|
|
2076
|
|
|
|
|
|
|
If no value is provided, this will get the curent value of the C<Authorization> header field, base64 decode it, and return the decoded string as a L<scalar object|Module::Generic::Scalar>, i.e. something like C<usernaem:password> |
2077
|
|
|
|
|
|
|
|
2078
|
|
|
|
|
|
|
my $str = $h->authorization_basic; |
2079
|
|
|
|
|
|
|
|
2080
|
|
|
|
|
|
|
=head2 boundary |
2081
|
|
|
|
|
|
|
|
2082
|
|
|
|
|
|
|
This is a convenience method to set or get the boundary, if any, used for multipart C<Content-Type> |
2083
|
|
|
|
|
|
|
|
2084
|
|
|
|
|
|
|
If provided, this will add the C<boundary> parameter with the given value to the C<Content-Type> header field. |
2085
|
|
|
|
|
|
|
|
2086
|
|
|
|
|
|
|
If no value is provided, this returns the current boundary, if any, or an empty string. |
2087
|
|
|
|
|
|
|
|
2088
|
|
|
|
|
|
|
=head2 charset |
2089
|
|
|
|
|
|
|
|
2090
|
|
|
|
|
|
|
This is a convenience method to set or get the charset associated with the C<Content-Type> header field. |
2091
|
|
|
|
|
|
|
|
2092
|
|
|
|
|
|
|
If provided, this will add the C<charset> parameter with the given value to the C<Content-Type> header field. |
2093
|
|
|
|
|
|
|
|
2094
|
|
|
|
|
|
|
If no value is provided, this returns the current charset, if any, or an empty string. |
2095
|
|
|
|
|
|
|
|
2096
|
|
|
|
|
|
|
=head2 clear |
2097
|
|
|
|
|
|
|
|
2098
|
|
|
|
|
|
|
This will remove all header fields. |
2099
|
|
|
|
|
|
|
|
2100
|
|
|
|
|
|
|
=for Pod::Coverage:: client_date |
2101
|
|
|
|
|
|
|
|
2102
|
|
|
|
|
|
|
=head2 clone |
2103
|
|
|
|
|
|
|
|
2104
|
|
|
|
|
|
|
Returns a copy of this L<HTTP::Promise::Headers> object. |
2105
|
|
|
|
|
|
|
|
2106
|
|
|
|
|
|
|
=head2 content_is_text |
2107
|
|
|
|
|
|
|
|
2108
|
|
|
|
|
|
|
Returns true if the C<Content-Type> mime-type is textual in nature, i.e. its first half is C<text>, false otherwise. For example: C<text/plain> or C<text/html> |
2109
|
|
|
|
|
|
|
|
2110
|
|
|
|
|
|
|
=head2 content_is_html |
2111
|
|
|
|
|
|
|
|
2112
|
|
|
|
|
|
|
Returns true if the C<Content-Type> mime-type is html, such as C<text/html>, false otherwise. |
2113
|
|
|
|
|
|
|
|
2114
|
|
|
|
|
|
|
=head2 content_is_json |
2115
|
|
|
|
|
|
|
|
2116
|
|
|
|
|
|
|
Returns true if the C<Content-Type> mime-type is C<application/json>, false otherwise. |
2117
|
|
|
|
|
|
|
|
2118
|
|
|
|
|
|
|
=head2 content_is_xhtml |
2119
|
|
|
|
|
|
|
|
2120
|
|
|
|
|
|
|
Returns true if the C<Content-Type> mime-type is C<application/xhtml+xml> or C<application/vnd.wap.xhtml+xml>, false otherwise. |
2121
|
|
|
|
|
|
|
|
2122
|
|
|
|
|
|
|
=head2 content_is_xml |
2123
|
|
|
|
|
|
|
|
2124
|
|
|
|
|
|
|
Returns true if the C<Content-Type> mime-type is C<text/xml> or C<application/xml>, or contains the keyword C<xml>, false otherwise. |
2125
|
|
|
|
|
|
|
|
2126
|
|
|
|
|
|
|
=head2 content_type_charset |
2127
|
|
|
|
|
|
|
|
2128
|
|
|
|
|
|
|
This is a legacy method and it returns the upper-cased charset specified in the Content-Type header. |
2129
|
|
|
|
|
|
|
In list context return the lower-cased bare content type followed by the upper-cased charset. |
2130
|
|
|
|
|
|
|
Both values will be C<undef> if not specified in the header. |
2131
|
|
|
|
|
|
|
|
2132
|
|
|
|
|
|
|
=head2 decode_filename |
2133
|
|
|
|
|
|
|
|
2134
|
|
|
|
|
|
|
This takes a file name from the C<Content-Disposition> header value typically and returns it decoded if it was encoded as per the L<rfc2231|https://tools.ietf.org/html/rfc2231> |
2135
|
|
|
|
|
|
|
|
2136
|
|
|
|
|
|
|
For example: |
2137
|
|
|
|
|
|
|
|
2138
|
|
|
|
|
|
|
Content-Disposition: form-data; name="fileField"; filename*=UTF-8''%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB.txt |
2139
|
|
|
|
|
|
|
|
2140
|
|
|
|
|
|
|
my $fname = $h->decode_filename( "UTF-8''%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB.txt" ); |
2141
|
|
|
|
|
|
|
|
2142
|
|
|
|
|
|
|
or |
2143
|
|
|
|
|
|
|
|
2144
|
|
|
|
|
|
|
Content-Disposition: form-data; name="fileField"; filename*=UTF-8'ja-JP'%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB.txt |
2145
|
|
|
|
|
|
|
|
2146
|
|
|
|
|
|
|
my $fname = $h->decode_filename( "UTF-8'ja-JP'%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB.txt" ); |
2147
|
|
|
|
|
|
|
|
2148
|
|
|
|
|
|
|
or encoded with quoted-printable |
2149
|
|
|
|
|
|
|
|
2150
|
|
|
|
|
|
|
Content-Disposition: attachment; filename="=?UTF-8?Q?=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB.txt?=" |
2151
|
|
|
|
|
|
|
|
2152
|
|
|
|
|
|
|
my $fname = $h->decode_filename( "=?UTF-8?Q?=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB.txt?=" ); |
2153
|
|
|
|
|
|
|
|
2154
|
|
|
|
|
|
|
or encoded with base64 |
2155
|
|
|
|
|
|
|
|
2156
|
|
|
|
|
|
|
Content-Disposition: attachment; filename="=?UTF-8?B?44OV44Kh44Kk44OrLnR4dAo?=" |
2157
|
|
|
|
|
|
|
|
2158
|
|
|
|
|
|
|
my $fname = $h->decode_filename( "=?UTF-8?B?44OV44Kh44Kk44OrLnR4dAo?=" ); |
2159
|
|
|
|
|
|
|
|
2160
|
|
|
|
|
|
|
In the above example, the result for C<$fname> would yield C<ファイル.txt> (i.e. file.txt in Japanese) |
2161
|
|
|
|
|
|
|
|
2162
|
|
|
|
|
|
|
=head2 debug |
2163
|
|
|
|
|
|
|
|
2164
|
|
|
|
|
|
|
Sets or gets the debug value. If positive, this will trigger an output of debugging messages on the STDERR or in the web server log files. Be mindful that this slows down the script, so make sure to switch it off once you are done. |
2165
|
|
|
|
|
|
|
|
2166
|
|
|
|
|
|
|
=head2 default_type |
2167
|
|
|
|
|
|
|
|
2168
|
|
|
|
|
|
|
Sets or gets the default mime-type to be used. |
2169
|
|
|
|
|
|
|
|
2170
|
|
|
|
|
|
|
=head2 delete |
2171
|
|
|
|
|
|
|
|
2172
|
|
|
|
|
|
|
This is an alias for L</remove_header> |
2173
|
|
|
|
|
|
|
|
2174
|
|
|
|
|
|
|
=head2 encode_filename |
2175
|
|
|
|
|
|
|
|
2176
|
|
|
|
|
|
|
This takes a file name to be used in the C<Content-Disposition> header value, and an optional language iso 639 code (see L<rfc1766|https://tools.ietf.org/html/rfc1766>), and if it contains non ascii characters, it will utf-8 encode it and URI escape it according to L<rfc2231|https://tools.ietf.org/html/rfc2231> and return the newly encoded file name. |
2177
|
|
|
|
|
|
|
|
2178
|
|
|
|
|
|
|
If the file name did not require any encoding, it will return C<undef>, so you can write something like this: |
2179
|
|
|
|
|
|
|
|
2180
|
|
|
|
|
|
|
my $filename = q{マイファイル.txt}; |
2181
|
|
|
|
|
|
|
if( my $enc = $h->encode_filename( $filename ) ) |
2182
|
|
|
|
|
|
|
{ |
2183
|
|
|
|
|
|
|
$filename = $enc; |
2184
|
|
|
|
|
|
|
# Now $filename is: UTF-8''%E3%83%9E%E3%82%A4%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB.txt |
2185
|
|
|
|
|
|
|
} |
2186
|
|
|
|
|
|
|
|
2187
|
|
|
|
|
|
|
You can optionally pass a language code argument: |
2188
|
|
|
|
|
|
|
|
2189
|
|
|
|
|
|
|
if( my $enc = $h->encode_filename( $filename, 'ja-JP' ) ) |
2190
|
|
|
|
|
|
|
{ |
2191
|
|
|
|
|
|
|
$filename = $enc; |
2192
|
|
|
|
|
|
|
# Now $filename is: UTF-8'ja-JP'%E3%83%9E%E3%82%A4%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB.txt |
2193
|
|
|
|
|
|
|
} |
2194
|
|
|
|
|
|
|
|
2195
|
|
|
|
|
|
|
The C<Content-Disposition> header value would then contain a property C<filename*> (with the trailing wildcard). |
2196
|
|
|
|
|
|
|
|
2197
|
|
|
|
|
|
|
=head2 error |
2198
|
|
|
|
|
|
|
|
2199
|
|
|
|
|
|
|
Sets or gets an error and when set, this returns C<undef>. When no argument is provided, this returns the latest error set. |
2200
|
|
|
|
|
|
|
|
2201
|
|
|
|
|
|
|
The error returned is actually a L<HTTP::Promise::Exception> object. |
2202
|
|
|
|
|
|
|
|
2203
|
|
|
|
|
|
|
=head2 exists |
2204
|
|
|
|
|
|
|
|
2205
|
|
|
|
|
|
|
Provided with a header field name and this returns true if it exists, or false otherwise. |
2206
|
|
|
|
|
|
|
|
2207
|
|
|
|
|
|
|
=head2 flatten |
2208
|
|
|
|
|
|
|
|
2209
|
|
|
|
|
|
|
$h->flatten(); |
2210
|
|
|
|
|
|
|
|
2211
|
|
|
|
|
|
|
Returns the list of pairs of keys and values. |
2212
|
|
|
|
|
|
|
|
2213
|
|
|
|
|
|
|
=head2 get |
2214
|
|
|
|
|
|
|
|
2215
|
|
|
|
|
|
|
This is an alias for L</header>, mainly used without argument. |
2216
|
|
|
|
|
|
|
|
2217
|
|
|
|
|
|
|
=head2 header |
2218
|
|
|
|
|
|
|
|
2219
|
|
|
|
|
|
|
$h->header( $field ); |
2220
|
|
|
|
|
|
|
$h->header( $field => $value ); |
2221
|
|
|
|
|
|
|
$h->header( $f1 => $v1, $f2 => $v2, ... ); |
2222
|
|
|
|
|
|
|
|
2223
|
|
|
|
|
|
|
The following is an extract from the original L<HTTP::Headers> class. |
2224
|
|
|
|
|
|
|
|
2225
|
|
|
|
|
|
|
Sets or gets the value of one or more header fields. |
2226
|
|
|
|
|
|
|
The header field name (C<$field>) is not case sensitive. |
2227
|
|
|
|
|
|
|
To make the life easier for perl users who wants to avoid quoting before the => operator, you can use '_' as a replacement for '-' in header names. |
2228
|
|
|
|
|
|
|
|
2229
|
|
|
|
|
|
|
The L</header> method accepts multiple field-value (C<$field => $value>) pairs, which means that you can update several header field values with a single invocation. |
2230
|
|
|
|
|
|
|
|
2231
|
|
|
|
|
|
|
The C<$value> argument may be a plain string or an array reference of strings for a multi-valued field. If the C<$value> is provided as C<undef> then the field is removed. |
2232
|
|
|
|
|
|
|
|
2233
|
|
|
|
|
|
|
If the C<$value> is not given, then that header field will remain unchanged. In addition to being a string, C<$value> may be something that stringifies. |
2234
|
|
|
|
|
|
|
|
2235
|
|
|
|
|
|
|
The old value (or values) of the last of the header fields is returned. If no such field exists C<undef> will be returned. |
2236
|
|
|
|
|
|
|
|
2237
|
|
|
|
|
|
|
A multi-valued field will be returned as separate values in list context and will be concatenated with ", " as separator in scalar context. |
2238
|
|
|
|
|
|
|
The HTTP spec (L<rfc7230|https://tools.ietf.org/html/rfc7230> which obsoleted L<rfc2616|https://tools.ietf.org/html/rfc2616>) promises that joining multiple values in this way will not change the semantic of a header field, but in practice there are cases like old-style Netscape cookies where "," is used as part of the syntax of a single field value. |
2239
|
|
|
|
|
|
|
|
2240
|
|
|
|
|
|
|
Examples: |
2241
|
|
|
|
|
|
|
|
2242
|
|
|
|
|
|
|
$h->header( MIME_Version => '1.0', |
2243
|
|
|
|
|
|
|
User_Agent => 'My-Web-Client/0.01' ); |
2244
|
|
|
|
|
|
|
$h->header( Accept => "text/html, text/plain, image/*" ); |
2245
|
|
|
|
|
|
|
$h->header( Accept => [qw( text/html text/plain image/* )] ); |
2246
|
|
|
|
|
|
|
@accepts = $h->header( 'Accept' ); # get multiple values |
2247
|
|
|
|
|
|
|
$accepts = $h->header( 'Accept' ); # get values as a single string |
2248
|
|
|
|
|
|
|
|
2249
|
|
|
|
|
|
|
=head2 header_field_names |
2250
|
|
|
|
|
|
|
|
2251
|
|
|
|
|
|
|
The following is an extract from the original L<HTTP::Headers> class. |
2252
|
|
|
|
|
|
|
|
2253
|
|
|
|
|
|
|
Returns the list of distinct names for the fields present in the header. |
2254
|
|
|
|
|
|
|
The field names have case as suggested by HTTP spec, and the names are returned in the recommended "Good Practice" order. |
2255
|
|
|
|
|
|
|
|
2256
|
|
|
|
|
|
|
In scalar context return the number of distinct field names. |
2257
|
|
|
|
|
|
|
|
2258
|
|
|
|
|
|
|
=head2 init_header |
2259
|
|
|
|
|
|
|
|
2260
|
|
|
|
|
|
|
$h->init_header( $field => $value ); |
2261
|
|
|
|
|
|
|
|
2262
|
|
|
|
|
|
|
Set the specified header to the given value, but only if no previous value for that field is set. |
2263
|
|
|
|
|
|
|
|
2264
|
|
|
|
|
|
|
The header field name (C<$field>) is not case sensitive and '_' can be used as a replacement for '-'. |
2265
|
|
|
|
|
|
|
|
2266
|
|
|
|
|
|
|
The $value argument may be a scalar or a reference to a list of scalars. |
2267
|
|
|
|
|
|
|
|
2268
|
|
|
|
|
|
|
=head2 make_boundary |
2269
|
|
|
|
|
|
|
|
2270
|
|
|
|
|
|
|
Returns a new boundary using L<Data::UUID> |
2271
|
|
|
|
|
|
|
|
2272
|
|
|
|
|
|
|
=for Pod::Coverage message |
2273
|
|
|
|
|
|
|
|
2274
|
|
|
|
|
|
|
=for Pod::Coverage message_check |
2275
|
|
|
|
|
|
|
|
2276
|
|
|
|
|
|
|
=for Pod::Coverage message_frame |
2277
|
|
|
|
|
|
|
|
2278
|
|
|
|
|
|
|
=head2 mime_attr |
2279
|
|
|
|
|
|
|
|
2280
|
|
|
|
|
|
|
Provided with a header field name and an attribute name separated by a dot, such as C<content-disposition.filename> and this will return the value for that attribute in this header. |
2281
|
|
|
|
|
|
|
|
2282
|
|
|
|
|
|
|
If a value is provided, it will be set, otherwise it will be returned. |
2283
|
|
|
|
|
|
|
|
2284
|
|
|
|
|
|
|
If no attribute is provided, it will set or get the header field main value. |
2285
|
|
|
|
|
|
|
|
2286
|
|
|
|
|
|
|
For example: |
2287
|
|
|
|
|
|
|
|
2288
|
|
|
|
|
|
|
Content-Disposition: attachment; filename="hello.txt" |
2289
|
|
|
|
|
|
|
my $dispo = $h->mime_attr( 'content-disposition' ); |
2290
|
|
|
|
|
|
|
|
2291
|
|
|
|
|
|
|
will return C<attachment> |
2292
|
|
|
|
|
|
|
|
2293
|
|
|
|
|
|
|
=head2 mime_encoding |
2294
|
|
|
|
|
|
|
|
2295
|
|
|
|
|
|
|
Returns the value of the C<Content-Encoding>, C<Transfer-Encoding> or C<Content-Transfer-Encoding> (the latter only exists in mail, not in HTTP) |
2296
|
|
|
|
|
|
|
|
2297
|
|
|
|
|
|
|
=head2 mime_type |
2298
|
|
|
|
|
|
|
|
2299
|
|
|
|
|
|
|
Returns the mime-type from the C<Content-Type> header value, or the one from L<default_type>, if it is set. If nothing is found, this returns an empty string (not C<undef>). |
2300
|
|
|
|
|
|
|
|
2301
|
|
|
|
|
|
|
=head2 multipart_boundary |
2302
|
|
|
|
|
|
|
|
2303
|
|
|
|
|
|
|
Returns the multipart boundary used, if any, or an empty string otherwise. |
2304
|
|
|
|
|
|
|
|
2305
|
|
|
|
|
|
|
my $boundary = $h->multipart_boundary; |
2306
|
|
|
|
|
|
|
# or you can provide the Content-Type if you already have it; it will save a few cycle |
2307
|
|
|
|
|
|
|
my $boundary = $h->multipart_boundary( $content_type ); |
2308
|
|
|
|
|
|
|
|
2309
|
|
|
|
|
|
|
=head2 print |
2310
|
|
|
|
|
|
|
|
2311
|
|
|
|
|
|
|
Provided with a filehandle, or an L<HTTP::Promise::IO> object and this will print on it the string representation of the headers and return whatever value L<perlfunc/print> will return. |
2312
|
|
|
|
|
|
|
|
2313
|
|
|
|
|
|
|
=head2 proxy_authorization_basic |
2314
|
|
|
|
|
|
|
|
2315
|
|
|
|
|
|
|
=head2 push_header |
2316
|
|
|
|
|
|
|
|
2317
|
|
|
|
|
|
|
$h->push_header( $field => $value ); |
2318
|
|
|
|
|
|
|
$h->push_header( $f1 => $v1, $f2 => $v2, ... ); |
2319
|
|
|
|
|
|
|
|
2320
|
|
|
|
|
|
|
Add a new value for the specified header. Previous values for the same header are retained. |
2321
|
|
|
|
|
|
|
|
2322
|
|
|
|
|
|
|
As for the L</header> method, the field name (C<$field>) is not case sensitive and '_' can be used as a replacement for '-'. |
2323
|
|
|
|
|
|
|
|
2324
|
|
|
|
|
|
|
The $value argument may be a scalar or a reference to a list of scalars. |
2325
|
|
|
|
|
|
|
|
2326
|
|
|
|
|
|
|
$header->push_header( Accept => 'image/jpeg' ); |
2327
|
|
|
|
|
|
|
$header->push_header( Accept => [ map( "image/$_", qw( gif png tiff ) )] ); |
2328
|
|
|
|
|
|
|
|
2329
|
|
|
|
|
|
|
=head2 recommended_filename |
2330
|
|
|
|
|
|
|
|
2331
|
|
|
|
|
|
|
This returns the filename set in either C<Content-Disposition> with the C<filename> property or in C<Content-Type> with the C<name> property. |
2332
|
|
|
|
|
|
|
|
2333
|
|
|
|
|
|
|
If none exists, this returns C<undef>. |
2334
|
|
|
|
|
|
|
|
2335
|
|
|
|
|
|
|
=head2 remove |
2336
|
|
|
|
|
|
|
|
2337
|
|
|
|
|
|
|
This is an alias for L</remove_header> |
2338
|
|
|
|
|
|
|
|
2339
|
|
|
|
|
|
|
=head2 remove_content_headers |
2340
|
|
|
|
|
|
|
|
2341
|
|
|
|
|
|
|
This will remove all the headers used to describe the content of a message. |
2342
|
|
|
|
|
|
|
|
2343
|
|
|
|
|
|
|
All header field names prefixed with C<Content-> are included in this category, as well as C<Allow>, C<Expires> and |
2344
|
|
|
|
|
|
|
C<Last-Modified>. L<rfc7230|https://tools.ietf.org/html/rfc7230> denotes these headers as I<Entity Header Fields>. |
2345
|
|
|
|
|
|
|
|
2346
|
|
|
|
|
|
|
The return value is a new L<HTTP::Promise::Headers> object that contains the removed headers only. |
2347
|
|
|
|
|
|
|
|
2348
|
|
|
|
|
|
|
=head2 remove_header |
2349
|
|
|
|
|
|
|
|
2350
|
|
|
|
|
|
|
my @values = $h->remove_header( $field, ... ); |
2351
|
|
|
|
|
|
|
my $total_values_removed = $h->remove_header( $field, ... ); |
2352
|
|
|
|
|
|
|
|
2353
|
|
|
|
|
|
|
This function removes the header with the specified names. |
2354
|
|
|
|
|
|
|
|
2355
|
|
|
|
|
|
|
The header names (C<$field>) are not case sensitive and '_' can be used as a replacement for '-'. |
2356
|
|
|
|
|
|
|
|
2357
|
|
|
|
|
|
|
The return value is the values of the headers removed. In scalar context the number of headers removed is returned. |
2358
|
|
|
|
|
|
|
|
2359
|
|
|
|
|
|
|
Note that if you pass in multiple header names then it is generally not possible to tell which of the returned values belonged to which field. |
2360
|
|
|
|
|
|
|
|
2361
|
|
|
|
|
|
|
=head2 replace |
2362
|
|
|
|
|
|
|
|
2363
|
|
|
|
|
|
|
Provided with a header field name and a value and this replace whatever current value with the value provided. |
2364
|
|
|
|
|
|
|
|
2365
|
|
|
|
|
|
|
It returns the current object for chaining. |
2366
|
|
|
|
|
|
|
|
2367
|
|
|
|
|
|
|
=head2 request_timeout |
2368
|
|
|
|
|
|
|
|
2369
|
|
|
|
|
|
|
Sets or gets the request timeout. This takes an integer. |
2370
|
|
|
|
|
|
|
|
2371
|
|
|
|
|
|
|
=head2 scan |
2372
|
|
|
|
|
|
|
|
2373
|
|
|
|
|
|
|
$h->scan( \&process_header_field ); |
2374
|
|
|
|
|
|
|
|
2375
|
|
|
|
|
|
|
Apply a subroutine to each header field in turn. |
2376
|
|
|
|
|
|
|
The callback routine is called with two parameters; the name of the field and a single value (a string). |
2377
|
|
|
|
|
|
|
If a header field is multi-valued, then the routine is called once for each value. |
2378
|
|
|
|
|
|
|
The field name passed to the callback routine has case as suggested by HTTP spec, and the headers will be visited in the recommended "Good Practice" order. |
2379
|
|
|
|
|
|
|
|
2380
|
|
|
|
|
|
|
Any return values of the callback routine are ignored. |
2381
|
|
|
|
|
|
|
The loop can be broken by raising an exception (C<die>), but the caller of scan() would have to trap the exception itself. |
2382
|
|
|
|
|
|
|
|
2383
|
|
|
|
|
|
|
=head2 type |
2384
|
|
|
|
|
|
|
|
2385
|
|
|
|
|
|
|
This sets or gets the C<Content-Type> header value when setting a value, and returns only the mime-type when retrieving the value. |
2386
|
|
|
|
|
|
|
|
2387
|
|
|
|
|
|
|
$h->type( 'text/plain' ); |
2388
|
|
|
|
|
|
|
# Assuming Content-Type: text/html; charset=utf-8 |
2389
|
|
|
|
|
|
|
my $type = $h->type; # text/html |
2390
|
|
|
|
|
|
|
|
2391
|
|
|
|
|
|
|
=head2 uri_escape_utf8 |
2392
|
|
|
|
|
|
|
|
2393
|
|
|
|
|
|
|
Provided with a string and this returns an URI-escaped string using L<URI::Escape::XS> |
2394
|
|
|
|
|
|
|
|
2395
|
|
|
|
|
|
|
=head1 HTTP HEADERS METHODS |
2396
|
|
|
|
|
|
|
|
2397
|
|
|
|
|
|
|
=head2 accept |
2398
|
|
|
|
|
|
|
|
2399
|
|
|
|
|
|
|
$h->accept( q{text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8} ); |
2400
|
|
|
|
|
|
|
$h->accept( [qw( text/html application/xhtml+xml application/xml;q=0.9 */*;q=0.8 )] ); |
2401
|
|
|
|
|
|
|
|
2402
|
|
|
|
|
|
|
Sets or gets the C<Accept> header field value. It takes either a string or an array or array reference of values. |
2403
|
|
|
|
|
|
|
|
2404
|
|
|
|
|
|
|
See L<rfc7231, section 5.3.2|https://tools.ietf.org/html/rfc7231#section-5.3.2> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept> |
2405
|
|
|
|
|
|
|
|
2406
|
|
|
|
|
|
|
See also L<HTTP::Promise::Headers::Accept> |
2407
|
|
|
|
|
|
|
|
2408
|
|
|
|
|
|
|
=head2 accept_charset |
2409
|
|
|
|
|
|
|
|
2410
|
|
|
|
|
|
|
$h->accept( 'utf-8' ); |
2411
|
|
|
|
|
|
|
|
2412
|
|
|
|
|
|
|
Sets or gets the C<Accept-Charset> headers field value. It takes a single string value. |
2413
|
|
|
|
|
|
|
|
2414
|
|
|
|
|
|
|
You should know that the C<Accept-Charset> header is deprecated by HTTP standards and that no modern web browsers is sending nor any modern HTTP server recognising it. |
2415
|
|
|
|
|
|
|
|
2416
|
|
|
|
|
|
|
See L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Charset> |
2417
|
|
|
|
|
|
|
|
2418
|
|
|
|
|
|
|
=head2 accept_encoding |
2419
|
|
|
|
|
|
|
|
2420
|
|
|
|
|
|
|
$h->accept_encoding( 'gzip, deflate, br' ); |
2421
|
|
|
|
|
|
|
$h->accept_encoding( [qw( gzip deflate br )] ); |
2422
|
|
|
|
|
|
|
$h->accept_encoding( 'br;q=1.0, gzip;q=0.8, *;q=0.1' ); |
2423
|
|
|
|
|
|
|
|
2424
|
|
|
|
|
|
|
Sets or gets the C<Accept-Encoding> header field value. It takes either a string or an array or array reference of values. |
2425
|
|
|
|
|
|
|
|
2426
|
|
|
|
|
|
|
See also L<HTTP::Promise::Headers::AcceptEncoding> to have a more granular control. |
2427
|
|
|
|
|
|
|
|
2428
|
|
|
|
|
|
|
Encoding header fields and their nuances: |
2429
|
|
|
|
|
|
|
|
2430
|
|
|
|
|
|
|
=over 4 |
2431
|
|
|
|
|
|
|
|
2432
|
|
|
|
|
|
|
=item C<Accept-Encoding> |
2433
|
|
|
|
|
|
|
|
2434
|
|
|
|
|
|
|
The encodings accepted by the client. |
2435
|
|
|
|
|
|
|
|
2436
|
|
|
|
|
|
|
=item C<Content-Encoding> |
2437
|
|
|
|
|
|
|
|
2438
|
|
|
|
|
|
|
Contains the encodings that have been applied to the content, before transport |
2439
|
|
|
|
|
|
|
|
2440
|
|
|
|
|
|
|
=item C<TE> |
2441
|
|
|
|
|
|
|
|
2442
|
|
|
|
|
|
|
The encodings the user agent accepts. |
2443
|
|
|
|
|
|
|
|
2444
|
|
|
|
|
|
|
=item C<Transfer-Encoding> |
2445
|
|
|
|
|
|
|
|
2446
|
|
|
|
|
|
|
The encoding applied during transfer, such as C<chunked> |
2447
|
|
|
|
|
|
|
|
2448
|
|
|
|
|
|
|
=back |
2449
|
|
|
|
|
|
|
|
2450
|
|
|
|
|
|
|
See L<rfc7231, section 5.3.4|https://tools.ietf.org/html/rfc7231#section-5.3.4> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding> |
2451
|
|
|
|
|
|
|
|
2452
|
|
|
|
|
|
|
=head2 accept_language |
2453
|
|
|
|
|
|
|
|
2454
|
|
|
|
|
|
|
$h->accept_language( 'fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5' ); |
2455
|
|
|
|
|
|
|
$h->accept_language( [qw(fr-CH fr;q=0.9 en;q=0.8 de;q=0.7 *;q=0.5 )] ); |
2456
|
|
|
|
|
|
|
|
2457
|
|
|
|
|
|
|
Sets or gets the C<Accept-Language> header field value. It takes either a string or an array or array reference of values. |
2458
|
|
|
|
|
|
|
|
2459
|
|
|
|
|
|
|
See also L<HTTP::Promise::Headers::AcceptLanguage> to have a more granular control. |
2460
|
|
|
|
|
|
|
|
2461
|
|
|
|
|
|
|
See L<rfc7231, section 5.3.5|https://tools.ietf.org/html/rfc7231#section-5.3.5> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language> |
2462
|
|
|
|
|
|
|
|
2463
|
|
|
|
|
|
|
=head2 accept_patch |
2464
|
|
|
|
|
|
|
|
2465
|
|
|
|
|
|
|
$h->accept_patch( 'application/example, text/example' ); |
2466
|
|
|
|
|
|
|
$h->accept_patch( [qw( application/example text/example )] ); |
2467
|
|
|
|
|
|
|
$h->accept_patch( 'text/example;charset=utf-8' ); |
2468
|
|
|
|
|
|
|
$h->accept_patch( 'application/merge-patch+json' ); |
2469
|
|
|
|
|
|
|
|
2470
|
|
|
|
|
|
|
Sets or gets the C<Accept-Patch> header field value. It takes either a string or an array or array reference of values. |
2471
|
|
|
|
|
|
|
|
2472
|
|
|
|
|
|
|
This is a server response header. |
2473
|
|
|
|
|
|
|
|
2474
|
|
|
|
|
|
|
See L<rfc5789, section 3.1|https://tools.ietf.org/html/rfc5789#section-3.1>, L<rfc7231, section 4.3.4|https://tools.ietf.org/html/rfc7231#section-4.3.4> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Patch> |
2475
|
|
|
|
|
|
|
|
2476
|
|
|
|
|
|
|
=head2 accept_post |
2477
|
|
|
|
|
|
|
|
2478
|
|
|
|
|
|
|
$h->accept_post( 'application/example, text/example' ); |
2479
|
|
|
|
|
|
|
$h->accept_post( [qw( application/example text/example )] ); |
2480
|
|
|
|
|
|
|
$h->accept_post( 'image/webp' ); |
2481
|
|
|
|
|
|
|
$h->accept_post( '*/*' ); |
2482
|
|
|
|
|
|
|
|
2483
|
|
|
|
|
|
|
Sets or gets the C<Accept-Post> header field value. It takes either a string or an array or array reference of values. |
2484
|
|
|
|
|
|
|
|
2485
|
|
|
|
|
|
|
This is a server response header. |
2486
|
|
|
|
|
|
|
|
2487
|
|
|
|
|
|
|
See L<rfc7231, section 4.3.3|https://tools.ietf.org/html/rfc7231#section-4.3.3> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Post> |
2488
|
|
|
|
|
|
|
|
2489
|
|
|
|
|
|
|
=head2 accept_ranges |
2490
|
|
|
|
|
|
|
|
2491
|
|
|
|
|
|
|
$h->accept_ranges(1234); |
2492
|
|
|
|
|
|
|
|
2493
|
|
|
|
|
|
|
Sets or gets the C<Accept-Ranges> header field value. It takes either a string or an array or array reference of values. |
2494
|
|
|
|
|
|
|
|
2495
|
|
|
|
|
|
|
This is a server response header. |
2496
|
|
|
|
|
|
|
|
2497
|
|
|
|
|
|
|
See L<rfc7233, section 2.3|https://tools.ietf.org/html/rfc7233#section-2.3> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Ranges> |
2498
|
|
|
|
|
|
|
|
2499
|
|
|
|
|
|
|
=head2 acceptables |
2500
|
|
|
|
|
|
|
|
2501
|
|
|
|
|
|
|
This returns a new L<HTTP::Promise::Headers::Accept> object based on the content of the C<Accept> header value. |
2502
|
|
|
|
|
|
|
|
2503
|
|
|
|
|
|
|
=head2 age |
2504
|
|
|
|
|
|
|
|
2505
|
|
|
|
|
|
|
$h->age(1234); |
2506
|
|
|
|
|
|
|
|
2507
|
|
|
|
|
|
|
Sets or gets the C<Age> header field value. It takes a numeric value. |
2508
|
|
|
|
|
|
|
|
2509
|
|
|
|
|
|
|
This is a server response header. |
2510
|
|
|
|
|
|
|
|
2511
|
|
|
|
|
|
|
See L<rfc7234, section 5.1|https://tools.ietf.org/html/rfc7234#section-5.1> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Age> |
2512
|
|
|
|
|
|
|
|
2513
|
|
|
|
|
|
|
=head2 allow |
2514
|
|
|
|
|
|
|
|
2515
|
|
|
|
|
|
|
$h->allow( 'GET, POST, HEAD' ); |
2516
|
|
|
|
|
|
|
$h->allow( [qw( GET POST HEAD )] ); |
2517
|
|
|
|
|
|
|
|
2518
|
|
|
|
|
|
|
Sets or gets the C<Allow> header field value. It takes either a string or an array or array reference of values. |
2519
|
|
|
|
|
|
|
|
2520
|
|
|
|
|
|
|
This is a server response header. |
2521
|
|
|
|
|
|
|
|
2522
|
|
|
|
|
|
|
See L<rfc7231, section 7.4.1|https://tools.ietf.org/html/rfc7231#section-7.4.1> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Age> |
2523
|
|
|
|
|
|
|
|
2524
|
|
|
|
|
|
|
=head2 allow_credentials |
2525
|
|
|
|
|
|
|
|
2526
|
|
|
|
|
|
|
# Access-Control-Allow-Credentials: true |
2527
|
|
|
|
|
|
|
$h->allow_credentials( 'true' ); |
2528
|
|
|
|
|
|
|
|
2529
|
|
|
|
|
|
|
Sets or gets the C<Access-Control-Allow-Credentials> header field value. It takes a string boolean value: C<true> or C<false>. |
2530
|
|
|
|
|
|
|
|
2531
|
|
|
|
|
|
|
See L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials> |
2532
|
|
|
|
|
|
|
|
2533
|
|
|
|
|
|
|
=head2 allow_headers |
2534
|
|
|
|
|
|
|
|
2535
|
|
|
|
|
|
|
# Access-Control-Allow-Headers: X-Custom-Header, Upgrade-Insecure-Requests |
2536
|
|
|
|
|
|
|
$h->allow_headers( 'X-Custom-Header, Upgrade-Insecure-Requests' ); |
2537
|
|
|
|
|
|
|
$h->allow_headers( [qw( X-Custom-Header Upgrade-Insecure-Requests )] ); |
2538
|
|
|
|
|
|
|
|
2539
|
|
|
|
|
|
|
Sets or gets the C<Access-Control-Allow-Headers> header field value. It takes either a string or an array or array reference of values. |
2540
|
|
|
|
|
|
|
|
2541
|
|
|
|
|
|
|
This is a server response header. |
2542
|
|
|
|
|
|
|
|
2543
|
|
|
|
|
|
|
See L<rfc7231, section 7.4.1|https://tools.ietf.org/html/rfc7231#section-7.4.1> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Age> |
2544
|
|
|
|
|
|
|
|
2545
|
|
|
|
|
|
|
=head2 allow_methods |
2546
|
|
|
|
|
|
|
|
2547
|
|
|
|
|
|
|
# Access-Control-Allow-Methods: POST, GET, OPTIONS |
2548
|
|
|
|
|
|
|
$h->allow_methods( 'POST, GET, OPTIONS' ); |
2549
|
|
|
|
|
|
|
$h->allow_methods( [qw( POST GET OPTIONS )] ); |
2550
|
|
|
|
|
|
|
# Access-Control-Allow-Methods: * |
2551
|
|
|
|
|
|
|
$h->allow_methods( '*' ); |
2552
|
|
|
|
|
|
|
|
2553
|
|
|
|
|
|
|
Sets or gets the C<Access-Control-Allow-Methods> header field value. It takes either a string or an array or array reference of values. |
2554
|
|
|
|
|
|
|
|
2555
|
|
|
|
|
|
|
This is a server response header. |
2556
|
|
|
|
|
|
|
|
2557
|
|
|
|
|
|
|
See L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods> |
2558
|
|
|
|
|
|
|
|
2559
|
|
|
|
|
|
|
=head2 allow_origin |
2560
|
|
|
|
|
|
|
|
2561
|
|
|
|
|
|
|
# Access-Control-Allow-Origin: * |
2562
|
|
|
|
|
|
|
$h->allow_origin( '*' ); |
2563
|
|
|
|
|
|
|
# Access-Control-Allow-Origin: https://food.example.org |
2564
|
|
|
|
|
|
|
$h->allow_origin( 'https://food.example.org' ); |
2565
|
|
|
|
|
|
|
# Access-Control-Allow-Origin: null |
2566
|
|
|
|
|
|
|
$h->allow_origin( 'null' ); |
2567
|
|
|
|
|
|
|
|
2568
|
|
|
|
|
|
|
Sets or gets the C<Access-Control-Allow-Origin> header field value. It takes a string value. |
2569
|
|
|
|
|
|
|
|
2570
|
|
|
|
|
|
|
This is a server response header. |
2571
|
|
|
|
|
|
|
|
2572
|
|
|
|
|
|
|
See L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods> |
2573
|
|
|
|
|
|
|
|
2574
|
|
|
|
|
|
|
=head2 alt_svc |
2575
|
|
|
|
|
|
|
|
2576
|
|
|
|
|
|
|
# Alt-Svc: h2=":443"; ma=2592000; |
2577
|
|
|
|
|
|
|
$h->alt_svc( 'h2=":443"; ma=2592000' ); |
2578
|
|
|
|
|
|
|
# Alt-Svc: h2=":443"; ma=2592000; persist=1 |
2579
|
|
|
|
|
|
|
$h->alt_svc( 'h2=":443"; ma=2592000; persist=1' ); |
2580
|
|
|
|
|
|
|
# Alt-Svc: h2="alt.example.com:443", h2=":443" |
2581
|
|
|
|
|
|
|
$h->alt_svc( 'h2="alt.example.com:443", h2=":443"' ); |
2582
|
|
|
|
|
|
|
# Alt-Svc: h3-25=":443"; ma=3600, h2=":443"; ma=3600 |
2583
|
|
|
|
|
|
|
$h->alt_svc( 'h3-25=":443"; ma=3600, h2=":443"; ma=3600' ); |
2584
|
|
|
|
|
|
|
|
2585
|
|
|
|
|
|
|
Sets or gets the C<Alt-Svc> header field value. It takes either a string or an array or array reference of values. |
2586
|
|
|
|
|
|
|
|
2587
|
|
|
|
|
|
|
See also L<HTTP::Promise::Headers::AltSvc> to have a more granular control. |
2588
|
|
|
|
|
|
|
|
2589
|
|
|
|
|
|
|
See L<rfc7838, section 3|https://tools.ietf.org/html/rfc7838#section-3> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Alt-Svc> |
2590
|
|
|
|
|
|
|
|
2591
|
|
|
|
|
|
|
=head2 alternate_server |
2592
|
|
|
|
|
|
|
|
2593
|
|
|
|
|
|
|
This is a convenience method for the header field C<Alt-Svc>. |
2594
|
|
|
|
|
|
|
|
2595
|
|
|
|
|
|
|
To et it value, you provide a hash or hash reference of properties, including C<name> and C<value> respectively for the protocol-id and the alternate authority. |
2596
|
|
|
|
|
|
|
|
2597
|
|
|
|
|
|
|
$h->alternate_server( name => 'h2', value => ':443', ma => 2592000, persist => 1 ); |
2598
|
|
|
|
|
|
|
|
2599
|
|
|
|
|
|
|
would create the header value: |
2600
|
|
|
|
|
|
|
|
2601
|
|
|
|
|
|
|
Alt-Svc: h2=":443"; ma=2592000; persist=1 |
2602
|
|
|
|
|
|
|
|
2603
|
|
|
|
|
|
|
Without any parameter, it creates a new L<HTTP::Promise::Headers::AltSvc> object for each C<Alt-Svc> header value and returns an L<array object|Module::Generic::Array> of all those L<HTTP::Promise::Headers::AltSvc> objects. |
2604
|
|
|
|
|
|
|
|
2605
|
|
|
|
|
|
|
=head2 authorization |
2606
|
|
|
|
|
|
|
|
2607
|
|
|
|
|
|
|
# Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l |
2608
|
|
|
|
|
|
|
$h->authorization( 'Basic YWxhZGRpbjpvcGVuc2VzYW1l' ); |
2609
|
|
|
|
|
|
|
|
2610
|
|
|
|
|
|
|
Sets or gets the C<Authorization> header field value. It takes a string value. |
2611
|
|
|
|
|
|
|
|
2612
|
|
|
|
|
|
|
See also L</authorization_basic> |
2613
|
|
|
|
|
|
|
|
2614
|
|
|
|
|
|
|
See L<rfc7235, section 4.2|https://tools.ietf.org/html/rfc7235#section-4.2> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization> |
2615
|
|
|
|
|
|
|
|
2616
|
|
|
|
|
|
|
=head2 cache_control |
2617
|
|
|
|
|
|
|
|
2618
|
|
|
|
|
|
|
# Cache-Control: max-age=604800 |
2619
|
|
|
|
|
|
|
$h->cache_control( 'max-age=604800' ); |
2620
|
|
|
|
|
|
|
# Cache-Control: s-maxage=604800 |
2621
|
|
|
|
|
|
|
$h->cache_control( 's-maxage=604800' ); |
2622
|
|
|
|
|
|
|
# Cache-Control: no-cache |
2623
|
|
|
|
|
|
|
$h->cache_control( 'no-cache' ); |
2624
|
|
|
|
|
|
|
# Cache-Control: max-age=604800, must-revalidate |
2625
|
|
|
|
|
|
|
$h->cache_control( 'max-age=604800, must-revalidate' ); |
2626
|
|
|
|
|
|
|
# Cache-Control: public, max-age=604800, immutable |
2627
|
|
|
|
|
|
|
$h->cache_control( 'public, max-age=604800, immutable' ); |
2628
|
|
|
|
|
|
|
|
2629
|
|
|
|
|
|
|
Sets or gets the C<Cache-Control> header field value. It takes either a string or an array or array reference of values. |
2630
|
|
|
|
|
|
|
|
2631
|
|
|
|
|
|
|
See also L<HTTP::Promise::Headers::CacheControl> to have a more granular control. |
2632
|
|
|
|
|
|
|
|
2633
|
|
|
|
|
|
|
See L<rfc7234, section 5.2|https://tools.ietf.org/html/rfc7234#section-5.2> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control> |
2634
|
|
|
|
|
|
|
|
2635
|
|
|
|
|
|
|
=head2 clear_site_data |
2636
|
|
|
|
|
|
|
|
2637
|
|
|
|
|
|
|
# Clear-Site-Data: "cache", "cookies", "storage", "executionContexts" |
2638
|
|
|
|
|
|
|
$h->clear_site_data( q{"cache", "cookies", "storage", "executionContexts"} ); |
2639
|
|
|
|
|
|
|
$h->clear_site_data( [qw( cache cookies storage executionContexts )] ); |
2640
|
|
|
|
|
|
|
|
2641
|
|
|
|
|
|
|
The Clear-Site-Data header accepts one or more directives. If all types of data should be cleared, the wildcard directive ("*") can be used. |
2642
|
|
|
|
|
|
|
|
2643
|
|
|
|
|
|
|
See also L<HTTP::Promise::Headers::ClearSiteData> to have a more granular control. |
2644
|
|
|
|
|
|
|
|
2645
|
|
|
|
|
|
|
See L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Clear-Site-Data> |
2646
|
|
|
|
|
|
|
|
2647
|
|
|
|
|
|
|
=head2 connection |
2648
|
|
|
|
|
|
|
|
2649
|
|
|
|
|
|
|
# Connection: keep-alive |
2650
|
|
|
|
|
|
|
# Connection: close |
2651
|
|
|
|
|
|
|
|
2652
|
|
|
|
|
|
|
Sets or gets the C<Connection> header field value. It takes a string value. |
2653
|
|
|
|
|
|
|
|
2654
|
|
|
|
|
|
|
See L<rfc7230, section 6.1|https://tools.ietf.org/html/rfc7230#section-6.1> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Connection> |
2655
|
|
|
|
|
|
|
|
2656
|
|
|
|
|
|
|
=head2 content_disposition |
2657
|
|
|
|
|
|
|
|
2658
|
|
|
|
|
|
|
# Content-Disposition: inline |
2659
|
|
|
|
|
|
|
# Content-Disposition: attachment |
2660
|
|
|
|
|
|
|
# Content-Disposition: attachment; filename="filename.jpg" |
2661
|
|
|
|
|
|
|
# Content-Disposition: form-data; name="fieldName" |
2662
|
|
|
|
|
|
|
# Content-Disposition: form-data; name="fieldName"; filename="filename.jpg" |
2663
|
|
|
|
|
|
|
|
2664
|
|
|
|
|
|
|
Sets or gets the C<Content-Disposition> header field value. It takes a string value. |
2665
|
|
|
|
|
|
|
|
2666
|
|
|
|
|
|
|
See also L<HTTP::Promise::Headers::ContentDisposition> to have a more granular control. |
2667
|
|
|
|
|
|
|
|
2668
|
|
|
|
|
|
|
See L<rfc6266, section 4|https://tools.ietf.org/html/rfc6266#section-4>, L<rfc7578, section 4.2|https://tools.ietf.org/html/rfc7578#section-4.2> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition> |
2669
|
|
|
|
|
|
|
|
2670
|
|
|
|
|
|
|
=head2 content_encoding |
2671
|
|
|
|
|
|
|
|
2672
|
|
|
|
|
|
|
# Content-Encoding: gzip |
2673
|
|
|
|
|
|
|
# Content-Encoding: compress |
2674
|
|
|
|
|
|
|
# Content-Encoding: deflate |
2675
|
|
|
|
|
|
|
# Content-Encoding: br |
2676
|
|
|
|
|
|
|
|
2677
|
|
|
|
|
|
|
# Multiple, in the order in which they were applied |
2678
|
|
|
|
|
|
|
# Content-Encoding: deflate, gzip |
2679
|
|
|
|
|
|
|
|
2680
|
|
|
|
|
|
|
Sets or gets the C<Cache-Encoding> header field value. It takes either a string or an array or array reference of values. |
2681
|
|
|
|
|
|
|
|
2682
|
|
|
|
|
|
|
Encoding header fields and their nuances: |
2683
|
|
|
|
|
|
|
|
2684
|
|
|
|
|
|
|
=over 4 |
2685
|
|
|
|
|
|
|
|
2686
|
|
|
|
|
|
|
=item C<Accept-Encoding> |
2687
|
|
|
|
|
|
|
|
2688
|
|
|
|
|
|
|
The encodings accepted by the client. |
2689
|
|
|
|
|
|
|
|
2690
|
|
|
|
|
|
|
=item C<Content-Encoding> |
2691
|
|
|
|
|
|
|
|
2692
|
|
|
|
|
|
|
Contains the encodings that have been applied to the content, before transport |
2693
|
|
|
|
|
|
|
|
2694
|
|
|
|
|
|
|
=item C<TE> |
2695
|
|
|
|
|
|
|
|
2696
|
|
|
|
|
|
|
The encodings the user agent accepts. |
2697
|
|
|
|
|
|
|
|
2698
|
|
|
|
|
|
|
=item C<Transfer-Encoding> |
2699
|
|
|
|
|
|
|
|
2700
|
|
|
|
|
|
|
The encoding applied during transfer, such as C<chunked> |
2701
|
|
|
|
|
|
|
|
2702
|
|
|
|
|
|
|
=back |
2703
|
|
|
|
|
|
|
|
2704
|
|
|
|
|
|
|
See L<rfc7230, section 3.3.1|https://tools.ietf.org/html/rfc7230#section-3.3.1>: |
2705
|
|
|
|
|
|
|
"Unlike Content-Encoding (L<Section 3.1.2.1 of [RFC7231]|https://tools.ietf.org/html/rfc7231#section-3.1.2.1>), Transfer-Encoding is a property of the message, not of the representation" |
2706
|
|
|
|
|
|
|
|
2707
|
|
|
|
|
|
|
See also L</accept_encoding>, L</transfer_encoding> and L</te> and this L<Stackoverflow discussion|https://stackoverflow.com/questions/11641923/transfer-encoding-gzip-vs-content-encoding-gzip> |
2708
|
|
|
|
|
|
|
|
2709
|
|
|
|
|
|
|
See L<rfc7231, section 3.1.2.2|https://tools.ietf.org/html/rfc7231#section-3.1.2.2> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding> |
2710
|
|
|
|
|
|
|
|
2711
|
|
|
|
|
|
|
=head2 content_language |
2712
|
|
|
|
|
|
|
|
2713
|
|
|
|
|
|
|
# Content-Language: de-DE |
2714
|
|
|
|
|
|
|
# Content-Language: en-US |
2715
|
|
|
|
|
|
|
$h->content_language( 'en-GB' ); |
2716
|
|
|
|
|
|
|
# Content-Language: de-DE, en-CA |
2717
|
|
|
|
|
|
|
$h->content_language( 'de-DE, en-CA' ); |
2718
|
|
|
|
|
|
|
$h->content_language( [qw( de-DE en-CA )] ); |
2719
|
|
|
|
|
|
|
|
2720
|
|
|
|
|
|
|
Sets or gets the C<Cache-Language> header field value. It takes either a string or an array or array reference of values. |
2721
|
|
|
|
|
|
|
|
2722
|
|
|
|
|
|
|
There is no enforcement on the value provided, so it is up to you to set the proper value or values. |
2723
|
|
|
|
|
|
|
|
2724
|
|
|
|
|
|
|
See L<rfc7231, section 3.1.3.2|https://tools.ietf.org/html/rfc7231#section-3.1.3.2>, L<rfc5646|https://tools.ietf.org/html/rfc5646> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Language> |
2725
|
|
|
|
|
|
|
|
2726
|
|
|
|
|
|
|
=head2 content_length |
2727
|
|
|
|
|
|
|
|
2728
|
|
|
|
|
|
|
# Content-Length: 72 |
2729
|
|
|
|
|
|
|
$h->content_length(72); |
2730
|
|
|
|
|
|
|
|
2731
|
|
|
|
|
|
|
Sets or gets the C<Connection> header field value. It takes a numeric value. |
2732
|
|
|
|
|
|
|
|
2733
|
|
|
|
|
|
|
See L<rfc7230, section 3.3.2|https://tools.ietf.org/html/rfc7230#section-3.3.2> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Length> |
2734
|
|
|
|
|
|
|
|
2735
|
|
|
|
|
|
|
=head2 content_location |
2736
|
|
|
|
|
|
|
|
2737
|
|
|
|
|
|
|
# Content-Location: /some/where/file.html |
2738
|
|
|
|
|
|
|
$h->content_location( '/some/where/file.html' ); |
2739
|
|
|
|
|
|
|
|
2740
|
|
|
|
|
|
|
Sets or gets the C<Connection> header field value. It takes a numeric value. |
2741
|
|
|
|
|
|
|
|
2742
|
|
|
|
|
|
|
See L<rfc7231, section 3.1.4.2|https://tools.ietf.org/html/rfc7231#section-3.1.4.2> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Location> |
2743
|
|
|
|
|
|
|
|
2744
|
|
|
|
|
|
|
=head2 content_range |
2745
|
|
|
|
|
|
|
|
2746
|
|
|
|
|
|
|
# Content-Range: bytes 200-1000/67589 |
2747
|
|
|
|
|
|
|
# Unsatisfiable range value |
2748
|
|
|
|
|
|
|
# Content-Range: bytes */1234 |
2749
|
|
|
|
|
|
|
|
2750
|
|
|
|
|
|
|
Sets or gets the C<Content-Range> header field value. It takes a string value. |
2751
|
|
|
|
|
|
|
|
2752
|
|
|
|
|
|
|
See also L<HTTP::Promise::Headers::ContentRange> to have a more granular control. |
2753
|
|
|
|
|
|
|
|
2754
|
|
|
|
|
|
|
See L<rfc7233, section 4.2|https://tools.ietf.org/html/rfc7233#section-4.2> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Range> |
2755
|
|
|
|
|
|
|
|
2756
|
|
|
|
|
|
|
=head2 content_security_policy |
2757
|
|
|
|
|
|
|
|
2758
|
|
|
|
|
|
|
# Content-Security-Policy: default-src 'self' http://example.com; |
2759
|
|
|
|
|
|
|
# connect-src 'none'; |
2760
|
|
|
|
|
|
|
# Content-Security-Policy: connect-src http://example.com/; |
2761
|
|
|
|
|
|
|
# script-src http://example.com/ |
2762
|
|
|
|
|
|
|
|
2763
|
|
|
|
|
|
|
Sets or gets the C<Content-Security-Policy> header field value. It takes a string value. |
2764
|
|
|
|
|
|
|
|
2765
|
|
|
|
|
|
|
See also L<HTTP::Promise::Headers::ContentSecurityPolicy> to have a more granular control. |
2766
|
|
|
|
|
|
|
|
2767
|
|
|
|
|
|
|
See L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy> |
2768
|
|
|
|
|
|
|
|
2769
|
|
|
|
|
|
|
=head2 content_security_policy_report_only |
2770
|
|
|
|
|
|
|
|
2771
|
|
|
|
|
|
|
# Content-Security-Policy-Report-Only: default-src https:; report-uri /csp-violation-report-endpoint/ |
2772
|
|
|
|
|
|
|
|
2773
|
|
|
|
|
|
|
Sets or gets the C<Content-Security-Policy-Report-Only> header field value. It takes a string value of properly formatted header value. |
2774
|
|
|
|
|
|
|
|
2775
|
|
|
|
|
|
|
See also L<HTTP::Promise::Headers::ContentSecurityPolicyReportOnly> to have a more granular control. |
2776
|
|
|
|
|
|
|
|
2777
|
|
|
|
|
|
|
=head2 content_type |
2778
|
|
|
|
|
|
|
|
2779
|
|
|
|
|
|
|
This sets or gets the C<Content-Type> header value. It takes a string value. |
2780
|
|
|
|
|
|
|
|
2781
|
|
|
|
|
|
|
If a value is provided, this will set the header value. If no value is provided, this simply return the header field value. |
2782
|
|
|
|
|
|
|
|
2783
|
|
|
|
|
|
|
See also L<HTTP::Promise::Headers::ContentType> to have a more granular control. |
2784
|
|
|
|
|
|
|
|
2785
|
|
|
|
|
|
|
See also L<rfc7233, section 4.1|https://tools.ietf.org/html/rfc7233#section-4.1>, L<rfc7231, section 3.1.1.5|https://tools.ietf.org/html/rfc7231#section-3.1.1.5> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types>, and L<this Mozilla documentation too|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type> |
2786
|
|
|
|
|
|
|
|
2787
|
|
|
|
|
|
|
=head2 cross_origin_embedder_policy |
2788
|
|
|
|
|
|
|
|
2789
|
|
|
|
|
|
|
# Cross-Origin-Embedder-Policy: require-corp |
2790
|
|
|
|
|
|
|
# Cross-Origin-Opener-Policy: same-origin |
2791
|
|
|
|
|
|
|
|
2792
|
|
|
|
|
|
|
This sets or gets the C<Cross-Origin-Embedder-Policy> header value. It takes a string value. |
2793
|
|
|
|
|
|
|
|
2794
|
|
|
|
|
|
|
It can have either of the following value: C<require-corp> or C<same-origin> |
2795
|
|
|
|
|
|
|
|
2796
|
|
|
|
|
|
|
See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy> |
2797
|
|
|
|
|
|
|
|
2798
|
|
|
|
|
|
|
=head2 cross_origin_opener_policy |
2799
|
|
|
|
|
|
|
|
2800
|
|
|
|
|
|
|
# Cross-Origin-Opener-Policy: unsafe-none |
2801
|
|
|
|
|
|
|
# Cross-Origin-Opener-Policy: same-origin-allow-popups |
2802
|
|
|
|
|
|
|
# Cross-Origin-Opener-Policy: same-origin |
2803
|
|
|
|
|
|
|
|
2804
|
|
|
|
|
|
|
This sets or gets the C<Cross-Origin-Opener-Policy> header value. It takes a string value. |
2805
|
|
|
|
|
|
|
|
2806
|
|
|
|
|
|
|
It can have either of the following value: C<unsafe-none> or C<same-origin-allow-popups> or C<same-origin> |
2807
|
|
|
|
|
|
|
|
2808
|
|
|
|
|
|
|
See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy> |
2809
|
|
|
|
|
|
|
|
2810
|
|
|
|
|
|
|
=head2 cross_origin_resource_policy |
2811
|
|
|
|
|
|
|
|
2812
|
|
|
|
|
|
|
This sets or gets the C<Cross-Origin-Resource-Policy> header value. It takes a string value. |
2813
|
|
|
|
|
|
|
|
2814
|
|
|
|
|
|
|
It can have either of the following value: C<same-site> or C<same-origin> or C<same-origin> |
2815
|
|
|
|
|
|
|
|
2816
|
|
|
|
|
|
|
See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Resource-Policy> |
2817
|
|
|
|
|
|
|
|
2818
|
|
|
|
|
|
|
For more example: L<https://resourcepolicy.fyi/> |
2819
|
|
|
|
|
|
|
|
2820
|
|
|
|
|
|
|
=head2 cspro |
2821
|
|
|
|
|
|
|
|
2822
|
|
|
|
|
|
|
This is an alias for L</content_security_policy_report_only> |
2823
|
|
|
|
|
|
|
|
2824
|
|
|
|
|
|
|
=head2 date |
2825
|
|
|
|
|
|
|
|
2826
|
|
|
|
|
|
|
This sets or gets the C<Date> header value. It takes a date string value, a unix timestamp or a L<DateTime> value. |
2827
|
|
|
|
|
|
|
|
2828
|
|
|
|
|
|
|
If no value is provided, it returns the current value of the C<Date> header field as a L<DateTime> object. |
2829
|
|
|
|
|
|
|
|
2830
|
|
|
|
|
|
|
=head2 device_memory |
2831
|
|
|
|
|
|
|
|
2832
|
|
|
|
|
|
|
# Device-Memory: 1 |
2833
|
|
|
|
|
|
|
|
2834
|
|
|
|
|
|
|
This sets or gets the C<Device-Memory> header value. It takes a number. |
2835
|
|
|
|
|
|
|
|
2836
|
|
|
|
|
|
|
L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Device-Memory> |
2837
|
|
|
|
|
|
|
|
2838
|
|
|
|
|
|
|
=head2 digest |
2839
|
|
|
|
|
|
|
|
2840
|
|
|
|
|
|
|
# Digest: sha-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE= |
2841
|
|
|
|
|
|
|
# Digest: sha-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=,unixsum=30637 |
2842
|
|
|
|
|
|
|
|
2843
|
|
|
|
|
|
|
This sets or gets the C<Digest> header value. It takes either a string or an array or array reference of properly formatted values. |
2844
|
|
|
|
|
|
|
|
2845
|
|
|
|
|
|
|
See L<draft rfc|https://tools.ietf.org/html/draft-ietf-httpbis-digest-headers-05#section-3> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Digest> |
2846
|
|
|
|
|
|
|
|
2847
|
|
|
|
|
|
|
=head2 dnt |
2848
|
|
|
|
|
|
|
|
2849
|
|
|
|
|
|
|
# DNT: 0 |
2850
|
|
|
|
|
|
|
# DNT: 1 |
2851
|
|
|
|
|
|
|
# DNT: null |
2852
|
|
|
|
|
|
|
|
2853
|
|
|
|
|
|
|
This sets or gets the C<DNT> header value. It takes a string value. |
2854
|
|
|
|
|
|
|
|
2855
|
|
|
|
|
|
|
See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/DNT> |
2856
|
|
|
|
|
|
|
|
2857
|
|
|
|
|
|
|
=head2 early_data |
2858
|
|
|
|
|
|
|
|
2859
|
|
|
|
|
|
|
# Early-Data: 1 |
2860
|
|
|
|
|
|
|
|
2861
|
|
|
|
|
|
|
This sets or gets the C<Early-Data> header value. It takes a string value. |
2862
|
|
|
|
|
|
|
|
2863
|
|
|
|
|
|
|
See also L<rfc8470, section 5.1|https://tools.ietf.org/html/rfc8470#section-5.1> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Early-Data> |
2864
|
|
|
|
|
|
|
|
2865
|
|
|
|
|
|
|
=head2 etag |
2866
|
|
|
|
|
|
|
|
2867
|
|
|
|
|
|
|
# ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4" |
2868
|
|
|
|
|
|
|
# ETag: W/"0815" |
2869
|
|
|
|
|
|
|
|
2870
|
|
|
|
|
|
|
This sets or gets the C<Etag> header value. It takes a string of properly formatted value. |
2871
|
|
|
|
|
|
|
|
2872
|
|
|
|
|
|
|
See also L<rfc7232, section 2.3|https://tools.ietf.org/html/rfc7232#section-2.3> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag> |
2873
|
|
|
|
|
|
|
|
2874
|
|
|
|
|
|
|
=head2 expect |
2875
|
|
|
|
|
|
|
|
2876
|
|
|
|
|
|
|
This sets or gets the C<Expect> header value. It takes a string of properly formatted value, typically C<100-continue> |
2877
|
|
|
|
|
|
|
|
2878
|
|
|
|
|
|
|
For example, before sending a very large file: |
2879
|
|
|
|
|
|
|
|
2880
|
|
|
|
|
|
|
PUT /some/where HTTP/1.1 |
2881
|
|
|
|
|
|
|
Host: origin.example.com |
2882
|
|
|
|
|
|
|
Content-Type: video/h264 |
2883
|
|
|
|
|
|
|
Content-Length: 1234567890987 |
2884
|
|
|
|
|
|
|
Expect: 100-continue |
2885
|
|
|
|
|
|
|
|
2886
|
|
|
|
|
|
|
If the server is ok, it would return a C<100 Continue> |
2887
|
|
|
|
|
|
|
|
2888
|
|
|
|
|
|
|
See also L<rfc7231, section 5.1.1|https://tools.ietf.org/html/rfc7231#section-5.1.1> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expect>, L<interesting article|https://www.bram.us/2020/04/14/about-the-http-expect-100-continue-header/> |
2889
|
|
|
|
|
|
|
|
2890
|
|
|
|
|
|
|
=head2 expect_ct |
2891
|
|
|
|
|
|
|
|
2892
|
|
|
|
|
|
|
# Expect-CT: max-age=86400, enforce, report-uri="https://foo.example.com/report" |
2893
|
|
|
|
|
|
|
$h->expect_ct( q{max-age=86400, enforce, report-uri="https://foo.example.com/report"} ); |
2894
|
|
|
|
|
|
|
$h->expect_ct( [qw( max-age=86400 enforce report-uri="https://foo.example.com/report" )] ); |
2895
|
|
|
|
|
|
|
|
2896
|
|
|
|
|
|
|
This sets or gets the C<Expect-CT> header value. It takes a string of properly formatted value. |
2897
|
|
|
|
|
|
|
|
2898
|
|
|
|
|
|
|
See also L<HTTP::Promise::Headers::ExpectCT> to have a more granular control. |
2899
|
|
|
|
|
|
|
|
2900
|
|
|
|
|
|
|
See also L<rfc draft|https://tools.ietf.org/html/draft-ietf-httpbis-expect-ct-08> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expect-CT> |
2901
|
|
|
|
|
|
|
|
2902
|
|
|
|
|
|
|
=head2 expires |
2903
|
|
|
|
|
|
|
|
2904
|
|
|
|
|
|
|
This sets or gets the C<Expires> header value. It takes a date string value, a unix timestamp or a L<DateTime> value. |
2905
|
|
|
|
|
|
|
|
2906
|
|
|
|
|
|
|
If no value is provided, it returns the current value of the C<Date> header field as a L<DateTime> object. |
2907
|
|
|
|
|
|
|
|
2908
|
|
|
|
|
|
|
For example: |
2909
|
|
|
|
|
|
|
|
2910
|
|
|
|
|
|
|
Expires: Wed, 21 Oct 2015 07:28:00 GMT |
2911
|
|
|
|
|
|
|
|
2912
|
|
|
|
|
|
|
See also L<rfc7234, section 5.3|https://tools.ietf.org/html/rfc7234#section-5.3> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expires> |
2913
|
|
|
|
|
|
|
|
2914
|
|
|
|
|
|
|
=head2 expose_headers |
2915
|
|
|
|
|
|
|
|
2916
|
|
|
|
|
|
|
This sets or gets the C<Expose-Headers> header value. It takes either a string or an array or array reference of properly formatted values. |
2917
|
|
|
|
|
|
|
|
2918
|
|
|
|
|
|
|
For example: |
2919
|
|
|
|
|
|
|
|
2920
|
|
|
|
|
|
|
Access-Control-Expose-Headers: *, Authorization |
2921
|
|
|
|
|
|
|
|
2922
|
|
|
|
|
|
|
See also L<rfc7234, section 5.3|https://tools.ietf.org/html/rfc7234#section-5.3> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers> |
2923
|
|
|
|
|
|
|
|
2924
|
|
|
|
|
|
|
=head2 forwarded |
2925
|
|
|
|
|
|
|
|
2926
|
|
|
|
|
|
|
This sets or gets the C<Forwarded> header value. It takes either a string or an array or array reference of properly formatted values. |
2927
|
|
|
|
|
|
|
|
2928
|
|
|
|
|
|
|
See also L<HTTP::Promise::Headers::Forwarded> to have a more granular control. |
2929
|
|
|
|
|
|
|
|
2930
|
|
|
|
|
|
|
For example: |
2931
|
|
|
|
|
|
|
|
2932
|
|
|
|
|
|
|
Forwarded: for=192.0.2.60;proto=http;by=203.0.113.43 |
2933
|
|
|
|
|
|
|
# Values from multiple proxy servers can be appended using a comma |
2934
|
|
|
|
|
|
|
Forwarded: for=192.0.2.43, for=198.51.100.17 |
2935
|
|
|
|
|
|
|
|
2936
|
|
|
|
|
|
|
See also L<rfc7239, section 4|https://tools.ietf.org/html/rfc7239#section-4> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded> |
2937
|
|
|
|
|
|
|
|
2938
|
|
|
|
|
|
|
=head2 from |
2939
|
|
|
|
|
|
|
|
2940
|
|
|
|
|
|
|
This sets or gets the C<From> header value. It takes a string value. |
2941
|
|
|
|
|
|
|
|
2942
|
|
|
|
|
|
|
For example: |
2943
|
|
|
|
|
|
|
|
2944
|
|
|
|
|
|
|
From: webmaster@example.org |
2945
|
|
|
|
|
|
|
|
2946
|
|
|
|
|
|
|
See also L<rfc7231, section 5.5.1|https://tools.ietf.org/html/rfc7231#section-5.5.1> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/From> |
2947
|
|
|
|
|
|
|
|
2948
|
|
|
|
|
|
|
=head2 host |
2949
|
|
|
|
|
|
|
|
2950
|
|
|
|
|
|
|
This sets or gets the C<Host> header value. It takes a string value. |
2951
|
|
|
|
|
|
|
|
2952
|
|
|
|
|
|
|
For example: |
2953
|
|
|
|
|
|
|
|
2954
|
|
|
|
|
|
|
Host: dev.example.org |
2955
|
|
|
|
|
|
|
|
2956
|
|
|
|
|
|
|
See also L<rfc7230, section 5.4|https://tools.ietf.org/html/rfc7230#section-5.4> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Host> |
2957
|
|
|
|
|
|
|
|
2958
|
|
|
|
|
|
|
=head2 if_match |
2959
|
|
|
|
|
|
|
|
2960
|
|
|
|
|
|
|
This sets or gets the C<If-Match> header value. It takes a string value. |
2961
|
|
|
|
|
|
|
|
2962
|
|
|
|
|
|
|
For example: |
2963
|
|
|
|
|
|
|
|
2964
|
|
|
|
|
|
|
If-Match: "bfc13a64729c4290ef5b2c2730249c88ca92d82d" |
2965
|
|
|
|
|
|
|
If-Match: "67ab43", "54ed21", "7892dd" |
2966
|
|
|
|
|
|
|
If-Match: * |
2967
|
|
|
|
|
|
|
|
2968
|
|
|
|
|
|
|
See also L<rfc7232, section 3.1|https://tools.ietf.org/html/rfc7232#section-3.1> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Match> |
2969
|
|
|
|
|
|
|
|
2970
|
|
|
|
|
|
|
=head2 if_modified_since |
2971
|
|
|
|
|
|
|
|
2972
|
|
|
|
|
|
|
This sets or gets the C<If-Modified-Since> header value. It takes a date string value, a unix timestamp or a L<DateTime> value. |
2973
|
|
|
|
|
|
|
|
2974
|
|
|
|
|
|
|
If no value is provided, it returns the current value of the C<Date> header field as a L<DateTime> object. |
2975
|
|
|
|
|
|
|
|
2976
|
|
|
|
|
|
|
For example: |
2977
|
|
|
|
|
|
|
|
2978
|
|
|
|
|
|
|
If-Modified-Since: Wed, 21 Oct 2015 07:28:00 GMT |
2979
|
|
|
|
|
|
|
|
2980
|
|
|
|
|
|
|
See also L<rfc7232, section 3.3|https://tools.ietf.org/html/rfc7232#section-3.3> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Modified-Since> |
2981
|
|
|
|
|
|
|
|
2982
|
|
|
|
|
|
|
=head2 if_none_match |
2983
|
|
|
|
|
|
|
|
2984
|
|
|
|
|
|
|
This sets or gets the C<If-None-Match> header value. It takes a string value. |
2985
|
|
|
|
|
|
|
|
2986
|
|
|
|
|
|
|
For example: |
2987
|
|
|
|
|
|
|
|
2988
|
|
|
|
|
|
|
If-None-Match: "bfc13a64729c4290ef5b2c2730249c88ca92d82d" |
2989
|
|
|
|
|
|
|
If-None-Match: W/"67ab43", "54ed21", "7892dd" |
2990
|
|
|
|
|
|
|
If-None-Match: * |
2991
|
|
|
|
|
|
|
|
2992
|
|
|
|
|
|
|
See also L<rfc7232, section 3.2|https://tools.ietf.org/html/rfc7232#section-3.2> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Modified-Since> |
2993
|
|
|
|
|
|
|
|
2994
|
|
|
|
|
|
|
=head2 if_range |
2995
|
|
|
|
|
|
|
|
2996
|
|
|
|
|
|
|
This sets or gets the C<If-Range> header value. It takes a string value. |
2997
|
|
|
|
|
|
|
|
2998
|
|
|
|
|
|
|
For example: |
2999
|
|
|
|
|
|
|
|
3000
|
|
|
|
|
|
|
If-Range: Wed, 21 Oct 2015 07:28:00 GMT |
3001
|
|
|
|
|
|
|
|
3002
|
|
|
|
|
|
|
See also L<rfc7233, section 3.2|https://tools.ietf.org/html/rfc7233#section-3.2> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Range> |
3003
|
|
|
|
|
|
|
|
3004
|
|
|
|
|
|
|
=head2 if_unmodified_since |
3005
|
|
|
|
|
|
|
|
3006
|
|
|
|
|
|
|
This sets or gets the C<If-Unmodified-Since> header value. It takes a date string value, a unix timestamp or a L<DateTime> value. |
3007
|
|
|
|
|
|
|
|
3008
|
|
|
|
|
|
|
If no value is provided, it returns the current value of the C<Date> header field as a L<DateTime> object. |
3009
|
|
|
|
|
|
|
|
3010
|
|
|
|
|
|
|
For example: |
3011
|
|
|
|
|
|
|
|
3012
|
|
|
|
|
|
|
If-Unmodified-Since: Wed, 21 Oct 2015 07:28:00 GMT |
3013
|
|
|
|
|
|
|
|
3014
|
|
|
|
|
|
|
See also L<rfc7232, section 3.4|https://tools.ietf.org/html/rfc7232#section-3.4> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Unmodified-Since> |
3015
|
|
|
|
|
|
|
|
3016
|
|
|
|
|
|
|
=head2 keep_alive |
3017
|
|
|
|
|
|
|
|
3018
|
|
|
|
|
|
|
This sets or gets the C<Keep-Alive> header value. It takes either a string or an array or array reference of properly formatted values. |
3019
|
|
|
|
|
|
|
|
3020
|
|
|
|
|
|
|
See also L<HTTP::Promise::Headers::KeepAlive> to have a more granular control. |
3021
|
|
|
|
|
|
|
|
3022
|
|
|
|
|
|
|
Example response containing a Keep-Alive header: |
3023
|
|
|
|
|
|
|
|
3024
|
|
|
|
|
|
|
HTTP/1.1 200 OK |
3025
|
|
|
|
|
|
|
Connection: Keep-Alive |
3026
|
|
|
|
|
|
|
Content-Encoding: gzip |
3027
|
|
|
|
|
|
|
Content-Type: text/html; charset=utf-8 |
3028
|
|
|
|
|
|
|
Date: Thu, 11 Aug 2016 15:23:13 GMT |
3029
|
|
|
|
|
|
|
Keep-Alive: timeout=5, max=1000 |
3030
|
|
|
|
|
|
|
Last-Modified: Mon, 25 Jul 2016 04:32:39 GMT |
3031
|
|
|
|
|
|
|
Server: Apache |
3032
|
|
|
|
|
|
|
|
3033
|
|
|
|
|
|
|
See also L<rfc7230, section A.1.2|https://tools.ietf.org/html/rfc7230#section-A.1.2> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Keep-Alive> |
3034
|
|
|
|
|
|
|
|
3035
|
|
|
|
|
|
|
=head2 last_modified |
3036
|
|
|
|
|
|
|
|
3037
|
|
|
|
|
|
|
This sets or gets the C<Last-Modified> header value. It takes a date string value, a unix timestamp or a L<DateTime> value. |
3038
|
|
|
|
|
|
|
|
3039
|
|
|
|
|
|
|
If no value is provided, it returns the current value of the C<Date> header field as a L<DateTime> object. |
3040
|
|
|
|
|
|
|
|
3041
|
|
|
|
|
|
|
For example: |
3042
|
|
|
|
|
|
|
|
3043
|
|
|
|
|
|
|
Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT |
3044
|
|
|
|
|
|
|
|
3045
|
|
|
|
|
|
|
See also L<rfc7232, section 2.2|https://tools.ietf.org/html/rfc7232#section-2.2> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified> |
3046
|
|
|
|
|
|
|
|
3047
|
|
|
|
|
|
|
=head2 link |
3048
|
|
|
|
|
|
|
|
3049
|
|
|
|
|
|
|
This sets or gets the C<Link> header value. It takes a string value. |
3050
|
|
|
|
|
|
|
|
3051
|
|
|
|
|
|
|
See also L<HTTP::Promise::Headers::Link> to have a more granular control. |
3052
|
|
|
|
|
|
|
|
3053
|
|
|
|
|
|
|
Example: |
3054
|
|
|
|
|
|
|
|
3055
|
|
|
|
|
|
|
Link: <https://example.com>; rel="preconnect" |
3056
|
|
|
|
|
|
|
|
3057
|
|
|
|
|
|
|
See also L<rfc8288, section 3|https://tools.ietf.org/html/rfc8288#section-3> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Link> |
3058
|
|
|
|
|
|
|
|
3059
|
|
|
|
|
|
|
=head2 location |
3060
|
|
|
|
|
|
|
|
3061
|
|
|
|
|
|
|
This sets or gets the C<Location> header value. It takes a string value. |
3062
|
|
|
|
|
|
|
|
3063
|
|
|
|
|
|
|
Example: |
3064
|
|
|
|
|
|
|
|
3065
|
|
|
|
|
|
|
Location: /index.html |
3066
|
|
|
|
|
|
|
|
3067
|
|
|
|
|
|
|
See also L<rfc7231, section 7.1.2|https://tools.ietf.org/html/rfc7231#section-7.1.2> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Location> |
3068
|
|
|
|
|
|
|
|
3069
|
|
|
|
|
|
|
=head2 max_age |
3070
|
|
|
|
|
|
|
|
3071
|
|
|
|
|
|
|
This sets or gets the C<Location> header value. It takes a numeric value. |
3072
|
|
|
|
|
|
|
|
3073
|
|
|
|
|
|
|
Example: |
3074
|
|
|
|
|
|
|
|
3075
|
|
|
|
|
|
|
Access-Control-Max-Age: 600 |
3076
|
|
|
|
|
|
|
|
3077
|
|
|
|
|
|
|
See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age> |
3078
|
|
|
|
|
|
|
|
3079
|
|
|
|
|
|
|
=head2 nel |
3080
|
|
|
|
|
|
|
|
3081
|
|
|
|
|
|
|
This sets or gets the C<NEL> header value. It takes a string of properly formatted json value. |
3082
|
|
|
|
|
|
|
|
3083
|
|
|
|
|
|
|
Example: |
3084
|
|
|
|
|
|
|
|
3085
|
|
|
|
|
|
|
NEL: { "report_to": "name_of_reporting_group", "max_age": 12345, "include_subdomains": false, "success_fraction": 0.0, "failure_fraction": 1.0 } |
3086
|
|
|
|
|
|
|
|
3087
|
|
|
|
|
|
|
See also L<rfc8288, section 3|https://tools.ietf.org/html/rfc8288#section-3> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/NEL> |
3088
|
|
|
|
|
|
|
|
3089
|
|
|
|
|
|
|
=for Pod::Coverage new_array |
3090
|
|
|
|
|
|
|
|
3091
|
|
|
|
|
|
|
=for Pod::Coverage new_field |
3092
|
|
|
|
|
|
|
|
3093
|
|
|
|
|
|
|
=for Pod::Coverage new_number |
3094
|
|
|
|
|
|
|
|
3095
|
|
|
|
|
|
|
=for Pod::Coverage new_scalar |
3096
|
|
|
|
|
|
|
|
3097
|
|
|
|
|
|
|
=head2 origin |
3098
|
|
|
|
|
|
|
|
3099
|
|
|
|
|
|
|
This sets or gets the C<Origin> header value. It takes a string of properly formatted json value. |
3100
|
|
|
|
|
|
|
|
3101
|
|
|
|
|
|
|
Example: |
3102
|
|
|
|
|
|
|
|
3103
|
|
|
|
|
|
|
Origin: http://dev.example.org:80 |
3104
|
|
|
|
|
|
|
|
3105
|
|
|
|
|
|
|
See also L<rfc6454, section 7|https://tools.ietf.org/html/rfc6454#section-7> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin> |
3106
|
|
|
|
|
|
|
|
3107
|
|
|
|
|
|
|
=for Pod::Coverage pass_error |
3108
|
|
|
|
|
|
|
|
3109
|
|
|
|
|
|
|
=head2 proxy |
3110
|
|
|
|
|
|
|
|
3111
|
|
|
|
|
|
|
Sets or gets the URI used for the proxy. It returns a L<URI> object. |
3112
|
|
|
|
|
|
|
|
3113
|
|
|
|
|
|
|
=head2 proxy_authenticate |
3114
|
|
|
|
|
|
|
|
3115
|
|
|
|
|
|
|
This sets or gets the C<Proxy-Authenticate> header value. It takes a string value. |
3116
|
|
|
|
|
|
|
|
3117
|
|
|
|
|
|
|
Example: |
3118
|
|
|
|
|
|
|
|
3119
|
|
|
|
|
|
|
Proxy-Authenticate: Basic realm="Access to the internal site" |
3120
|
|
|
|
|
|
|
|
3121
|
|
|
|
|
|
|
See also L<rfc6454, section 7|https://tools.ietf.org/html/rfc6454#section-7> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Proxy-Authenticate> |
3122
|
|
|
|
|
|
|
|
3123
|
|
|
|
|
|
|
=head2 proxy_authorization |
3124
|
|
|
|
|
|
|
|
3125
|
|
|
|
|
|
|
This sets or gets the C<Proxy-Authorization> header value. It takes a string value. |
3126
|
|
|
|
|
|
|
|
3127
|
|
|
|
|
|
|
Example: |
3128
|
|
|
|
|
|
|
|
3129
|
|
|
|
|
|
|
Proxy-Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l |
3130
|
|
|
|
|
|
|
|
3131
|
|
|
|
|
|
|
See also L<rfc7235, section 4.4|https://tools.ietf.org/html/rfc7235#section-4.4> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Proxy-Authorization> |
3132
|
|
|
|
|
|
|
|
3133
|
|
|
|
|
|
|
=head2 range |
3134
|
|
|
|
|
|
|
|
3135
|
|
|
|
|
|
|
This sets or gets the C<Range> header value. It takes a string value. |
3136
|
|
|
|
|
|
|
|
3137
|
|
|
|
|
|
|
See also L<HTTP::Promise::Headers::Range> to have a more granular control. |
3138
|
|
|
|
|
|
|
|
3139
|
|
|
|
|
|
|
Example: |
3140
|
|
|
|
|
|
|
|
3141
|
|
|
|
|
|
|
Range: bytes=200-1000, 2000-6576, 19000- |
3142
|
|
|
|
|
|
|
|
3143
|
|
|
|
|
|
|
See also L<rfc7233, section 3.1|https://tools.ietf.org/html/rfc7233#section-3.1> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range> |
3144
|
|
|
|
|
|
|
|
3145
|
|
|
|
|
|
|
=head2 referer |
3146
|
|
|
|
|
|
|
|
3147
|
|
|
|
|
|
|
This sets or gets the C<Referer> header value. It takes a string value. |
3148
|
|
|
|
|
|
|
|
3149
|
|
|
|
|
|
|
Example: |
3150
|
|
|
|
|
|
|
|
3151
|
|
|
|
|
|
|
Referer: https://dev.example.org/some/where |
3152
|
|
|
|
|
|
|
Referer: https://example.org/page?q=123 |
3153
|
|
|
|
|
|
|
Referer: https://example.org/ |
3154
|
|
|
|
|
|
|
|
3155
|
|
|
|
|
|
|
See also L<rfc7231, section 5.5.2|https://tools.ietf.org/html/rfc7231#section-5.5.2> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer> |
3156
|
|
|
|
|
|
|
|
3157
|
|
|
|
|
|
|
=head2 referrer |
3158
|
|
|
|
|
|
|
|
3159
|
|
|
|
|
|
|
This is an alias for L</referer> |
3160
|
|
|
|
|
|
|
|
3161
|
|
|
|
|
|
|
=head2 referrer_policy |
3162
|
|
|
|
|
|
|
|
3163
|
|
|
|
|
|
|
This sets or gets the C<Referrer-Policy> header value. It takes a string value. |
3164
|
|
|
|
|
|
|
|
3165
|
|
|
|
|
|
|
The allowed values can be: C<no-referrer>, C<no-referrer-when-downgrade>, C<origin>, C<origin-when-cross-origin>, C<same-origin>, C<strict-origin>, C<strict-origin-when-cross-origin>, C<unsafe-url> |
3166
|
|
|
|
|
|
|
|
3167
|
|
|
|
|
|
|
Example: |
3168
|
|
|
|
|
|
|
|
3169
|
|
|
|
|
|
|
Referrer-Policy: no-referrer |
3170
|
|
|
|
|
|
|
# With fallback |
3171
|
|
|
|
|
|
|
Referrer-Policy: no-referrer, strict-origin-when-cross-origin |
3172
|
|
|
|
|
|
|
|
3173
|
|
|
|
|
|
|
See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy> |
3174
|
|
|
|
|
|
|
|
3175
|
|
|
|
|
|
|
=head2 request_headers |
3176
|
|
|
|
|
|
|
|
3177
|
|
|
|
|
|
|
This sets or gets the C<Access-Control-Request-Headers> header value. It takes a string value. |
3178
|
|
|
|
|
|
|
|
3179
|
|
|
|
|
|
|
Example: |
3180
|
|
|
|
|
|
|
|
3181
|
|
|
|
|
|
|
Access-Control-Request-Headers: X-PINGOTHER, Content-Type |
3182
|
|
|
|
|
|
|
|
3183
|
|
|
|
|
|
|
See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Request-Headers> |
3184
|
|
|
|
|
|
|
|
3185
|
|
|
|
|
|
|
=head2 request_method |
3186
|
|
|
|
|
|
|
|
3187
|
|
|
|
|
|
|
This sets or gets the C<Access-Control-Request-Method> header value. It takes a string value. |
3188
|
|
|
|
|
|
|
|
3189
|
|
|
|
|
|
|
Example: |
3190
|
|
|
|
|
|
|
|
3191
|
|
|
|
|
|
|
Access-Control-Request-Method: POST |
3192
|
|
|
|
|
|
|
|
3193
|
|
|
|
|
|
|
See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Request-Method> |
3194
|
|
|
|
|
|
|
|
3195
|
|
|
|
|
|
|
=head2 retry_after |
3196
|
|
|
|
|
|
|
|
3197
|
|
|
|
|
|
|
This sets or gets the C<Retry-After> header value. It takes a string value. |
3198
|
|
|
|
|
|
|
|
3199
|
|
|
|
|
|
|
Example: |
3200
|
|
|
|
|
|
|
|
3201
|
|
|
|
|
|
|
Retry-After: Wed, 21 Oct 2015 07:28:00 GMT |
3202
|
|
|
|
|
|
|
Retry-After: 120 |
3203
|
|
|
|
|
|
|
|
3204
|
|
|
|
|
|
|
See also L<rfc7231, section 7.1.3|https://tools.ietf.org/html/rfc7231#section-7.1.3> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After> |
3205
|
|
|
|
|
|
|
|
3206
|
|
|
|
|
|
|
=head2 save_data |
3207
|
|
|
|
|
|
|
|
3208
|
|
|
|
|
|
|
This sets or gets the C<Save-Data> header value. It takes a string value. |
3209
|
|
|
|
|
|
|
|
3210
|
|
|
|
|
|
|
The value can be either C<on> or C<off> |
3211
|
|
|
|
|
|
|
|
3212
|
|
|
|
|
|
|
Example: |
3213
|
|
|
|
|
|
|
|
3214
|
|
|
|
|
|
|
Save-Data: on |
3215
|
|
|
|
|
|
|
|
3216
|
|
|
|
|
|
|
See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Save-Data> |
3217
|
|
|
|
|
|
|
|
3218
|
|
|
|
|
|
|
=head2 server |
3219
|
|
|
|
|
|
|
|
3220
|
|
|
|
|
|
|
This sets or gets the C<Server> header value. It takes a string value. |
3221
|
|
|
|
|
|
|
|
3222
|
|
|
|
|
|
|
Example: |
3223
|
|
|
|
|
|
|
|
3224
|
|
|
|
|
|
|
Server: Apache/2.4.1 (Unix) |
3225
|
|
|
|
|
|
|
|
3226
|
|
|
|
|
|
|
See also L<rfc7231, section 7.4.2|https://tools.ietf.org/html/rfc7231#section-7.4.2> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server> |
3227
|
|
|
|
|
|
|
|
3228
|
|
|
|
|
|
|
=head2 server_timing |
3229
|
|
|
|
|
|
|
|
3230
|
|
|
|
|
|
|
This sets or gets the C<Server> header value. It takes a string value. |
3231
|
|
|
|
|
|
|
|
3232
|
|
|
|
|
|
|
See also L<HTTP::Promise::Headers::ServerTiming> to have a more granular control. |
3233
|
|
|
|
|
|
|
|
3234
|
|
|
|
|
|
|
Example: |
3235
|
|
|
|
|
|
|
|
3236
|
|
|
|
|
|
|
# Single metric without value |
3237
|
|
|
|
|
|
|
Server-Timing: missedCache |
3238
|
|
|
|
|
|
|
|
3239
|
|
|
|
|
|
|
# Single metric with value |
3240
|
|
|
|
|
|
|
Server-Timing: cpu;dur=2.4 |
3241
|
|
|
|
|
|
|
|
3242
|
|
|
|
|
|
|
# Single metric with description and value |
3243
|
|
|
|
|
|
|
Server-Timing: cache;desc="Cache Read";dur=23.2 |
3244
|
|
|
|
|
|
|
|
3245
|
|
|
|
|
|
|
# Two metrics with value |
3246
|
|
|
|
|
|
|
Server-Timing: db;dur=53, app;dur=47.2 |
3247
|
|
|
|
|
|
|
|
3248
|
|
|
|
|
|
|
See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server-Timing> |
3249
|
|
|
|
|
|
|
|
3250
|
|
|
|
|
|
|
=head2 set_cookie |
3251
|
|
|
|
|
|
|
|
3252
|
|
|
|
|
|
|
This sets or gets the C<Set-Cookie> header value. It takes a string value. |
3253
|
|
|
|
|
|
|
|
3254
|
|
|
|
|
|
|
See also L<Cookie> to have a more granular control. |
3255
|
|
|
|
|
|
|
|
3256
|
|
|
|
|
|
|
Example: |
3257
|
|
|
|
|
|
|
|
3258
|
|
|
|
|
|
|
Set-Cookie: sessionId=38afes7a8 |
3259
|
|
|
|
|
|
|
Set-Cookie: __Secure-ID=123; Secure; Domain=example.com |
3260
|
|
|
|
|
|
|
Set-Cookie: __Host-ID=123; Secure; Path=/ |
3261
|
|
|
|
|
|
|
|
3262
|
|
|
|
|
|
|
See also L<rfc6265, section 4.1|https://tools.ietf.org/html/rfc6265#section-4.1> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie> |
3263
|
|
|
|
|
|
|
|
3264
|
|
|
|
|
|
|
=head2 sourcemap |
3265
|
|
|
|
|
|
|
|
3266
|
|
|
|
|
|
|
This sets or gets the C<SourceMap> header value. It takes a string value. |
3267
|
|
|
|
|
|
|
|
3268
|
|
|
|
|
|
|
Example: |
3269
|
|
|
|
|
|
|
|
3270
|
|
|
|
|
|
|
SourceMap: /path/to/file.js.map |
3271
|
|
|
|
|
|
|
|
3272
|
|
|
|
|
|
|
See also L<draft specifications|https://sourcemaps.info/spec.html> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/SourceMap> |
3273
|
|
|
|
|
|
|
|
3274
|
|
|
|
|
|
|
=head2 strict_transport_security |
3275
|
|
|
|
|
|
|
|
3276
|
|
|
|
|
|
|
This sets or gets the C<Strict-Transport-Security> header value. It takes a string value. |
3277
|
|
|
|
|
|
|
|
3278
|
|
|
|
|
|
|
See also L<HTTP::Promise::Headers::StrictTransportSecurity> to have a more granular control. |
3279
|
|
|
|
|
|
|
|
3280
|
|
|
|
|
|
|
Example: |
3281
|
|
|
|
|
|
|
|
3282
|
|
|
|
|
|
|
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload |
3283
|
|
|
|
|
|
|
|
3284
|
|
|
|
|
|
|
See also L<rfc6797, section 6.1|https://tools.ietf.org/html/rfc6797#section-6.1> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security> |
3285
|
|
|
|
|
|
|
|
3286
|
|
|
|
|
|
|
=head2 te |
3287
|
|
|
|
|
|
|
|
3288
|
|
|
|
|
|
|
This sets or gets the C<TE> header value. It takes a string value. |
3289
|
|
|
|
|
|
|
|
3290
|
|
|
|
|
|
|
See also L<HTTP::Promise::Headers::TE> to have a more granular control. |
3291
|
|
|
|
|
|
|
|
3292
|
|
|
|
|
|
|
Example: |
3293
|
|
|
|
|
|
|
|
3294
|
|
|
|
|
|
|
TE: deflate |
3295
|
|
|
|
|
|
|
TE: gzip |
3296
|
|
|
|
|
|
|
TE: trailers |
3297
|
|
|
|
|
|
|
|
3298
|
|
|
|
|
|
|
# Multiple directives, weighted with the quality value syntax: |
3299
|
|
|
|
|
|
|
TE: trailers, deflate;q=0.5 |
3300
|
|
|
|
|
|
|
|
3301
|
|
|
|
|
|
|
Notably, the value C<trailers> means the HTTP client support trailers, which are a set of headers sent after the body. |
3302
|
|
|
|
|
|
|
|
3303
|
|
|
|
|
|
|
Encoding header fields and their nuances: |
3304
|
|
|
|
|
|
|
|
3305
|
|
|
|
|
|
|
=over 4 |
3306
|
|
|
|
|
|
|
|
3307
|
|
|
|
|
|
|
=item C<Accept-Encoding> |
3308
|
|
|
|
|
|
|
|
3309
|
|
|
|
|
|
|
The encodings accepted by the client. |
3310
|
|
|
|
|
|
|
|
3311
|
|
|
|
|
|
|
=item C<Content-Encoding> |
3312
|
|
|
|
|
|
|
|
3313
|
|
|
|
|
|
|
Contains the encodings that have been applied to the content, before transport |
3314
|
|
|
|
|
|
|
|
3315
|
|
|
|
|
|
|
=item C<TE> |
3316
|
|
|
|
|
|
|
|
3317
|
|
|
|
|
|
|
The encodings the user agent accepts. |
3318
|
|
|
|
|
|
|
|
3319
|
|
|
|
|
|
|
=item C<Transfer-Encoding> |
3320
|
|
|
|
|
|
|
|
3321
|
|
|
|
|
|
|
The encoding applied during transfer, such as C<chunked> |
3322
|
|
|
|
|
|
|
|
3323
|
|
|
|
|
|
|
=back |
3324
|
|
|
|
|
|
|
|
3325
|
|
|
|
|
|
|
See also L</transfer_encoding>, L<rfc7230, section 4.3|https://tools.ietf.org/html/rfc7230#section-4.3> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/TE>, L<article on trailers|https://httptoolkit.tech/blog/http-wtf/#http-trailers> |
3326
|
|
|
|
|
|
|
|
3327
|
|
|
|
|
|
|
=head2 timing_allow_origin |
3328
|
|
|
|
|
|
|
|
3329
|
|
|
|
|
|
|
This sets or gets the C<Timing-Allow-Origin> header value. It takes a string value. |
3330
|
|
|
|
|
|
|
|
3331
|
|
|
|
|
|
|
Example: |
3332
|
|
|
|
|
|
|
|
3333
|
|
|
|
|
|
|
Timing-Allow-Origin: * |
3334
|
|
|
|
|
|
|
Timing-Allow-Origin: https://dev.example.org, https://example.com |
3335
|
|
|
|
|
|
|
|
3336
|
|
|
|
|
|
|
See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Timing-Allow-Origin> |
3337
|
|
|
|
|
|
|
|
3338
|
|
|
|
|
|
|
=head2 title |
3339
|
|
|
|
|
|
|
|
3340
|
|
|
|
|
|
|
Sets or gets the C<Title> of the HTML document if that were the case. This is here for legacy. |
3341
|
|
|
|
|
|
|
|
3342
|
|
|
|
|
|
|
=head2 tk |
3343
|
|
|
|
|
|
|
|
3344
|
|
|
|
|
|
|
This sets or gets the deprecated C<Tk> header value. It takes a string value. |
3345
|
|
|
|
|
|
|
|
3346
|
|
|
|
|
|
|
Example: |
3347
|
|
|
|
|
|
|
|
3348
|
|
|
|
|
|
|
Tk: N |
3349
|
|
|
|
|
|
|
|
3350
|
|
|
|
|
|
|
See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Tk> |
3351
|
|
|
|
|
|
|
|
3352
|
|
|
|
|
|
|
=head2 trailer |
3353
|
|
|
|
|
|
|
|
3354
|
|
|
|
|
|
|
This sets or gets the C<Trailer> header value. It takes a string value. |
3355
|
|
|
|
|
|
|
|
3356
|
|
|
|
|
|
|
Example: |
3357
|
|
|
|
|
|
|
|
3358
|
|
|
|
|
|
|
Trailer: Expires |
3359
|
|
|
|
|
|
|
|
3360
|
|
|
|
|
|
|
See also L<rfc7230, section 4.4|https://tools.ietf.org/html/rfc7230#section-4.4>, L<rfc7230, section 4.1.2|https://tools.ietf.org/html/rfc7230#section-4.1.2> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Trailer> |
3361
|
|
|
|
|
|
|
|
3362
|
|
|
|
|
|
|
=head2 transfer_encoding |
3363
|
|
|
|
|
|
|
|
3364
|
|
|
|
|
|
|
This sets or gets the C<Transfer-Encoding> header value. It takes a string value. |
3365
|
|
|
|
|
|
|
|
3366
|
|
|
|
|
|
|
Example: |
3367
|
|
|
|
|
|
|
|
3368
|
|
|
|
|
|
|
Transfer-Encoding: chunked |
3369
|
|
|
|
|
|
|
Transfer-Encoding: compress |
3370
|
|
|
|
|
|
|
Transfer-Encoding: deflate |
3371
|
|
|
|
|
|
|
Transfer-Encoding: gzip |
3372
|
|
|
|
|
|
|
|
3373
|
|
|
|
|
|
|
# Several values can be listed, separated by a comma |
3374
|
|
|
|
|
|
|
Transfer-Encoding: gzip, chunked |
3375
|
|
|
|
|
|
|
|
3376
|
|
|
|
|
|
|
Encoding header fields and their nuances: |
3377
|
|
|
|
|
|
|
|
3378
|
|
|
|
|
|
|
=over 4 |
3379
|
|
|
|
|
|
|
|
3380
|
|
|
|
|
|
|
=item C<Accept-Encoding> |
3381
|
|
|
|
|
|
|
|
3382
|
|
|
|
|
|
|
The encodings accepted by the client. |
3383
|
|
|
|
|
|
|
|
3384
|
|
|
|
|
|
|
=item C<Content-Encoding> |
3385
|
|
|
|
|
|
|
|
3386
|
|
|
|
|
|
|
Contains the encodings that have been applied to the content, before transport |
3387
|
|
|
|
|
|
|
|
3388
|
|
|
|
|
|
|
=item C<TE> |
3389
|
|
|
|
|
|
|
|
3390
|
|
|
|
|
|
|
The encodings the user agent accepts. |
3391
|
|
|
|
|
|
|
|
3392
|
|
|
|
|
|
|
=item C<Transfer-Encoding> |
3393
|
|
|
|
|
|
|
|
3394
|
|
|
|
|
|
|
The encoding applied during transfer, such as C<chunked> |
3395
|
|
|
|
|
|
|
|
3396
|
|
|
|
|
|
|
=back |
3397
|
|
|
|
|
|
|
|
3398
|
|
|
|
|
|
|
See L<rfc7230, section 3.3.1|https://tools.ietf.org/html/rfc7230#section-3.3.1>: |
3399
|
|
|
|
|
|
|
"Unlike Content-Encoding (L<Section 3.1.2.1 of [RFC7231]|https://tools.ietf.org/html/rfc7231#section-3.1.2.1>), Transfer-Encoding is a property of the message, not of the representation" |
3400
|
|
|
|
|
|
|
|
3401
|
|
|
|
|
|
|
See also L</te>, L<rfc7230, section 3.3.1|https://tools.ietf.org/html/rfc7230#section-3.3.1> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding> and L<Wikipedia|https://en.wikipedia.org/wiki/Chunked_transfer_encoding> |
3402
|
|
|
|
|
|
|
|
3403
|
|
|
|
|
|
|
=head2 upgrade |
3404
|
|
|
|
|
|
|
|
3405
|
|
|
|
|
|
|
This sets or gets the C<Upgrade> header value. It takes a string value. |
3406
|
|
|
|
|
|
|
|
3407
|
|
|
|
|
|
|
Example: |
3408
|
|
|
|
|
|
|
|
3409
|
|
|
|
|
|
|
Connection: upgrade |
3410
|
|
|
|
|
|
|
Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11 |
3411
|
|
|
|
|
|
|
|
3412
|
|
|
|
|
|
|
Connection: Upgrade |
3413
|
|
|
|
|
|
|
Upgrade: websocket |
3414
|
|
|
|
|
|
|
|
3415
|
|
|
|
|
|
|
See also L<rfc7230, section 6.7|https://tools.ietf.org/html/rfc7230#section-6.7>, L<rfc7231, section 6.6.15|https://tools.ietf.org/html/rfc7231#section-6.6.15>, L<rfc7240, section 8.1.1|https://tools.ietf.org/html/rfc7240#section-8.1.1> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Upgrade> |
3416
|
|
|
|
|
|
|
|
3417
|
|
|
|
|
|
|
=head2 upgrade_insecure_requests |
3418
|
|
|
|
|
|
|
|
3419
|
|
|
|
|
|
|
This sets or gets the C<Upgrade-Insecure-Requests> header value. It takes a string value. |
3420
|
|
|
|
|
|
|
|
3421
|
|
|
|
|
|
|
Example: |
3422
|
|
|
|
|
|
|
|
3423
|
|
|
|
|
|
|
Upgrade-Insecure-Requests: 1 |
3424
|
|
|
|
|
|
|
|
3425
|
|
|
|
|
|
|
See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Upgrade-Insecure-Requests> |
3426
|
|
|
|
|
|
|
|
3427
|
|
|
|
|
|
|
=head2 user_agent |
3428
|
|
|
|
|
|
|
|
3429
|
|
|
|
|
|
|
This sets or gets the C<User-Agent> header value. It takes a string value. |
3430
|
|
|
|
|
|
|
|
3431
|
|
|
|
|
|
|
Example: |
3432
|
|
|
|
|
|
|
|
3433
|
|
|
|
|
|
|
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:42.0) Gecko/20100101 Firefox/42.0 |
3434
|
|
|
|
|
|
|
User-Agent: curl/7.64.1 |
3435
|
|
|
|
|
|
|
|
3436
|
|
|
|
|
|
|
See also L<rfc7231, section 5.5.3|https://tools.ietf.org/html/rfc7231#section-5.5.3> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent> |
3437
|
|
|
|
|
|
|
|
3438
|
|
|
|
|
|
|
=head2 vary |
3439
|
|
|
|
|
|
|
|
3440
|
|
|
|
|
|
|
This sets or gets the C<Vary> header value. It takes a string value. |
3441
|
|
|
|
|
|
|
|
3442
|
|
|
|
|
|
|
Example: |
3443
|
|
|
|
|
|
|
|
3444
|
|
|
|
|
|
|
Vary: * |
3445
|
|
|
|
|
|
|
Vary: Accept-Encoding, User-Agent |
3446
|
|
|
|
|
|
|
|
3447
|
|
|
|
|
|
|
See also L<rfc7231, section 7.1.4|https://tools.ietf.org/html/rfc7231#section-7.1.4> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Vary> |
3448
|
|
|
|
|
|
|
|
3449
|
|
|
|
|
|
|
=head2 via |
3450
|
|
|
|
|
|
|
|
3451
|
|
|
|
|
|
|
This sets or gets the C<Via> header value. It takes a string value. |
3452
|
|
|
|
|
|
|
|
3453
|
|
|
|
|
|
|
Example: |
3454
|
|
|
|
|
|
|
|
3455
|
|
|
|
|
|
|
Via: 1.1 vegur |
3456
|
|
|
|
|
|
|
Via: HTTP/1.1 GWA |
3457
|
|
|
|
|
|
|
Via: 1.0 fred, 1.1 p.example.net |
3458
|
|
|
|
|
|
|
|
3459
|
|
|
|
|
|
|
See also L<rfc7230, section 5.7.1|https://tools.ietf.org/html/rfc7230#section-5.7.1> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Via> |
3460
|
|
|
|
|
|
|
|
3461
|
|
|
|
|
|
|
=head2 want_digest |
3462
|
|
|
|
|
|
|
|
3463
|
|
|
|
|
|
|
This sets or gets the C<Want-Digest> header value. It takes a string value. |
3464
|
|
|
|
|
|
|
|
3465
|
|
|
|
|
|
|
Example: |
3466
|
|
|
|
|
|
|
|
3467
|
|
|
|
|
|
|
Want-Digest: sha-256 |
3468
|
|
|
|
|
|
|
Want-Digest: SHA-512;q=0.3, sha-256;q=1, md5;q=0 |
3469
|
|
|
|
|
|
|
|
3470
|
|
|
|
|
|
|
See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Want-Digest> |
3471
|
|
|
|
|
|
|
|
3472
|
|
|
|
|
|
|
=head2 warning |
3473
|
|
|
|
|
|
|
|
3474
|
|
|
|
|
|
|
This sets or gets the C<Warning> header value. It takes a string value. |
3475
|
|
|
|
|
|
|
|
3476
|
|
|
|
|
|
|
Example: |
3477
|
|
|
|
|
|
|
|
3478
|
|
|
|
|
|
|
Warning: 110 anderson/1.3.37 "Response is stale" |
3479
|
|
|
|
|
|
|
|
3480
|
|
|
|
|
|
|
See also L<rfc7234, section 5.5|https://tools.ietf.org/html/rfc7234#section-5.5> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Warning> |
3481
|
|
|
|
|
|
|
|
3482
|
|
|
|
|
|
|
=head2 www_authenticate |
3483
|
|
|
|
|
|
|
|
3484
|
|
|
|
|
|
|
This sets or gets the C<WWW-Authenticate> header value. It takes a string value. |
3485
|
|
|
|
|
|
|
|
3486
|
|
|
|
|
|
|
Example: |
3487
|
|
|
|
|
|
|
|
3488
|
|
|
|
|
|
|
WWW-Authenticate: Basic realm="Access to the staging site", charset="UTF-8" |
3489
|
|
|
|
|
|
|
WWW-Authenticate: Digest |
3490
|
|
|
|
|
|
|
realm="http-auth@example.org", |
3491
|
|
|
|
|
|
|
qop="auth, auth-int", |
3492
|
|
|
|
|
|
|
algorithm=SHA-256, |
3493
|
|
|
|
|
|
|
nonce="7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v", |
3494
|
|
|
|
|
|
|
opaque="FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS" |
3495
|
|
|
|
|
|
|
WWW-Authenticate: Digest |
3496
|
|
|
|
|
|
|
realm="http-auth@example.org", |
3497
|
|
|
|
|
|
|
qop="auth, auth-int", |
3498
|
|
|
|
|
|
|
algorithm=MD5, |
3499
|
|
|
|
|
|
|
nonce="7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v", |
3500
|
|
|
|
|
|
|
opaque="FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS" |
3501
|
|
|
|
|
|
|
|
3502
|
|
|
|
|
|
|
See also L<rfc7235, section 4.1|https://tools.ietf.org/html/rfc7235#section-4.1> and L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/WWW-Authenticate> |
3503
|
|
|
|
|
|
|
|
3504
|
|
|
|
|
|
|
=head2 x |
3505
|
|
|
|
|
|
|
|
3506
|
|
|
|
|
|
|
Sets or gets an arbitrary C<X-*> header. For example: |
3507
|
|
|
|
|
|
|
|
3508
|
|
|
|
|
|
|
$h->x( 'Spip-Cache' => 3600 ); |
3509
|
|
|
|
|
|
|
|
3510
|
|
|
|
|
|
|
would set the C<X-Spip-Cache> header value to C<3600> |
3511
|
|
|
|
|
|
|
|
3512
|
|
|
|
|
|
|
my $value = $h->x( 'Spip-Cache' ); |
3513
|
|
|
|
|
|
|
|
3514
|
|
|
|
|
|
|
=head2 x_content_type_options |
3515
|
|
|
|
|
|
|
|
3516
|
|
|
|
|
|
|
This sets or gets the C<X-Content-Type-Options> header value. It takes a string value. |
3517
|
|
|
|
|
|
|
|
3518
|
|
|
|
|
|
|
Example: |
3519
|
|
|
|
|
|
|
|
3520
|
|
|
|
|
|
|
X-Content-Type-Options: nosniff |
3521
|
|
|
|
|
|
|
|
3522
|
|
|
|
|
|
|
See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options> |
3523
|
|
|
|
|
|
|
|
3524
|
|
|
|
|
|
|
=head2 x_dns_prefetch_control |
3525
|
|
|
|
|
|
|
|
3526
|
|
|
|
|
|
|
This sets or gets the C<X-DNS-Prefetch-Control> header value. It takes a string value. |
3527
|
|
|
|
|
|
|
|
3528
|
|
|
|
|
|
|
Example: |
3529
|
|
|
|
|
|
|
|
3530
|
|
|
|
|
|
|
X-DNS-Prefetch-Control: on |
3531
|
|
|
|
|
|
|
X-DNS-Prefetch-Control: off |
3532
|
|
|
|
|
|
|
|
3533
|
|
|
|
|
|
|
See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-DNS-Prefetch-Control> |
3534
|
|
|
|
|
|
|
|
3535
|
|
|
|
|
|
|
=head2 x_forwarded_for |
3536
|
|
|
|
|
|
|
|
3537
|
|
|
|
|
|
|
This sets or gets the C<X-Forwarded-For> header value. It takes a string value. |
3538
|
|
|
|
|
|
|
|
3539
|
|
|
|
|
|
|
Example: |
3540
|
|
|
|
|
|
|
|
3541
|
|
|
|
|
|
|
X-Forwarded-For: 2001:db8:85a3:8d3:1319:8a2e:370:7348 |
3542
|
|
|
|
|
|
|
X-Forwarded-For: 203.0.113.195 |
3543
|
|
|
|
|
|
|
X-Forwarded-For: 203.0.113.195, 2001:db8:85a3:8d3:1319:8a2e:370:7348 |
3544
|
|
|
|
|
|
|
|
3545
|
|
|
|
|
|
|
See also L</host>, L</forwarded>, L</x_forwarded_host>, L</x_forwarded_proto>, L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For> |
3546
|
|
|
|
|
|
|
|
3547
|
|
|
|
|
|
|
=head2 x_forwarded_host |
3548
|
|
|
|
|
|
|
|
3549
|
|
|
|
|
|
|
This sets or gets the C<X-Forwarded-Host> header value. It takes a string value. |
3550
|
|
|
|
|
|
|
|
3551
|
|
|
|
|
|
|
Example: |
3552
|
|
|
|
|
|
|
|
3553
|
|
|
|
|
|
|
X-Forwarded-Host: id42.example-cdn.com |
3554
|
|
|
|
|
|
|
|
3555
|
|
|
|
|
|
|
See also L</host>, L</forwarded>, L</x_forwarded_for>, L</x_forwarded_proto>, L<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Host> |
3556
|
|
|
|
|
|
|
|
3557
|
|
|
|
|
|
|
=head2 x_forwarded_proto |
3558
|
|
|
|
|
|
|
|
3559
|
|
|
|
|
|
|
This sets or gets the C<X-Forwarded-Proto> header value. It takes a string value. |
3560
|
|
|
|
|
|
|
|
3561
|
|
|
|
|
|
|
Example: |
3562
|
|
|
|
|
|
|
|
3563
|
|
|
|
|
|
|
X-Forwarded-Proto: https |
3564
|
|
|
|
|
|
|
|
3565
|
|
|
|
|
|
|
See also L</host>, L</forwarded>, L</x_forwarded_for>, L</x_forwarded_host>, L<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto> |
3566
|
|
|
|
|
|
|
|
3567
|
|
|
|
|
|
|
=head2 x_frame_options |
3568
|
|
|
|
|
|
|
|
3569
|
|
|
|
|
|
|
This sets or gets the C<X-Frame-Options> header value. It takes a string value. |
3570
|
|
|
|
|
|
|
|
3571
|
|
|
|
|
|
|
Example: |
3572
|
|
|
|
|
|
|
|
3573
|
|
|
|
|
|
|
X-Frame-Options: DENY |
3574
|
|
|
|
|
|
|
X-Frame-Options: SAMEORIGIN |
3575
|
|
|
|
|
|
|
|
3576
|
|
|
|
|
|
|
See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options> |
3577
|
|
|
|
|
|
|
|
3578
|
|
|
|
|
|
|
=head2 x_xss_protection |
3579
|
|
|
|
|
|
|
|
3580
|
|
|
|
|
|
|
This sets or gets the C<X-XSS-Protection> header value. It takes a string value. |
3581
|
|
|
|
|
|
|
|
3582
|
|
|
|
|
|
|
Example: |
3583
|
|
|
|
|
|
|
|
3584
|
|
|
|
|
|
|
X-XSS-Protection: 0 |
3585
|
|
|
|
|
|
|
X-XSS-Protection: 1 |
3586
|
|
|
|
|
|
|
X-XSS-Protection: 1; mode=block |
3587
|
|
|
|
|
|
|
X-XSS-Protection: 1; report=https://example.org/some/where |
3588
|
|
|
|
|
|
|
|
3589
|
|
|
|
|
|
|
See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection> |
3590
|
|
|
|
|
|
|
|
3591
|
|
|
|
|
|
|
=for Pod::Coverage STORABLE_thaw_post_processing |
3592
|
|
|
|
|
|
|
|
3593
|
|
|
|
|
|
|
=head1 AUTHOR |
3594
|
|
|
|
|
|
|
|
3595
|
|
|
|
|
|
|
Jacques Deguest E<lt>F<jack@deguest.jp>E<gt> |
3596
|
|
|
|
|
|
|
|
3597
|
|
|
|
|
|
|
=head1 SEE ALSO |
3598
|
|
|
|
|
|
|
|
3599
|
|
|
|
|
|
|
L<Mozilla documentation on HTTP headers|https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers> |
3600
|
|
|
|
|
|
|
|
3601
|
|
|
|
|
|
|
L<HTTP::Promise::Headers::AcceptEncoding>, L<HTTP::Promise::Headers::AcceptLanguage>, L<HTTP::Promise::Headers::Accept>, L<HTTP::Promise::Headers::AltSvc>, L<HTTP::Promise::Headers::CacheControl>, L<HTTP::Promise::Headers::ClearSiteData>, L<HTTP::Promise::Headers::ContentDisposition>, L<HTTP::Promise::Headers::ContentRange>, L<HTTP::Promise::Headers::ContentSecurityPolicy>, L<HTTP::Promise::Headers::ContentSecurityPolicyReportOnly>, L<HTTP::Promise::Headers::ContentType>, L<HTTP::Promise::Headers::Cookie>, L<HTTP::Promise::Headers::ExpectCT>, L<HTTP::Promise::Headers::Forwarded>, L<HTTP::Promise::Headers::Generic>, L<HTTP::Promise::Headers::KeepAlive>, L<HTTP::Promise::Headers::Link>, L<HTTP::Promise::Headers::Range>, L<HTTP::Promise::Headers::ServerTiming>, L<HTTP::Promise::Headers::StrictTransportSecurity>, L<HTTP::Promise::Headers::TE> |
3602
|
|
|
|
|
|
|
|
3603
|
|
|
|
|
|
|
L<rfc7230, section 3.2 on headers field names|https://tools.ietf.org/html/rfc7230#section-3.2>, |
3604
|
|
|
|
|
|
|
L<rfc6838 on mime types|https://tools.ietf.org/html/rfc6838> |
3605
|
|
|
|
|
|
|
|
3606
|
|
|
|
|
|
|
L<HTTP::Promise>, L<HTTP::Promise::Request>, L<HTTP::Promise::Response>, L<HTTP::Promise::Message>, L<HTTP::Promise::Entity>, L<HTTP::Promise::Headers>, L<HTTP::Promise::Body>, L<HTTP::Promise::Body::Form>, L<HTTP::Promise::Body::Form::Data>, L<HTTP::Promise::Body::Form::Field>, L<HTTP::Promise::Status>, L<HTTP::Promise::MIME>, L<HTTP::Promise::Parser>, L<HTTP::Promise::IO>, L<HTTP::Promise::Stream>, L<HTTP::Promise::Exception> |
3607
|
|
|
|
|
|
|
|
3608
|
|
|
|
|
|
|
=head1 COPYRIGHT & LICENSE |
3609
|
|
|
|
|
|
|
|
3610
|
|
|
|
|
|
|
Copyright(c) 2022 DEGUEST Pte. Ltd. |
3611
|
|
|
|
|
|
|
|
3612
|
|
|
|
|
|
|
All rights reserved |
3613
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. |
3614
|
|
|
|
|
|
|
|
3615
|
|
|
|
|
|
|
=cut |