use v6;
module HTTP::Headers::Util-0.2;
sub split_header_words (*@values) is export {
my @return;
for @values -> $value is copy {
my @current;
while ($value.chars) {
if ($value ~~ s:P5/^\s*(=*[^\s=;,]+)//) {
push @current, ~$0; # 'token' or parameter 'attribute'
# a quoted value
if ($value ~~ s:P5/^\s*=\s*\"([^\"\\]*(?:\\.[^\"\\]*)*)\"//) {
my $val = ~$0;
$val ~~ s:P5:g/\\(.)/$0/;
push @current, $val;
# some unquoted value
} elsif ($value ~~ s:P5/^\s*=\s*([^;,\s]*)//) {
my $val = ~$0;
$val ~~ s:P5/\s+$//;
push @current, $val;
# no value, a lone token
} else {
push @current, undef;
}
} elsif ($value ~~ s:P5/^\s*,//) {
push @return, [@current] if @current;
@current = ();
} elsif ($value ~~ s:P5/^\s*;// || $value ~~ s:P5/^\s+//) {
# continue
} else {
die "This should not happen: '$value'";
}
}
push @return, [@current] if @current;
}
return @return;
}
multi sub join_header_words(*@words) is export {
join ', ', gather {
for @words -> $cur {
take join '; ', gather {
for $cur -> $k, $v {
if $v.defined {
# XXX add / to character class in regex below
# currently results in parsefail
if $v ~~ m:P5/[\x00-\x20()<>@,;:\\\"\[\]?={}\x7F-\xFF]/ || !$v.chars {
my $esc = $v;
$esc ~~ s:P5:g/([\"\\])/\\$0/; # escape " and \
take qq($k="$esc");
}
else {
# token
take "$k=$v";
}
}
else {
take $k;
}
}
}
}
}
}
1;