| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
##---------------------------------------------------------------------------- |
|
2
|
|
|
|
|
|
|
## Asynchronous HTTP Request and Promise - ~/lib/HTTP/Promise/Headers/Generic.pm |
|
3
|
|
|
|
|
|
|
## Version v0.1.1 |
|
4
|
|
|
|
|
|
|
## Copyright(c) 2022 DEGUEST Pte. Ltd. |
|
5
|
|
|
|
|
|
|
## Author: Jacques Deguest <jack@deguest.jp> |
|
6
|
|
|
|
|
|
|
## Created 2022/05/06 |
|
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::Generic; |
|
15
|
|
|
|
|
|
|
BEGIN |
|
16
|
|
|
|
|
|
|
{ |
|
17
|
11
|
|
|
11
|
|
6861
|
use strict; |
|
|
11
|
|
|
|
|
27
|
|
|
|
11
|
|
|
|
|
337
|
|
|
18
|
11
|
|
|
11
|
|
82
|
use warnings; |
|
|
11
|
|
|
|
|
23
|
|
|
|
11
|
|
|
|
|
403
|
|
|
19
|
11
|
|
|
11
|
|
86
|
use parent qw( Module::Generic ); |
|
|
11
|
|
|
|
|
47
|
|
|
|
11
|
|
|
|
|
146
|
|
|
20
|
11
|
|
|
11
|
|
101033
|
use vars qw( $VERSION $QV_ELEMENT $QV_VALUE ); |
|
|
11
|
|
|
|
|
25
|
|
|
|
11
|
|
|
|
|
938
|
|
|
21
|
11
|
|
|
11
|
|
88
|
use Encode (); |
|
|
11
|
|
|
|
|
24
|
|
|
|
11
|
|
|
|
|
261
|
|
|
22
|
11
|
|
|
11
|
|
578
|
use URI::Escape::XS (); |
|
|
11
|
|
|
|
|
99034
|
|
|
|
11
|
|
|
|
|
306
|
|
|
23
|
11
|
|
|
11
|
|
75
|
use Want; |
|
|
11
|
|
|
|
|
26
|
|
|
|
11
|
|
|
|
|
1616
|
|
|
24
|
|
|
|
|
|
|
use overload ( |
|
25
|
|
|
|
|
|
|
'""' => 'as_string', |
|
26
|
558
|
|
|
558
|
|
12463
|
'bool' => sub{1}, |
|
27
|
|
|
|
|
|
|
# No fallback on purpose |
|
28
|
11
|
|
|
11
|
|
89
|
); |
|
|
11
|
|
|
|
|
36
|
|
|
|
11
|
|
|
|
|
206
|
|
|
29
|
|
|
|
|
|
|
# Accept: audio/*; q=0.2, audio/basic |
|
30
|
11
|
|
|
11
|
|
2642
|
our $QV_ELEMENT = qr/(?:[^\;\,]+)/; |
|
31
|
11
|
|
|
|
|
63
|
our $QV_VALUE = qr/(?:0(?:\.[0-9]{0,3})?|1(?:\.0{0,3})?)/; |
|
32
|
11
|
|
|
|
|
316
|
our $VERSION = 'v0.1.1'; |
|
33
|
|
|
|
|
|
|
}; |
|
34
|
|
|
|
|
|
|
|
|
35
|
11
|
|
|
11
|
|
76
|
use strict; |
|
|
11
|
|
|
|
|
37
|
|
|
|
11
|
|
|
|
|
302
|
|
|
36
|
11
|
|
|
11
|
|
67
|
use warnings; |
|
|
11
|
|
|
|
|
24
|
|
|
|
11
|
|
|
|
|
33886
|
|
|
37
|
|
|
|
|
|
|
|
|
38
|
0
|
|
|
0
|
1
|
0
|
sub as_string { return( shift->value ); } |
|
39
|
|
|
|
|
|
|
|
|
40
|
0
|
|
|
0
|
1
|
0
|
sub field_name { return( shift->_set_get_scalar( '_name', @_ ) ); } |
|
41
|
|
|
|
|
|
|
|
|
42
|
2
|
|
|
2
|
1
|
23
|
sub uri_escape_utf8 { return( URI::Escape::XS::uri_escape( Encode::encode( 'UTF-8', $_[1] ) ) ); } |
|
43
|
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
# By default and superseded by inheriting classes such as Content-Type that has more |
|
45
|
|
|
|
|
|
|
# elaborate value with parameters |
|
46
|
0
|
|
|
0
|
1
|
0
|
sub value { return( shift->_set_get_scalar( '_value', @_ ) ); } |
|
47
|
|
|
|
|
|
|
|
|
48
|
168
|
|
|
168
|
|
979
|
sub _field_name { return( shift->_set_get_scalar( '_name', @_ ) ); } |
|
49
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
# rfc2231 <https://tools.ietf.org/html/rfc2231> |
|
51
|
|
|
|
|
|
|
sub _filename_decode |
|
52
|
|
|
|
|
|
|
{ |
|
53
|
10
|
|
|
10
|
|
24
|
my $self = shift( @_ ); |
|
54
|
10
|
|
|
|
|
21
|
my $fname = shift( @_ ); |
|
55
|
10
|
50
|
|
|
|
40
|
$self->_load_class( 'HTTP::Promise::Headers' ) || return( $self->pass_error ); |
|
56
|
10
|
|
|
|
|
426
|
my( $new_fname, $charset, $lang ) = HTTP::Promise::Headers->decode_filename( $fname ); |
|
57
|
10
|
50
|
|
|
|
36
|
if( defined( $new_fname ) ) |
|
58
|
|
|
|
|
|
|
{ |
|
59
|
10
|
|
|
|
|
19
|
$fname = $new_fname; |
|
60
|
|
|
|
|
|
|
} |
|
61
|
10
|
50
|
|
|
|
45
|
return( wantarray() ? ( $fname, $charset, $lang ) : $fname ); |
|
62
|
|
|
|
|
|
|
} |
|
63
|
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
# rfc2231 <https://tools.ietf.org/html/rfc2231> |
|
65
|
|
|
|
|
|
|
sub _filename_encode |
|
66
|
|
|
|
|
|
|
{ |
|
67
|
2
|
|
|
2
|
|
6
|
my $self = shift( @_ ); |
|
68
|
2
|
|
|
|
|
7
|
my $fname = shift( @_ ); |
|
69
|
2
|
|
|
|
|
3
|
my $lang = shift( @_ ); |
|
70
|
2
|
50
|
|
|
|
17
|
if( $fname =~ /[^\x00-\x7f]/ ) |
|
71
|
|
|
|
|
|
|
{ |
|
72
|
2
|
50
|
|
|
|
8
|
$lang = '' if( !defined( $lang ) ); |
|
73
|
2
|
|
|
|
|
28
|
return( sprintf( "UTF-8'${lang}'%s", $self->uri_escape_utf8( $fname ) ) ); |
|
74
|
|
|
|
|
|
|
} |
|
75
|
|
|
|
|
|
|
# Nothing to be done. We return undef on purpose to indicate nothing was done |
|
76
|
0
|
|
|
|
|
0
|
return; |
|
77
|
|
|
|
|
|
|
} |
|
78
|
|
|
|
|
|
|
|
|
79
|
316
|
|
|
316
|
|
1326
|
sub _hv { return( shift->_set_get_object_without_init( '_hv', 'Module::Generic::HeaderValue', @_ ) ); } |
|
80
|
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
sub _hv_as_string |
|
82
|
|
|
|
|
|
|
{ |
|
83
|
48
|
|
|
48
|
|
157
|
my $self = shift( @_ ); |
|
84
|
48
|
|
|
|
|
314
|
my $hv = $self->_hv; |
|
85
|
48
|
50
|
|
|
|
1387
|
return( '' ) if( !$hv ); |
|
86
|
48
|
|
|
|
|
558
|
return( $hv->as_string( @_ ) ); |
|
87
|
|
|
|
|
|
|
} |
|
88
|
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
sub _get_header_value_object |
|
90
|
|
|
|
|
|
|
{ |
|
91
|
0
|
|
|
0
|
|
0
|
my $self = shift( @_ ); |
|
92
|
0
|
0
|
|
|
|
0
|
$self->_load_class( 'Module::Generic::HeaderValue' ) || |
|
93
|
|
|
|
|
|
|
return( $self->pass_error ); |
|
94
|
0
|
|
0
|
|
|
0
|
my $hv = Module::Generic::HeaderValue->new( shift( @_ ) ) || |
|
95
|
|
|
|
|
|
|
return( $self->pass_error( Module::Generic::HeaderValue->error ) ); |
|
96
|
0
|
|
|
|
|
0
|
return( $hv ); |
|
97
|
|
|
|
|
|
|
} |
|
98
|
|
|
|
|
|
|
|
|
99
|
0
|
|
|
0
|
|
0
|
sub _make_boundary { return( Data::UUID->new->create_str ); } |
|
100
|
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
sub _new_hv |
|
102
|
|
|
|
|
|
|
{ |
|
103
|
5
|
|
|
5
|
|
33
|
my $self = shift( @_ ); |
|
104
|
5
|
50
|
|
|
|
27
|
$self->_load_class( 'Module::Generic::HeaderValue' ) || return( $self->pass_error ); |
|
105
|
5
|
|
|
|
|
321
|
return( Module::Generic::HeaderValue->new( @_ ) ); |
|
106
|
|
|
|
|
|
|
} |
|
107
|
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
sub _new_qv_object |
|
109
|
|
|
|
|
|
|
{ |
|
110
|
35
|
|
|
35
|
|
77
|
my $self = shift( @_ ); |
|
111
|
35
|
|
|
|
|
183
|
my $o = HTTP::Promise::Field::QualityValue->new( @_ ); |
|
112
|
35
|
50
|
|
|
|
259
|
return( $self->pass_error( HTTP::Promise::Field::QualityValue->error ) ) if( !defined( $o ) ); |
|
113
|
35
|
|
|
|
|
85
|
return( $o ); |
|
114
|
|
|
|
|
|
|
} |
|
115
|
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
sub _parse_header_value |
|
117
|
|
|
|
|
|
|
{ |
|
118
|
87
|
|
|
87
|
|
258
|
my $self = shift( @_ ); |
|
119
|
87
|
|
|
|
|
204
|
my $this = shift( @_ ); |
|
120
|
87
|
50
|
33
|
|
|
546
|
return( $self->error( "No header value was provided to parse." ) ) if( !defined( $this ) || !length( "$this" ) ); |
|
121
|
87
|
50
|
|
|
|
804
|
$self->_load_class( 'Module::Generic::HeaderValue' ) || |
|
122
|
|
|
|
|
|
|
return( $self->pass_error ); |
|
123
|
87
|
|
50
|
|
|
19358
|
my $hv = Module::Generic::HeaderValue->new_from_header( $this, @_ ) || |
|
124
|
|
|
|
|
|
|
return( $self->pass_error( Module::Generic::HeaderValue->error ) ); |
|
125
|
87
|
|
|
|
|
579212
|
return( $hv ); |
|
126
|
|
|
|
|
|
|
} |
|
127
|
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
# rfc7231, section 5.3.1 |
|
129
|
|
|
|
|
|
|
# <https://tools.ietf.org/html/rfc7231#section-5.3.1> |
|
130
|
|
|
|
|
|
|
sub _parse_quality_value |
|
131
|
|
|
|
|
|
|
{ |
|
132
|
10
|
|
|
10
|
|
33
|
my $self = shift( @_ ); |
|
133
|
10
|
|
|
|
|
23
|
my $str = shift( @_ ); |
|
134
|
10
|
50
|
33
|
|
|
92
|
return( $self->error( "No header value was provided to parse." ) ) if( !defined( $str ) || !length( "$str" ) ); |
|
135
|
|
|
|
|
|
|
# No blank |
|
136
|
10
|
|
|
|
|
49
|
$str =~ s/[[:blank:]\h]]+//g; |
|
137
|
10
|
|
|
|
|
96
|
my $choices = $self->new_array; |
|
138
|
|
|
|
|
|
|
# Credits: HTTP::AcceptLanguage from Kazuhiro Osawa |
|
139
|
10
|
|
|
|
|
12470
|
for my $def ( split( /,[[:blank:]\h]*/, $str ) ) |
|
140
|
|
|
|
|
|
|
{ |
|
141
|
35
|
|
|
|
|
757
|
my( $element, $quality ) = $def =~ /\A($QV_ELEMENT)(?:;[[:blank:]\h]*[qQ]=($QV_VALUE))?\z/; |
|
142
|
|
|
|
|
|
|
# rfc7231, section 5.3.1: |
|
143
|
|
|
|
|
|
|
# "If no "q" parameter is present, the default weight is 1." |
|
144
|
|
|
|
|
|
|
# rfc7231, section 5.3.5 |
|
145
|
|
|
|
|
|
|
# "no value is the same as q=1" |
|
146
|
|
|
|
|
|
|
# $quality = 1 unless( defined( $quality ) ); |
|
147
|
|
|
|
|
|
|
# next unless( $element && $quality > 0 ); |
|
148
|
35
|
50
|
|
|
|
123
|
next unless( $element ); |
|
149
|
35
|
|
|
|
|
154
|
my $qv = $self->_new_qv_object( $element => $quality ); |
|
150
|
35
|
|
|
|
|
141
|
$choices->push( $qv ); |
|
151
|
|
|
|
|
|
|
} |
|
152
|
10
|
|
|
|
|
154
|
return( $choices ); |
|
153
|
|
|
|
|
|
|
} |
|
154
|
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
sub _qstring_join |
|
156
|
|
|
|
|
|
|
{ |
|
157
|
6
|
|
|
6
|
|
136
|
my $self = shift( @_ ); |
|
158
|
6
|
|
|
|
|
13
|
my @parts = (); |
|
159
|
6
|
|
|
|
|
13
|
foreach my $s ( @_ ) |
|
160
|
|
|
|
|
|
|
{ |
|
161
|
26
|
|
|
|
|
36
|
$s =~ s/^"//; |
|
162
|
26
|
|
|
|
|
34
|
$s =~ s/(?!\\)"$//; |
|
163
|
26
|
|
|
|
|
30
|
$s =~ s/(?!\\)\"/\\"/g; |
|
164
|
26
|
|
|
|
|
59
|
push( @parts, qq{"${s}"} ); |
|
165
|
|
|
|
|
|
|
} |
|
166
|
6
|
|
|
|
|
65
|
return( join( ', ', @parts ) ); |
|
167
|
|
|
|
|
|
|
} |
|
168
|
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
# Returns an array of tokens that were initially surrounded by double quotes, and |
|
170
|
|
|
|
|
|
|
# separated by comma even if they contained double quotes inside. |
|
171
|
|
|
|
|
|
|
# Example for Clear-Site-Data header field: |
|
172
|
|
|
|
|
|
|
# "cache", "cookies", "storage", "executionContexts" |
|
173
|
|
|
|
|
|
|
# "cache\"", "oh "la" la", "storage\", \"", "executionContexts" |
|
174
|
|
|
|
|
|
|
sub _qstring_split |
|
175
|
|
|
|
|
|
|
{ |
|
176
|
2
|
|
|
2
|
|
45
|
my $self = shift( @_ ); |
|
177
|
2
|
|
|
|
|
23
|
my $str = shift( @_ ); |
|
178
|
2
|
|
|
|
|
27
|
my @parts = split( /(?<=(?<!\\)\")[[:blank:]\h]*,[[:blank:]\h]*(?=\")/, $str ); |
|
179
|
2
|
|
|
|
|
9
|
for( @parts ) |
|
180
|
|
|
|
|
|
|
{ |
|
181
|
|
|
|
|
|
|
#substr( $_, 0, 1, '' ); |
|
182
|
|
|
|
|
|
|
#substr( $_, -1, 1, '' ); |
|
183
|
|
|
|
|
|
|
# s/^"|"$//g; |
|
184
|
8
|
|
|
|
|
27
|
s/^"//; |
|
185
|
8
|
|
|
|
|
35
|
s/"$//; |
|
186
|
|
|
|
|
|
|
} |
|
187
|
2
|
|
|
|
|
31
|
return( @parts ); |
|
188
|
|
|
|
|
|
|
} |
|
189
|
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
sub _qv_add |
|
191
|
|
|
|
|
|
|
{ |
|
192
|
0
|
|
|
0
|
|
0
|
my $self = shift( @_ ); |
|
193
|
0
|
|
|
|
|
0
|
my( $elem, $val ) = @_; |
|
194
|
0
|
|
0
|
|
|
0
|
my $qv = HTTP::Promise::Field::QualityValue->new( $elem => $val ) || |
|
195
|
|
|
|
|
|
|
return( $self->pass_error( HTTP::Promise::Field::QualityValue->error ) ); |
|
196
|
0
|
|
|
|
|
0
|
$self->elements->push( $qv ); |
|
197
|
0
|
|
|
|
|
0
|
return( $qv ); |
|
198
|
|
|
|
|
|
|
} |
|
199
|
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
sub _qv_as_string |
|
201
|
|
|
|
|
|
|
{ |
|
202
|
15
|
|
|
15
|
|
40
|
my $self = shift( @_ ); |
|
203
|
15
|
|
|
|
|
39
|
my $all = $self->elements; |
|
204
|
15
|
50
|
|
|
|
1101
|
return( '' ) if( $all->is_empty ); |
|
205
|
15
|
|
|
52
|
|
378
|
my $res = $all->map(sub{ $_->as_string }); |
|
|
52
|
|
|
|
|
450
|
|
|
206
|
15
|
|
|
|
|
1927
|
return( $res->join( ', ' )->scalar ); |
|
207
|
|
|
|
|
|
|
} |
|
208
|
|
|
|
|
|
|
|
|
209
|
49
|
|
|
49
|
|
242
|
sub _qv_elements { return( shift->_set_get_object_array_object( '_qv_elements', 'HTTP::Promise::Field::QualityValue', @_ ) ); } |
|
210
|
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
sub _qv_get |
|
212
|
|
|
|
|
|
|
{ |
|
213
|
5
|
|
|
5
|
|
13
|
my $self = shift( @_ ); |
|
214
|
5
|
|
|
|
|
11
|
my $this = shift( @_ ); |
|
215
|
5
|
50
|
33
|
|
|
30
|
return( $self->error( "No a property name to get was provided." ) ) if( !defined( $this ) || !length( "$this" ) ); |
|
216
|
5
|
|
|
|
|
26
|
my $all = $self->elements; |
|
217
|
5
|
100
|
|
|
|
343
|
if( $self->_is_a( $this => 'HTTP::Promise::Field::QualityValue' ) ) |
|
218
|
|
|
|
|
|
|
{ |
|
219
|
1
|
|
|
|
|
44
|
my $pos = $all->pos( $this ); |
|
220
|
1
|
50
|
|
|
|
46
|
return( $all->[$pos] ) if( defined( $pos ) ); |
|
221
|
|
|
|
|
|
|
} |
|
222
|
|
|
|
|
|
|
else |
|
223
|
|
|
|
|
|
|
{ |
|
224
|
4
|
|
|
|
|
67
|
foreach( @$all ) |
|
225
|
|
|
|
|
|
|
{ |
|
226
|
7
|
100
|
|
|
|
2517
|
return( $_ ) if( $_->element eq $this ); |
|
227
|
|
|
|
|
|
|
} |
|
228
|
|
|
|
|
|
|
} |
|
229
|
0
|
|
|
|
|
0
|
return( '' ); |
|
230
|
|
|
|
|
|
|
} |
|
231
|
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
sub _qv_match |
|
233
|
|
|
|
|
|
|
{ |
|
234
|
0
|
|
|
0
|
|
0
|
my $self = shift( @_ ); |
|
235
|
0
|
|
|
|
|
0
|
my $this = shift( @_ ); |
|
236
|
0
|
0
|
0
|
|
|
0
|
return( '' ) if( !defined( $this ) || !length( "$this" ) ); |
|
237
|
0
|
0
|
0
|
|
|
0
|
$this = [split( /(?:[[:blank:]]+|[[:blank:]]*\,[[:blank:]]*)/, "$this" )] if( !$self->_is_array( $this ) && ( !ref( $this ) || overload::Method( $this => '""' ) ) ); |
|
|
|
|
0
|
|
|
|
|
|
238
|
0
|
0
|
|
|
|
0
|
return( $self->error( "Invalid argument provided. Provide either an array reference or a string or something that stringifies." ) ) if( !$self->_is_array( $this ) ); |
|
239
|
0
|
|
|
|
|
0
|
my $ordered = [map( lc( $_ ), @$this )]; |
|
240
|
0
|
0
|
|
|
|
0
|
return( '' ) if( !scalar( @$ordered ) ); |
|
241
|
0
|
0
|
|
|
|
0
|
my $acceptables = $self->can( 'sort' ) ? $self->sort : $self->_qv_sort; |
|
242
|
0
|
|
|
|
|
0
|
my $ok = $self->new_array; |
|
243
|
0
|
|
|
|
|
0
|
my $seen = {}; |
|
244
|
0
|
|
|
|
|
0
|
foreach my $e ( @$acceptables ) |
|
245
|
|
|
|
|
|
|
{ |
|
246
|
0
|
|
|
|
|
0
|
my $e_lc = $e->element->lc; |
|
247
|
0
|
0
|
|
|
|
0
|
if( $e->element->index( '*' ) != -1 ) |
|
248
|
|
|
|
|
|
|
{ |
|
249
|
0
|
|
|
|
|
0
|
my $wildcard_ok = $self->_qv_match_wildcard( $e_lc => $ordered, $this ); |
|
250
|
0
|
0
|
|
|
|
0
|
return( $self->pass_error ) if( !defined( $wildcard_ok ) ); |
|
251
|
0
|
0
|
|
|
|
0
|
$ok->push( $wildcard_ok->list ) if( !$wildcard_ok->is_empty ); |
|
252
|
|
|
|
|
|
|
} |
|
253
|
|
|
|
|
|
|
else |
|
254
|
|
|
|
|
|
|
{ |
|
255
|
0
|
|
|
|
|
0
|
for( my $i = 0; $i < scalar( @$ordered ); $i++ ) |
|
256
|
|
|
|
|
|
|
{ |
|
257
|
0
|
0
|
|
|
|
0
|
if( $e_lc eq $ordered->[$i] ) |
|
258
|
|
|
|
|
|
|
{ |
|
259
|
|
|
|
|
|
|
# We'll return the caller's original value, not the lowercase one we use for comparison |
|
260
|
0
|
|
|
|
|
0
|
$ok->push( $this->[$i] ); |
|
261
|
|
|
|
|
|
|
} |
|
262
|
|
|
|
|
|
|
} |
|
263
|
|
|
|
|
|
|
} |
|
264
|
|
|
|
|
|
|
} |
|
265
|
0
|
|
|
|
|
0
|
return( $ok->unique ); |
|
266
|
|
|
|
|
|
|
} |
|
267
|
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
# Works for language and content-type and content-encoding |
|
269
|
|
|
|
|
|
|
sub _qv_match_wildcard |
|
270
|
|
|
|
|
|
|
{ |
|
271
|
0
|
|
|
0
|
|
0
|
my $self = shift( @_ ); |
|
272
|
|
|
|
|
|
|
# $proposals contain the value offered in lower case, whereas $original contains |
|
273
|
|
|
|
|
|
|
# the original value and we return our value from there. Both $proposals and $original |
|
274
|
|
|
|
|
|
|
# are of the same size. |
|
275
|
0
|
|
|
|
|
0
|
my( $acceptable, $proposals, $original, $seen ) = @_; |
|
276
|
0
|
0
|
|
|
|
0
|
return( $self->error( "Bad arguments. Usage: \$h->_qv_match_wildcard( \$acceptable, \$proposals, \$original )" ) ) unless( @_ == 3 ); |
|
277
|
0
|
0
|
|
|
|
0
|
return( $self->error( "This is not a wildcard acceptable value." ) ) if( $acceptable->index( '*' ) == -1 ); |
|
278
|
0
|
0
|
|
|
|
0
|
return( $self->error( "Proposed values must be an array reference." ) ) unless( $self->_is_array( $proposals ) ); |
|
279
|
0
|
0
|
|
|
|
0
|
return( $self->error( "Original array of proposed values must be an array reference." ) ) unless( $self->_is_array( $original ) ); |
|
280
|
0
|
|
|
|
|
0
|
my $ok = $self->new_array; |
|
281
|
0
|
0
|
|
|
|
0
|
if( $acceptable->index( '/' ) != -1 ) |
|
282
|
|
|
|
|
|
|
{ |
|
283
|
0
|
|
|
|
|
0
|
my( $main, $sub ) = $acceptable->element->split( qr/\// ); |
|
284
|
0
|
|
|
|
|
0
|
for( my $i = 0; $i < scalar( @$proposals ); $i++ ) |
|
285
|
|
|
|
|
|
|
{ |
|
286
|
0
|
|
|
|
|
0
|
my $supported = $proposals->[$i]; |
|
287
|
0
|
|
|
|
|
0
|
my( $this_main, $this_sub ) = split( /\//, "$supported", 2 ); |
|
288
|
0
|
0
|
|
|
|
0
|
if( $main eq '*' ) |
|
|
|
0
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
{ |
|
290
|
0
|
0
|
|
|
|
0
|
if( $sub eq '*' ) |
|
291
|
|
|
|
|
|
|
{ |
|
292
|
0
|
|
|
|
|
0
|
$ok->push( $original->[$i] ); |
|
293
|
|
|
|
|
|
|
} |
|
294
|
|
|
|
|
|
|
else |
|
295
|
|
|
|
|
|
|
{ |
|
296
|
0
|
0
|
|
|
|
0
|
$ok->push( $original->[$i] ) if( $this_sub eq $sub ); |
|
297
|
|
|
|
|
|
|
} |
|
298
|
|
|
|
|
|
|
} |
|
299
|
|
|
|
|
|
|
elsif( $main eq $this_main ) |
|
300
|
|
|
|
|
|
|
{ |
|
301
|
0
|
0
|
|
|
|
0
|
if( $sub eq '*' ) |
|
302
|
|
|
|
|
|
|
{ |
|
303
|
0
|
|
|
|
|
0
|
$ok->push( $original->[$i] ); |
|
304
|
|
|
|
|
|
|
} |
|
305
|
|
|
|
|
|
|
else |
|
306
|
|
|
|
|
|
|
{ |
|
307
|
0
|
0
|
|
|
|
0
|
$ok->push( $original->[$i] ) if( $this_sub eq $sub ); |
|
308
|
|
|
|
|
|
|
} |
|
309
|
|
|
|
|
|
|
} |
|
310
|
|
|
|
|
|
|
} |
|
311
|
|
|
|
|
|
|
} |
|
312
|
|
|
|
|
|
|
# simply return the proposal value since anything goes |
|
313
|
|
|
|
|
|
|
else |
|
314
|
|
|
|
|
|
|
{ |
|
315
|
0
|
|
|
|
|
0
|
$ok->push( $original->[0] ); |
|
316
|
|
|
|
|
|
|
} |
|
317
|
0
|
|
|
|
|
0
|
return( $ok ); |
|
318
|
|
|
|
|
|
|
} |
|
319
|
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
sub _qv_remove |
|
321
|
|
|
|
|
|
|
{ |
|
322
|
1
|
|
|
1
|
|
4
|
my $self = shift( @_ ); |
|
323
|
1
|
|
|
|
|
3
|
my $this = shift( @_ ); |
|
324
|
1
|
|
|
|
|
4
|
my $all = $self->elements; |
|
325
|
1
|
50
|
|
|
|
73
|
if( $self->_is_a( $this => 'HTTP::Promise::Field::QualityValue' ) ) |
|
326
|
|
|
|
|
|
|
{ |
|
327
|
0
|
|
|
|
|
0
|
return( $all->delete( $this ) ); |
|
328
|
|
|
|
|
|
|
} |
|
329
|
|
|
|
|
|
|
else |
|
330
|
|
|
|
|
|
|
{ |
|
331
|
1
|
|
|
|
|
18
|
my $e; |
|
332
|
1
|
|
|
|
|
5
|
for( my $i = 0; $i < scalar( @$all ); $i++ ) |
|
333
|
|
|
|
|
|
|
{ |
|
334
|
2
|
100
|
|
|
|
876
|
if( $all->[$i]->element eq "$this" ) |
|
335
|
|
|
|
|
|
|
{ |
|
336
|
1
|
|
|
|
|
814
|
$e = $all->splice( $i, 1 ); |
|
337
|
1
|
|
|
|
|
84
|
last; |
|
338
|
|
|
|
|
|
|
} |
|
339
|
|
|
|
|
|
|
} |
|
340
|
1
|
|
|
|
|
9
|
return( $e ); |
|
341
|
|
|
|
|
|
|
} |
|
342
|
|
|
|
|
|
|
} |
|
343
|
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
sub _qv_sort |
|
345
|
|
|
|
|
|
|
{ |
|
346
|
1
|
|
|
1
|
|
4
|
my $self = shift( @_ ); |
|
347
|
1
|
|
|
|
|
14
|
my $opts = $self->_get_args_as_hash( @_ ); |
|
348
|
1
|
50
|
|
|
|
12
|
$opts->{asc} = 0 if( !exists( $opts->{asc} ) ); |
|
349
|
1
|
|
|
|
|
5
|
my $all = $self->elements; |
|
350
|
|
|
|
|
|
|
my $sorted = $opts->{asc} |
|
351
|
0
|
|
0
|
0
|
|
0
|
? $all->sort(sub{ ( $_[0]->value // 1 ) <=> ( $_[1]->value // 1 ) }) |
|
|
|
|
0
|
|
|
|
|
|
352
|
1
|
50
|
100
|
5
|
|
107
|
: $all->sort(sub{ ( $_[1]->value // 1 ) <=> ( $_[0]->value // 1 ) }); |
|
|
5
|
|
100
|
|
|
3402
|
|
|
353
|
1
|
|
|
|
|
1023
|
$self->elements( $sorted ); |
|
354
|
1
|
|
|
|
|
235
|
return( $sorted ); |
|
355
|
|
|
|
|
|
|
} |
|
356
|
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
sub _set_get_param_boolean |
|
358
|
|
|
|
|
|
|
{ |
|
359
|
0
|
|
|
0
|
|
0
|
my $self = shift( @_ ); |
|
360
|
0
|
|
0
|
|
|
0
|
my $name = shift( @_ ) || return( $self->error( "No parameter name was provided." ) ); |
|
361
|
0
|
|
0
|
|
|
0
|
my $hv = $self->_hv || return( $self->error( "Header value object could not be found!" ) ); |
|
362
|
0
|
0
|
|
|
|
0
|
if( @_ ) |
|
363
|
|
|
|
|
|
|
{ |
|
364
|
0
|
|
|
|
|
0
|
my $v = shift( @_ ); |
|
365
|
0
|
0
|
|
|
|
0
|
if( $v ) |
|
366
|
|
|
|
|
|
|
{ |
|
367
|
0
|
|
|
|
|
0
|
$hv->param( $name => undef ); |
|
368
|
|
|
|
|
|
|
} |
|
369
|
|
|
|
|
|
|
else |
|
370
|
|
|
|
|
|
|
{ |
|
371
|
0
|
|
|
|
|
0
|
$hv->params->delete( $name ); |
|
372
|
|
|
|
|
|
|
} |
|
373
|
|
|
|
|
|
|
} |
|
374
|
0
|
|
|
|
|
0
|
return( $hv->param( $name ) ); |
|
375
|
|
|
|
|
|
|
} |
|
376
|
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
sub _set_get_param |
|
378
|
|
|
|
|
|
|
{ |
|
379
|
107
|
|
|
107
|
|
334
|
my $self = shift( @_ ); |
|
380
|
107
|
|
50
|
|
|
433
|
my $name = shift( @_ ) || return( $self->error( "No parameter name was provided." ) ); |
|
381
|
107
|
|
|
|
|
318
|
my $hv = $self->_hv; |
|
382
|
|
|
|
|
|
|
# If the HeaderValue object is not een set, and the caller just want to retrieve the |
|
383
|
|
|
|
|
|
|
# value of a property, we return an empty string (undef is for errors) |
|
384
|
107
|
50
|
66
|
|
|
3307
|
return( '' ) if( !scalar( @_ ) && !$hv ); |
|
385
|
107
|
50
|
|
|
|
959
|
return( $self->error( "Header value object (Module::Generic::HeaderValue) could not be found!" ) ) if( !$hv ); |
|
386
|
107
|
100
|
|
|
|
759
|
if( @_ ) |
|
387
|
|
|
|
|
|
|
{ |
|
388
|
18
|
|
|
|
|
90
|
$hv->param( $name => shift( @_ ) ); |
|
389
|
|
|
|
|
|
|
} |
|
390
|
107
|
|
|
|
|
16222
|
return( $hv->param( $name ) ); |
|
391
|
|
|
|
|
|
|
} |
|
392
|
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
sub _set_get_params |
|
394
|
|
|
|
|
|
|
{ |
|
395
|
0
|
|
|
0
|
|
0
|
my $self = shift( @_ ); |
|
396
|
0
|
|
0
|
|
|
0
|
my $hv = $self->_hv || return( $self->error( "Header value object could not be found!" ) ); |
|
397
|
0
|
|
|
|
|
0
|
my $params = $hv->params; |
|
398
|
0
|
0
|
|
|
|
0
|
if( @_ ) |
|
399
|
|
|
|
|
|
|
{ |
|
400
|
0
|
|
|
|
|
0
|
while( my( $n, $v ) = splice( @_, 0, 2 ) ) |
|
401
|
|
|
|
|
|
|
{ |
|
402
|
0
|
|
|
|
|
0
|
$params->set( $n => $v ); |
|
403
|
|
|
|
|
|
|
} |
|
404
|
|
|
|
|
|
|
} |
|
405
|
|
|
|
|
|
|
else |
|
406
|
|
|
|
|
|
|
{ |
|
407
|
0
|
|
|
|
|
0
|
return( $params ); |
|
408
|
|
|
|
|
|
|
} |
|
409
|
|
|
|
|
|
|
} |
|
410
|
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
sub _set_get_properties_as_string |
|
412
|
|
|
|
|
|
|
{ |
|
413
|
28
|
|
|
28
|
|
72
|
my $self = shift( @_ ); |
|
414
|
28
|
|
|
|
|
151
|
my $opts = $self->_get_args_as_hash( @_ ); |
|
415
|
28
|
|
100
|
|
|
2433
|
my $sep = $opts->{separator} || $opts->{sep} || ','; |
|
416
|
28
|
|
100
|
|
|
128
|
my $eq = $opts->{equal} || '='; |
|
417
|
28
|
|
|
|
|
93
|
my $params = $self->params; |
|
418
|
28
|
|
|
|
|
21297
|
my $props = $self->properties; |
|
419
|
28
|
|
|
|
|
20707
|
my $quotes = {}; |
|
420
|
28
|
100
|
|
|
|
264
|
$quotes = $self->_needs_quotes if( $self->can( '_needs_quotes' ) ); |
|
421
|
28
|
|
|
|
|
10411
|
my @res = (); |
|
422
|
11
|
|
|
11
|
|
130
|
no overloading '""'; |
|
|
11
|
|
|
|
|
25
|
|
|
|
11
|
|
|
|
|
8133
|
|
|
423
|
28
|
|
|
|
|
112
|
foreach( @$params ) |
|
424
|
|
|
|
|
|
|
{ |
|
425
|
98
|
50
|
|
|
|
2700
|
if( !exists( $props->{ $_ } ) ) |
|
426
|
|
|
|
|
|
|
{ |
|
427
|
|
|
|
|
|
|
# warnings::warn( "Property is in our stack, but not in our repository of properties, skipping.\n" ) if( warnings::enabled( ref( $self ) ) ); |
|
428
|
|
|
|
|
|
|
# warn( "Property is in our stack, but not in our repository of properties, skipping.\n" ) if( $self->_warnings_is_enabled ); |
|
429
|
0
|
|
|
|
|
0
|
warn( "Property \"$_\" is in our stack, but not in our repository of properties, skipping.\n" ); |
|
430
|
0
|
|
|
|
|
0
|
next; |
|
431
|
|
|
|
|
|
|
} |
|
432
|
|
|
|
|
|
|
# If the property exists in our repo, but has no value it is a boolean |
|
433
|
98
|
100
|
|
|
|
1996
|
push( @res, defined( $props->{ $_ } ) ? sprintf( "$_${eq}%s", ( $quotes->{ $_ } ? '"' : '' ) . $props->{ $_ } . ( $quotes->{ $_ } ? '"' : '' ) ) : $_ ); |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
} |
|
435
|
28
|
|
|
|
|
1491
|
return( join( "${sep} ", @res ) ); |
|
436
|
|
|
|
|
|
|
} |
|
437
|
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
# Used by Cache-Control |
|
439
|
|
|
|
|
|
|
sub _set_get_property_boolean |
|
440
|
|
|
|
|
|
|
{ |
|
441
|
32
|
|
|
32
|
|
84
|
my $self = shift( @_ ); |
|
442
|
32
|
|
50
|
|
|
134
|
my $prop = shift( @_ ) || return( $self->error( "No parameter name was provided." ) ); |
|
443
|
32
|
|
|
|
|
89
|
my $params = $self->params; |
|
444
|
32
|
|
|
|
|
24143
|
my $props = $self->properties; |
|
445
|
32
|
|
|
|
|
26073
|
my $pos = $params->pos( $prop ); |
|
446
|
32
|
100
|
|
|
|
826
|
if( @_ ) |
|
447
|
|
|
|
|
|
|
{ |
|
448
|
9
|
|
|
|
|
24
|
my $bool = shift( @_ ); |
|
449
|
9
|
100
|
|
|
|
25
|
if( defined( $pos ) ) |
|
450
|
|
|
|
|
|
|
{ |
|
451
|
4
|
100
|
100
|
|
|
28
|
if( defined( $bool ) && $bool ) |
|
452
|
|
|
|
|
|
|
{ |
|
453
|
|
|
|
|
|
|
# Nothing to do, it is already there |
|
454
|
|
|
|
|
|
|
# Making sure we have it in our properties hash as well |
|
455
|
1
|
|
|
|
|
7
|
$props->{ $prop } = undef; |
|
456
|
|
|
|
|
|
|
} |
|
457
|
|
|
|
|
|
|
# Undefined or false properties get removed |
|
458
|
|
|
|
|
|
|
else |
|
459
|
|
|
|
|
|
|
{ |
|
460
|
3
|
|
|
|
|
23
|
$params->splice( $pos, 1 ); |
|
461
|
3
|
|
|
|
|
253
|
$props->delete( $prop ); |
|
462
|
|
|
|
|
|
|
} |
|
463
|
|
|
|
|
|
|
} |
|
464
|
|
|
|
|
|
|
# Not there yet |
|
465
|
|
|
|
|
|
|
else |
|
466
|
|
|
|
|
|
|
{ |
|
467
|
5
|
50
|
33
|
|
|
39
|
if( defined( $bool ) && $bool ) |
|
468
|
|
|
|
|
|
|
{ |
|
469
|
5
|
|
|
|
|
30
|
$params->push( $prop ); |
|
470
|
5
|
|
|
|
|
51
|
$props->{ $prop } = undef; |
|
471
|
|
|
|
|
|
|
} |
|
472
|
|
|
|
|
|
|
# Nothing to do, it is not there yet |
|
473
|
|
|
|
|
|
|
# Still make sure it is removed from the properties hash as well |
|
474
|
|
|
|
|
|
|
else |
|
475
|
|
|
|
|
|
|
{ |
|
476
|
0
|
|
|
|
|
0
|
$props->delete( $prop ); |
|
477
|
|
|
|
|
|
|
} |
|
478
|
|
|
|
|
|
|
} |
|
479
|
9
|
|
|
|
|
271
|
return( $bool ); |
|
480
|
|
|
|
|
|
|
} |
|
481
|
|
|
|
|
|
|
else |
|
482
|
|
|
|
|
|
|
{ |
|
483
|
23
|
100
|
|
|
|
214
|
return( defined( $pos ) ? 1 : 0 ); |
|
484
|
|
|
|
|
|
|
} |
|
485
|
|
|
|
|
|
|
} |
|
486
|
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
# Used by Cache-Control, Expect-CT |
|
488
|
|
|
|
|
|
|
sub _set_get_property_number |
|
489
|
|
|
|
|
|
|
{ |
|
490
|
18
|
|
|
18
|
|
51
|
my $self = shift( @_ ); |
|
491
|
18
|
|
50
|
|
|
79
|
my $prop = shift( @_ ) || return( $self->error( "No parameter name was provided." ) ); |
|
492
|
18
|
100
|
|
|
|
65
|
if( @_ ) |
|
493
|
|
|
|
|
|
|
{ |
|
494
|
2
|
|
|
|
|
6
|
my $v = shift( @_ ); |
|
495
|
2
|
50
|
66
|
|
|
16
|
return( $self->error( "The value provided for property \"${prop}\" is not a number." ) ) if( defined( $v ) && !$self->_is_integer( $v ) ); |
|
496
|
2
|
|
|
|
|
27
|
return( $self->_set_get_property_value( $prop => $v ) ); |
|
497
|
|
|
|
|
|
|
} |
|
498
|
16
|
|
|
|
|
78
|
return( $self->_set_get_property_value( $prop ) ); |
|
499
|
|
|
|
|
|
|
} |
|
500
|
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
# Used by Expect-CT |
|
502
|
|
|
|
|
|
|
sub _set_get_property_value |
|
503
|
|
|
|
|
|
|
{ |
|
504
|
76
|
|
|
76
|
|
151
|
my $self = shift( @_ ); |
|
505
|
76
|
|
50
|
|
|
220
|
my $prop = shift( @_ ) || return( $self->error( "No parameter name was provided." ) ); |
|
506
|
76
|
|
|
|
|
135
|
my $opts = {}; |
|
507
|
76
|
100
|
|
|
|
215
|
$opts = pop( @_ ) if( ref( $_[-1] ) eq 'HASH' ); |
|
508
|
76
|
|
100
|
|
|
362
|
$opts->{needs_quotes} //= 0; |
|
509
|
76
|
|
100
|
|
|
302
|
$opts->{maybe_boolean} //= 0; |
|
510
|
76
|
|
|
|
|
178
|
my $params = $self->params; |
|
511
|
76
|
|
|
|
|
58684
|
my $props = $self->properties; |
|
512
|
76
|
|
|
|
|
56332
|
my $pos = $params->pos( $prop ); |
|
513
|
76
|
100
|
|
|
|
2276
|
if( @_ ) |
|
514
|
|
|
|
|
|
|
{ |
|
515
|
4
|
|
|
|
|
21
|
my $v = shift( @_ ); |
|
516
|
4
|
100
|
|
|
|
15
|
if( !defined( $v ) ) |
|
517
|
|
|
|
|
|
|
{ |
|
518
|
2
|
50
|
|
|
|
9
|
$self->params->splice( $pos, 1 ) if( defined( $pos ) ); |
|
519
|
2
|
|
|
|
|
1155
|
return( $self->properties->delete( $prop ) ); |
|
520
|
|
|
|
|
|
|
} |
|
521
|
|
|
|
|
|
|
|
|
522
|
|
|
|
|
|
|
# Not there yet, add the value |
|
523
|
2
|
50
|
|
|
|
20
|
if( !defined( $pos ) ) |
|
524
|
|
|
|
|
|
|
{ |
|
525
|
2
|
50
|
0
|
|
|
19
|
$params->push( $prop ) if( !$opts->{maybe_boolean} || ( $opts->{maybe_boolean} && $v ) ); |
|
|
|
|
33
|
|
|
|
|
|
526
|
2
|
50
|
33
|
|
|
26
|
if( exists( $opts->{maybe_boolean} ) && $opts->{maybe_boolean} ) |
|
527
|
|
|
|
|
|
|
{ |
|
528
|
0
|
0
|
|
|
|
0
|
if( $v == 1 ) |
|
|
|
0
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
{ |
|
530
|
0
|
|
|
|
|
0
|
$props->{ $prop } = undef; |
|
531
|
|
|
|
|
|
|
} |
|
532
|
|
|
|
|
|
|
elsif( !$v ) |
|
533
|
|
|
|
|
|
|
{ |
|
534
|
0
|
|
|
|
|
0
|
$props->delete( $prop ); |
|
535
|
|
|
|
|
|
|
} |
|
536
|
|
|
|
|
|
|
else |
|
537
|
|
|
|
|
|
|
{ |
|
538
|
0
|
|
|
|
|
0
|
$props->{ $prop } = $v; |
|
539
|
|
|
|
|
|
|
} |
|
540
|
|
|
|
|
|
|
} |
|
541
|
|
|
|
|
|
|
else |
|
542
|
|
|
|
|
|
|
{ |
|
543
|
2
|
|
|
|
|
13
|
$props->{ $prop } = $v; |
|
544
|
|
|
|
|
|
|
} |
|
545
|
|
|
|
|
|
|
} |
|
546
|
|
|
|
|
|
|
else |
|
547
|
|
|
|
|
|
|
{ |
|
548
|
0
|
0
|
0
|
|
|
0
|
if( exists( $opts->{maybe_boolean} ) && $opts->{maybe_boolean} ) |
|
549
|
|
|
|
|
|
|
{ |
|
550
|
0
|
0
|
|
|
|
0
|
if( !$v ) |
|
|
|
0
|
|
|
|
|
|
|
551
|
|
|
|
|
|
|
{ |
|
552
|
0
|
|
|
|
|
0
|
$params->splice( $pos, 1 ); |
|
553
|
0
|
|
|
|
|
0
|
$props->delete( $prop ); |
|
554
|
|
|
|
|
|
|
} |
|
555
|
|
|
|
|
|
|
elsif( $v == 1 ) |
|
556
|
|
|
|
|
|
|
{ |
|
557
|
0
|
|
|
|
|
0
|
$props->{ $prop } = undef; |
|
558
|
|
|
|
|
|
|
} |
|
559
|
|
|
|
|
|
|
else |
|
560
|
|
|
|
|
|
|
{ |
|
561
|
0
|
|
|
|
|
0
|
$props->{ $prop } = $v; |
|
562
|
|
|
|
|
|
|
} |
|
563
|
|
|
|
|
|
|
} |
|
564
|
|
|
|
|
|
|
else |
|
565
|
|
|
|
|
|
|
{ |
|
566
|
0
|
|
|
|
|
0
|
$props->{ $prop } = $v; |
|
567
|
|
|
|
|
|
|
} |
|
568
|
|
|
|
|
|
|
} |
|
569
|
|
|
|
|
|
|
# Used for non-standard properties during stringification |
|
570
|
2
|
100
|
66
|
|
|
86
|
if( $opts->{needs_quotes} && $self->can( '_needs_quotes' ) ) |
|
571
|
|
|
|
|
|
|
{ |
|
572
|
1
|
|
|
|
|
8
|
$self->_needs_quotes->set( $prop => 1 ); |
|
573
|
|
|
|
|
|
|
} |
|
574
|
2
|
|
|
|
|
566
|
return( $v ); |
|
575
|
|
|
|
|
|
|
} |
|
576
|
|
|
|
|
|
|
else |
|
577
|
|
|
|
|
|
|
{ |
|
578
|
72
|
50
|
|
|
|
172
|
if( defined( $pos ) ) |
|
579
|
|
|
|
|
|
|
{ |
|
580
|
|
|
|
|
|
|
return( |
|
581
|
|
|
|
|
|
|
$opts->{maybe_boolean} |
|
582
|
|
|
|
|
|
|
? defined( $pos ) ? 1 : 0 |
|
583
|
72
|
50
|
|
|
|
450
|
: $props->{ $prop } |
|
|
|
100
|
|
|
|
|
|
|
584
|
|
|
|
|
|
|
); |
|
585
|
|
|
|
|
|
|
} |
|
586
|
0
|
|
|
|
|
0
|
return( '' ); |
|
587
|
|
|
|
|
|
|
} |
|
588
|
|
|
|
|
|
|
} |
|
589
|
|
|
|
|
|
|
|
|
590
|
|
|
|
|
|
|
# Same as _set_get_param but with surrounding double quotes |
|
591
|
|
|
|
|
|
|
sub _set_get_qparam |
|
592
|
|
|
|
|
|
|
{ |
|
593
|
14
|
|
|
14
|
|
44
|
my $self = shift( @_ ); |
|
594
|
14
|
|
50
|
|
|
55
|
my $name = shift( @_ ) || return( $self->error( "No parameter name was provided." ) ); |
|
595
|
14
|
|
50
|
|
|
40
|
my $hv = $self->_hv || return( $self->error( "Header value object could not be found!" ) ); |
|
596
|
14
|
|
|
|
|
431
|
my $v; |
|
597
|
14
|
50
|
|
|
|
41
|
if( @_ ) |
|
598
|
|
|
|
|
|
|
{ |
|
599
|
0
|
|
|
|
|
0
|
$v = shift( @_ ); |
|
600
|
0
|
|
|
|
|
0
|
$v =~ s/^\"//; |
|
601
|
0
|
|
|
|
|
0
|
$v =~ s/(?<!\\)\"$//; |
|
602
|
0
|
|
|
|
|
0
|
$hv->param( $name => qq{"${v}"} ); |
|
603
|
|
|
|
|
|
|
} |
|
604
|
|
|
|
|
|
|
else |
|
605
|
|
|
|
|
|
|
{ |
|
606
|
14
|
|
|
|
|
50
|
$v = $hv->param( $name ); |
|
607
|
14
|
100
|
100
|
|
|
8203
|
return( '' ) if( !defined( $v ) || !length( "$v" ) ); |
|
608
|
11
|
|
|
|
|
34
|
$v =~ s/^\"//; |
|
609
|
11
|
|
|
|
|
28
|
$v =~ s/(?<!\\)\"$//; |
|
610
|
|
|
|
|
|
|
} |
|
611
|
11
|
|
|
|
|
76
|
return( $v ); |
|
612
|
|
|
|
|
|
|
} |
|
613
|
|
|
|
|
|
|
|
|
614
|
|
|
|
|
|
|
sub _set_get_value |
|
615
|
|
|
|
|
|
|
{ |
|
616
|
0
|
|
|
0
|
|
0
|
my $self = shift( @_ ); |
|
617
|
0
|
|
|
|
|
0
|
my $hv = $self->_hv; |
|
618
|
0
|
0
|
|
|
|
0
|
if( @_ ) |
|
619
|
|
|
|
|
|
|
{ |
|
620
|
0
|
|
|
|
|
0
|
$hv->value( shift( @_ ) ); |
|
621
|
|
|
|
|
|
|
} |
|
622
|
0
|
|
|
|
|
0
|
return( $hv->value_data ); |
|
623
|
|
|
|
|
|
|
} |
|
624
|
|
|
|
|
|
|
|
|
625
|
|
|
|
|
|
|
# NOTE: sub FREEZE is inherited |
|
626
|
|
|
|
|
|
|
|
|
627
|
21
|
|
|
21
|
0
|
1564
|
sub STORABLE_freeze { CORE::return( CORE::shift->FREEZE( @_ ) ); } |
|
628
|
|
|
|
|
|
|
|
|
629
|
21
|
|
|
21
|
0
|
13262
|
sub STORABLE_thaw { CORE::return( CORE::shift->THAW( @_ ) ); } |
|
630
|
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
# NOTE: sub THAW is inherited |
|
632
|
|
|
|
|
|
|
|
|
633
|
|
|
|
|
|
|
# NOTE: HTTP::Promise::Field::QualityValue class |
|
634
|
|
|
|
|
|
|
{ |
|
635
|
|
|
|
|
|
|
package |
|
636
|
|
|
|
|
|
|
HTTP::Promise::Field::QualityValue; |
|
637
|
|
|
|
|
|
|
BEGIN |
|
638
|
0
|
|
|
|
|
0
|
{ |
|
639
|
11
|
|
|
11
|
|
17219
|
use strict; |
|
|
11
|
|
|
|
|
40
|
|
|
|
11
|
|
|
|
|
435
|
|
|
640
|
11
|
|
|
11
|
|
113
|
use warnings; |
|
|
11
|
|
|
|
|
28
|
|
|
|
11
|
|
|
|
|
585
|
|
|
641
|
11
|
|
|
11
|
|
93
|
use parent qw( Module::Generic ); |
|
|
11
|
|
|
|
|
37
|
|
|
|
11
|
|
|
|
|
77
|
|
|
642
|
|
|
|
|
|
|
use overload ( |
|
643
|
|
|
|
|
|
|
'""' => 'as_string', |
|
644
|
70
|
|
|
70
|
|
2446
|
'bool' => sub{1}, |
|
645
|
11
|
|
|
11
|
|
1122
|
); |
|
|
11
|
|
|
0
|
|
37
|
|
|
|
11
|
|
|
|
|
136
|
|
|
646
|
|
|
|
|
|
|
}; |
|
647
|
|
|
|
|
|
|
|
|
648
|
|
|
|
|
|
|
sub as_string |
|
649
|
|
|
|
|
|
|
{ |
|
650
|
67
|
|
|
67
|
|
1197
|
my $self = shift( @_ ); |
|
651
|
67
|
|
|
|
|
145
|
my $elem = $self->element; |
|
652
|
67
|
|
|
|
|
54098
|
my $val = $self->value; |
|
653
|
67
|
100
|
66
|
|
|
50680
|
return( $elem ) if( !defined( $val ) || !length( "${val}" ) ); |
|
654
|
44
|
|
|
|
|
401
|
return( "${elem};q=${val}" ); |
|
655
|
|
|
|
|
|
|
} |
|
656
|
|
|
|
|
|
|
|
|
657
|
|
|
|
|
|
|
sub init |
|
658
|
|
|
|
|
|
|
{ |
|
659
|
35
|
|
|
35
|
|
2711
|
my $self = shift( @_ ); |
|
660
|
35
|
|
|
|
|
80
|
my $elem = shift( @_ ); |
|
661
|
35
|
50
|
33
|
|
|
210
|
return( $self->error( "No element was provided for this quality value." ) ) if( !defined( $elem ) || !length( "$elem" ) ); |
|
662
|
35
|
|
|
|
|
95
|
my $val = shift( @_ ); |
|
663
|
35
|
50
|
|
|
|
131
|
$self->SUPER::init( @_ ) || return( $self->pass_error ); |
|
664
|
35
|
|
|
|
|
123
|
$self->element( $elem ); |
|
665
|
35
|
|
|
|
|
66192
|
$self->value( $val ); |
|
666
|
35
|
|
|
|
|
1046452
|
return( $self ); |
|
667
|
|
|
|
|
|
|
} |
|
668
|
|
|
|
|
|
|
|
|
669
|
123
|
|
|
123
|
|
5437
|
sub element { return( shift->_set_get_scalar_as_object( 'element', @_ ) ); } |
|
670
|
|
|
|
|
|
|
|
|
671
|
124
|
|
|
124
|
|
10629
|
sub value { return( shift->_set_get_number( { field => 'value', undef_ok => 1 }, @_ ) ); } |
|
672
|
|
|
|
|
|
|
|
|
673
|
|
|
|
|
|
|
# NOTE: sub FREEZE is inherited |
|
674
|
|
|
|
|
|
|
|
|
675
|
17
|
|
|
17
|
|
10467
|
sub STORABLE_freeze { CORE::return( CORE::shift->FREEZE( @_ ) ); } |
|
676
|
|
|
|
|
|
|
|
|
677
|
17
|
|
|
17
|
|
13934
|
sub STORABLE_thaw { CORE::return( CORE::shift->THAW( @_ ) ); } |
|
678
|
|
|
|
|
|
|
|
|
679
|
|
|
|
|
|
|
# NOTE: sub THAW is inherited |
|
680
|
|
|
|
|
|
|
|
|
681
|
|
|
|
|
|
|
} |
|
682
|
|
|
|
|
|
|
|
|
683
|
|
|
|
|
|
|
1; |
|
684
|
|
|
|
|
|
|
# NOTE: POD |
|
685
|
|
|
|
|
|
|
__END__ |
|
686
|
|
|
|
|
|
|
|
|
687
|
|
|
|
|
|
|
=encoding utf-8 |
|
688
|
|
|
|
|
|
|
|
|
689
|
|
|
|
|
|
|
=head1 NAME |
|
690
|
|
|
|
|
|
|
|
|
691
|
|
|
|
|
|
|
HTTP::Promise::Headers::Generic - Generic HTTP Header Class |
|
692
|
|
|
|
|
|
|
|
|
693
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
694
|
|
|
|
|
|
|
|
|
695
|
|
|
|
|
|
|
package HTTP::Promise::Headers::MyHeader; |
|
696
|
|
|
|
|
|
|
use strict; |
|
697
|
|
|
|
|
|
|
use warnings; |
|
698
|
|
|
|
|
|
|
use parent qw( HTTP::Promise::Headers::Generic ); |
|
699
|
|
|
|
|
|
|
|
|
700
|
|
|
|
|
|
|
=head1 VERSION |
|
701
|
|
|
|
|
|
|
|
|
702
|
|
|
|
|
|
|
v0.1.1 |
|
703
|
|
|
|
|
|
|
|
|
704
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
705
|
|
|
|
|
|
|
|
|
706
|
|
|
|
|
|
|
This is a generic module to be inherited by HTTP header modules. See for example: 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> |
|
707
|
|
|
|
|
|
|
|
|
708
|
|
|
|
|
|
|
=head1 METHODS |
|
709
|
|
|
|
|
|
|
|
|
710
|
|
|
|
|
|
|
=head2 as_string |
|
711
|
|
|
|
|
|
|
|
|
712
|
|
|
|
|
|
|
Return a string representation of this header field object. |
|
713
|
|
|
|
|
|
|
|
|
714
|
|
|
|
|
|
|
=head2 field_name |
|
715
|
|
|
|
|
|
|
|
|
716
|
|
|
|
|
|
|
Sets or gets the object headers field name |
|
717
|
|
|
|
|
|
|
|
|
718
|
|
|
|
|
|
|
=head2 uri_escape_utf8 |
|
719
|
|
|
|
|
|
|
|
|
720
|
|
|
|
|
|
|
Provided with some string and this returns the URI-escaped version of this using L<URI::Escape::XS> |
|
721
|
|
|
|
|
|
|
|
|
722
|
|
|
|
|
|
|
=head2 value |
|
723
|
|
|
|
|
|
|
|
|
724
|
|
|
|
|
|
|
By default and superseded by inheriting classes such as Content-Type that has more elaborate value with parameters |
|
725
|
|
|
|
|
|
|
|
|
726
|
|
|
|
|
|
|
=head1 PRIVATE METHODS |
|
727
|
|
|
|
|
|
|
|
|
728
|
|
|
|
|
|
|
=head2 _filename_decode |
|
729
|
|
|
|
|
|
|
|
|
730
|
|
|
|
|
|
|
Provided with a filename, and this will decode it, if necessary, by calling L<HTTP::Promise::Headers/decode_filename> |
|
731
|
|
|
|
|
|
|
|
|
732
|
|
|
|
|
|
|
It returns in list context the decoded filename, the character-set and language used and in scalar context the decoded filename. |
|
733
|
|
|
|
|
|
|
|
|
734
|
|
|
|
|
|
|
If the filename did not need to be decoded, it will return the filename untouched, so this is quite safe to use. |
|
735
|
|
|
|
|
|
|
|
|
736
|
|
|
|
|
|
|
See L<rfc2231|https://tools.ietf.org/html/rfc2231> |
|
737
|
|
|
|
|
|
|
|
|
738
|
|
|
|
|
|
|
=head2 _filename_encode |
|
739
|
|
|
|
|
|
|
|
|
740
|
|
|
|
|
|
|
Provided with a filename, and an optional language, and this will encode it, if necessary, following the L<rfc2231|https://tools.ietf.org/html/rfc2231> |
|
741
|
|
|
|
|
|
|
|
|
742
|
|
|
|
|
|
|
If the filename did not need to be encoded, it returns C<undef>, so be sure to check for the return value. |
|
743
|
|
|
|
|
|
|
|
|
744
|
|
|
|
|
|
|
See L<rfc2231|https://tools.ietf.org/html/rfc2231> |
|
745
|
|
|
|
|
|
|
|
|
746
|
|
|
|
|
|
|
=head2 _hv |
|
747
|
|
|
|
|
|
|
|
|
748
|
|
|
|
|
|
|
Sets or gets the L<header value object|Module::Generic::HeaderValue> |
|
749
|
|
|
|
|
|
|
|
|
750
|
|
|
|
|
|
|
=head2 _hv_as_string |
|
751
|
|
|
|
|
|
|
|
|
752
|
|
|
|
|
|
|
Returns the L<header value object|Module::Generic::HeaderValue> as a string, if a header value object is set, or an empty string otherwise. |
|
753
|
|
|
|
|
|
|
|
|
754
|
|
|
|
|
|
|
=head2 _get_header_value_object |
|
755
|
|
|
|
|
|
|
|
|
756
|
|
|
|
|
|
|
This instantiates a new L<header value object|Module::Generic::HeaderValue>, passing it whatever arguments were provided, and return the new object. |
|
757
|
|
|
|
|
|
|
|
|
758
|
|
|
|
|
|
|
=head2 _make_boundary |
|
759
|
|
|
|
|
|
|
|
|
760
|
|
|
|
|
|
|
Returns a new boundary using L<Data::UUID> |
|
761
|
|
|
|
|
|
|
|
|
762
|
|
|
|
|
|
|
=head2 _new_hv |
|
763
|
|
|
|
|
|
|
|
|
764
|
|
|
|
|
|
|
Does the same thing as L</_get_header_value_object> |
|
765
|
|
|
|
|
|
|
|
|
766
|
|
|
|
|
|
|
=head2 _new_qv_object |
|
767
|
|
|
|
|
|
|
|
|
768
|
|
|
|
|
|
|
This instantiates a new quality value object using C<HTTP::Promise::Field::QualityValue>, passing it whatever arguments were provided, and return the new object. |
|
769
|
|
|
|
|
|
|
|
|
770
|
|
|
|
|
|
|
=head2 _parse_header_value |
|
771
|
|
|
|
|
|
|
|
|
772
|
|
|
|
|
|
|
Provided with a string, and this instantiates a new L<header value object|Module::Generic::HeaderValue>, by calling L<Module::Generic::HeaderValue/new_from_header> passing it the string and any other arguments that were provided, and return the new object. |
|
773
|
|
|
|
|
|
|
|
|
774
|
|
|
|
|
|
|
Upon error, this sets an L<error|Module::Generic/error> and returns C<undef> |
|
775
|
|
|
|
|
|
|
|
|
776
|
|
|
|
|
|
|
=head2 _parse_quality_value |
|
777
|
|
|
|
|
|
|
|
|
778
|
|
|
|
|
|
|
Provided with a string representing a quality value, and this will parse it and return a new L<array object|Module::Generic::Array> |
|
779
|
|
|
|
|
|
|
|
|
780
|
|
|
|
|
|
|
See L<rfc7231, section 5.3.1|https://tools.ietf.org/html/rfc7231#section-5.3.1> |
|
781
|
|
|
|
|
|
|
|
|
782
|
|
|
|
|
|
|
=head2 _qstring_join |
|
783
|
|
|
|
|
|
|
|
|
784
|
|
|
|
|
|
|
Provided with a list of strings and this will ensure any special characters are escaped before returning them as one string separated by comma. |
|
785
|
|
|
|
|
|
|
|
|
786
|
|
|
|
|
|
|
See also L</_qstring_split> |
|
787
|
|
|
|
|
|
|
|
|
788
|
|
|
|
|
|
|
=head2 _qstring_split |
|
789
|
|
|
|
|
|
|
|
|
790
|
|
|
|
|
|
|
Provided with a string, and this will split it by comma, mindful of any special characters. |
|
791
|
|
|
|
|
|
|
|
|
792
|
|
|
|
|
|
|
It returns an array of the parts split. |
|
793
|
|
|
|
|
|
|
|
|
794
|
|
|
|
|
|
|
=head2 _qv_add |
|
795
|
|
|
|
|
|
|
|
|
796
|
|
|
|
|
|
|
Provided with an element and its value, and this will instantiate a new C<HTTP::Promise::Field::QualityValue> object and add it to the list of objects contained with the method C<elements> (implemented in each specific header module) |
|
797
|
|
|
|
|
|
|
|
|
798
|
|
|
|
|
|
|
=head2 _qv_as_string |
|
799
|
|
|
|
|
|
|
|
|
800
|
|
|
|
|
|
|
This takes the list of all elements contained with the method C<elements> (implemented in each specific header module) and returns them as a string separated by comma. |
|
801
|
|
|
|
|
|
|
|
|
802
|
|
|
|
|
|
|
=head2 _qv_elements |
|
803
|
|
|
|
|
|
|
|
|
804
|
|
|
|
|
|
|
Sets or gets the L<array object|Module::Generic::Array> containing the list of quality values. |
|
805
|
|
|
|
|
|
|
|
|
806
|
|
|
|
|
|
|
=head2 _qv_get |
|
807
|
|
|
|
|
|
|
|
|
808
|
|
|
|
|
|
|
Provided with a quality value element, and this returns its corresponding object if it exists, or an empty string otherwise. |
|
809
|
|
|
|
|
|
|
|
|
810
|
|
|
|
|
|
|
Upon error, this sets an L<error|Module::Generic/error> and returns C<undef> |
|
811
|
|
|
|
|
|
|
|
|
812
|
|
|
|
|
|
|
=head2 _qv_match |
|
813
|
|
|
|
|
|
|
|
|
814
|
|
|
|
|
|
|
Provided with a string, and this returns an L<array object|Module::Generic::Array> of matching quality value objects in their order of preference. |
|
815
|
|
|
|
|
|
|
|
|
816
|
|
|
|
|
|
|
Upon error, this sets an L<error|Module::Generic/error> and returns C<undef> |
|
817
|
|
|
|
|
|
|
|
|
818
|
|
|
|
|
|
|
=head2 _qv_match_wildcard |
|
819
|
|
|
|
|
|
|
|
|
820
|
|
|
|
|
|
|
This method is used to do the actual work of matching a requested value such as C<fr-FR> or <text/html> depending on the type of header, against the ones announced in the header. |
|
821
|
|
|
|
|
|
|
|
|
822
|
|
|
|
|
|
|
For example: |
|
823
|
|
|
|
|
|
|
|
|
824
|
|
|
|
|
|
|
Accept: image/* |
|
825
|
|
|
|
|
|
|
Accept: text/html |
|
826
|
|
|
|
|
|
|
Accept: */* |
|
827
|
|
|
|
|
|
|
Accept: text/html, application/xhtml+xml, application/xml;q=0.9, image/webp, */*;q=0.8 |
|
828
|
|
|
|
|
|
|
|
|
829
|
|
|
|
|
|
|
Accept-Encoding: gzip |
|
830
|
|
|
|
|
|
|
|
|
831
|
|
|
|
|
|
|
Accept-Encoding: deflate, gzip;q=1.0, *;q=0.5 |
|
832
|
|
|
|
|
|
|
|
|
833
|
|
|
|
|
|
|
Accept-Language: fr-FR, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5 |
|
834
|
|
|
|
|
|
|
|
|
835
|
|
|
|
|
|
|
|
|
836
|
|
|
|
|
|
|
This takes an "acceptable" L<scalar object|Module::Generic::Scalar>, an L<array object|Module::Generic::Array> of proposed quality-value objects, and an L<array object|Module::Generic::Array> of original proposed value, and possibly an hash reference of already seen object address. |
|
837
|
|
|
|
|
|
|
|
|
838
|
|
|
|
|
|
|
It returns an L<array object|Module::Generic::Array> of matching quality-value objects. |
|
839
|
|
|
|
|
|
|
|
|
840
|
|
|
|
|
|
|
=head2 _qv_remove |
|
841
|
|
|
|
|
|
|
|
|
842
|
|
|
|
|
|
|
Provided with a quality-value string or object, and this will remove it from the list of elements. |
|
843
|
|
|
|
|
|
|
|
|
844
|
|
|
|
|
|
|
It returns the element removed, or upon error, this sets an L<error|Module::Generic/error> and returns C<undef> |
|
845
|
|
|
|
|
|
|
|
|
846
|
|
|
|
|
|
|
=head2 _qv_sort |
|
847
|
|
|
|
|
|
|
|
|
848
|
|
|
|
|
|
|
This takes an optional hash or hash reference of options and returns an L<array object|Module::Generic::Array> of sorted element by their quality-value. |
|
849
|
|
|
|
|
|
|
|
|
850
|
|
|
|
|
|
|
Supported options are: |
|
851
|
|
|
|
|
|
|
|
|
852
|
|
|
|
|
|
|
=over 4 |
|
853
|
|
|
|
|
|
|
|
|
854
|
|
|
|
|
|
|
=item * C<asc> |
|
855
|
|
|
|
|
|
|
|
|
856
|
|
|
|
|
|
|
Boolean. If true, the elements will be sorted in their ascending order, otherwise in their descending order. |
|
857
|
|
|
|
|
|
|
|
|
858
|
|
|
|
|
|
|
=back |
|
859
|
|
|
|
|
|
|
|
|
860
|
|
|
|
|
|
|
=head2 _set_get_param_boolean |
|
861
|
|
|
|
|
|
|
|
|
862
|
|
|
|
|
|
|
In retrieval mode, this takes a header value parameter, and this returns its value. |
|
863
|
|
|
|
|
|
|
|
|
864
|
|
|
|
|
|
|
In assignment mode, this takes a header value parameter, and a value, possibly C<undef> and assign it to the given parameter. |
|
865
|
|
|
|
|
|
|
|
|
866
|
|
|
|
|
|
|
Upon error, this sets an L<error|Module::Generic/error> and returns C<undef> |
|
867
|
|
|
|
|
|
|
|
|
868
|
|
|
|
|
|
|
=head2 _set_get_param |
|
869
|
|
|
|
|
|
|
|
|
870
|
|
|
|
|
|
|
In retrieval mode, this takes a header value parameter, and it returns its corresponding value. |
|
871
|
|
|
|
|
|
|
|
|
872
|
|
|
|
|
|
|
In assignment mode, this takes a header value parameter, and a value and assign it. |
|
873
|
|
|
|
|
|
|
|
|
874
|
|
|
|
|
|
|
Upon error, this sets an L<error|Module::Generic/error> and returns C<undef> |
|
875
|
|
|
|
|
|
|
|
|
876
|
|
|
|
|
|
|
=head2 _set_get_params |
|
877
|
|
|
|
|
|
|
|
|
878
|
|
|
|
|
|
|
This takes a list of header-value parameter and their corresponding value and set them. |
|
879
|
|
|
|
|
|
|
|
|
880
|
|
|
|
|
|
|
If no argument is provided, this returns the L<array object|Module::Generic::Array> containing all the header-value parameters. |
|
881
|
|
|
|
|
|
|
|
|
882
|
|
|
|
|
|
|
=head2 _set_get_properties_as_string |
|
883
|
|
|
|
|
|
|
|
|
884
|
|
|
|
|
|
|
This takes an hash or hash reference of options and returns the header-value parameters as a regular string. |
|
885
|
|
|
|
|
|
|
|
|
886
|
|
|
|
|
|
|
Supported options are: |
|
887
|
|
|
|
|
|
|
|
|
888
|
|
|
|
|
|
|
=over 4 |
|
889
|
|
|
|
|
|
|
|
|
890
|
|
|
|
|
|
|
=item * C<equal> |
|
891
|
|
|
|
|
|
|
|
|
892
|
|
|
|
|
|
|
=item * C<separator> or C<sep> |
|
893
|
|
|
|
|
|
|
|
|
894
|
|
|
|
|
|
|
=back |
|
895
|
|
|
|
|
|
|
|
|
896
|
|
|
|
|
|
|
=head2 _set_get_property_boolean |
|
897
|
|
|
|
|
|
|
|
|
898
|
|
|
|
|
|
|
This sets or gets a boolean value for the given header-value property. |
|
899
|
|
|
|
|
|
|
|
|
900
|
|
|
|
|
|
|
It returns the boolean value for the given property. |
|
901
|
|
|
|
|
|
|
|
|
902
|
|
|
|
|
|
|
Upon error, this sets an L<error|Module::Generic/error> and returns C<undef> |
|
903
|
|
|
|
|
|
|
|
|
904
|
|
|
|
|
|
|
=head2 _set_get_property_number |
|
905
|
|
|
|
|
|
|
|
|
906
|
|
|
|
|
|
|
This sets or gets a number for the given header-value property. |
|
907
|
|
|
|
|
|
|
|
|
908
|
|
|
|
|
|
|
It returns the number value for the given property. |
|
909
|
|
|
|
|
|
|
|
|
910
|
|
|
|
|
|
|
Upon error, this sets an L<error|Module::Generic/error> and returns C<undef> |
|
911
|
|
|
|
|
|
|
|
|
912
|
|
|
|
|
|
|
=head2 _set_get_property_value |
|
913
|
|
|
|
|
|
|
|
|
914
|
|
|
|
|
|
|
This sets or gets a value for the given header-value property. |
|
915
|
|
|
|
|
|
|
|
|
916
|
|
|
|
|
|
|
It returns the value for the given property. |
|
917
|
|
|
|
|
|
|
|
|
918
|
|
|
|
|
|
|
Upon error, this sets an L<error|Module::Generic/error> and returns C<undef> |
|
919
|
|
|
|
|
|
|
|
|
920
|
|
|
|
|
|
|
=head2 _set_get_qparam |
|
921
|
|
|
|
|
|
|
|
|
922
|
|
|
|
|
|
|
Sets or gets a quality-value parameter. If a value is provided, any double quote found at the bginning or end are removed. |
|
923
|
|
|
|
|
|
|
|
|
924
|
|
|
|
|
|
|
It returns the current value. |
|
925
|
|
|
|
|
|
|
|
|
926
|
|
|
|
|
|
|
Upon error, this sets an L<error|Module::Generic/error> and returns C<undef> |
|
927
|
|
|
|
|
|
|
|
|
928
|
|
|
|
|
|
|
=head2 _set_get_value |
|
929
|
|
|
|
|
|
|
|
|
930
|
|
|
|
|
|
|
This sets or gets a header main value. |
|
931
|
|
|
|
|
|
|
|
|
932
|
|
|
|
|
|
|
For example C<text/html> in C<text/html; charset=utf-8> |
|
933
|
|
|
|
|
|
|
|
|
934
|
|
|
|
|
|
|
=head1 AUTHOR |
|
935
|
|
|
|
|
|
|
|
|
936
|
|
|
|
|
|
|
Jacques Deguest E<lt>F<jack@deguest.jp>E<gt> |
|
937
|
|
|
|
|
|
|
|
|
938
|
|
|
|
|
|
|
=head1 SEE ALSO |
|
939
|
|
|
|
|
|
|
|
|
940
|
|
|
|
|
|
|
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> |
|
941
|
|
|
|
|
|
|
|
|
942
|
|
|
|
|
|
|
=head1 COPYRIGHT & LICENSE |
|
943
|
|
|
|
|
|
|
|
|
944
|
|
|
|
|
|
|
Copyright(c) 2022 DEGUEST Pte. Ltd. |
|
945
|
|
|
|
|
|
|
|
|
946
|
|
|
|
|
|
|
All rights reserved. |
|
947
|
|
|
|
|
|
|
|
|
948
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. |
|
949
|
|
|
|
|
|
|
|
|
950
|
|
|
|
|
|
|
=cut |