Re: [PATCH] FIFO header order support in HTTP::Headers
Michael Greb <[email protected]>
| Newsgroups | gmane.comp.lang.perl.modules.lwp |
|---|---|
| Message-ID | <[email protected]> |
On Sep 5, 2008, at 7:23 PM, Gisle Aas wrote:
> True; and in this case we need to define what happens when fields are
> modified with 'push', 'set' or 'init' and 'remove' as that's the API
> that modify stuff. Let me suggest the following definition of the
> behaviour:
>
> - 'push' always append the field at the end of all headers. multiple
> occurrences of a field name do not have to be consecutive.
>
> - 'init' either does nothing or it works like 'push'.
>
> - 'remove' will always remove all concurrences of a field.
>
> - 'set' will work like 'push' if no other occurrence of the field
> exists.
>
> - 'set' will update the first occurrence if the field exists (and
> remove all other occurrences). if multiple field values is provided
> with 'set' they are basically all injected at the location of the
> first existing value.
On Sep 6, 2008 at 2:57 AM, Gisle Aas wrong:
> I think it makes sense to be able to enable them separately.
> Suggested interface:
>
> $h->scan(\&cb, original_order => 1, original_case => 1);
> $h->as_string(eol => "\n", original_order => 1, original_case => 1);'
The attached patch uses the interface above and works towards the
behavior outlined in the first message. Due to the headers being
stored as a hash, pushing does not currently preserve previous values,
second and subsequent pushes of the same header will overwrite the
previous value. Supporting this would require a change in how the
headers are stored within the module. Your thoughts? The most
obvious solution to me would be storing headers and their values as a
hashref in an arrayref
Server: Fool/1.0
content-encoding: gzip
Content-Type: text/plain; charset="UTF-8"
Content-Encoding: base64
Date: Fri Sep 5 10:24:37 CEST 2008
Would be stored as (assuming push_header):
$self->{_headers} = [
{ server => 'Fool/1.0' },
{ content-encoding => 'gzip'},
{ content-type => 'text/plain; charset="UTF-8"},
{ content-encoding => 'base64' },
{ date => 'Fri Sep 5 10:24:37 CEST 2008' }
];
This would negate the need for $self->{_original_order}. $self-
>{_header} (or some such) could be a hashref with header fields as
the keys and the header's index(s) in _headers as their value to speed
and simplify direct access to an individual header's value.
--
Michael Greb
Linode.com
609-593-7103 ext 1205
0001-preservation-of-original-header-order-and-case.patch
(application/octet-stream, 2.2 KB)
From 2fd608a131e40375719bd79f6b427890a5db7529 Mon Sep 17 00:00:00 2001 From: Michael Greb <[email protected]> Date: Sun, 7 Sep 2008 07:33:59 -0400 Subject: [PATCH] preservation of original header order and case --- lib/HTTP/Headers.pm | 17 ++++++++++------- 1 files changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/HTTP/Headers.pm b/lib/HTTP/Headers.pm index 5eb5329..c7d37dd 100644 --- a/lib/HTTP/Headers.pm +++ b/lib/HTTP/Headers.pm @@ -82,7 +82,7 @@ sub header my %seen; while (@_) { my $field = shift; - my $op = @_ ? ($seen{lc($field)}++ ? 'PUSH' : 'SET') : 'GET'; + my $op = @_ ? 'SET': 'GET'; @old = $self->_header($field, shift, $op); } return @old if wantarray; @@ -117,9 +117,12 @@ sub remove_header my $field; my @values; foreach $field (@fields) { - $field =~ tr/_/-/ if $field !~ /^:/ && $TRANSLATE_UNDERSCORE; - my $v = delete $self->{lc $field}; - push(@values, ref($v) eq 'ARRAY' ? @$v : $v) if defined $v; + $field =~ tr/_/-/ if $field !~ /^:/ && $TRANSLATE_UNDERSCORE; + $field = lc $field if $field !~ /^:/; + my $v = delete $self->{$field}; + delete $self->{_original_case}{$field}; + @{$self->{_original_order}} = grep !/^\Q$field\E$/, @{$self->{_original_order}}; + push(@values, ref($v) eq 'ARRAY' ? @$v : $v) if defined $v; } return @values; } @@ -167,7 +170,7 @@ sub _header $op ||= defined($val) ? 'SET' : 'GET'; unless ($op eq 'GET' || ($op eq 'INIT' && @old)) { if (defined($val)) { - my @new = ($op eq 'PUSH') ? @old : (); + my @new = ($op eq 'SET') ? @old : (); if (ref($val) ne 'ARRAY') { push(@new, $val); } @@ -176,12 +179,12 @@ sub _header } $self->{$field} = @new > 1 ? \@new : $new[0]; push @{$self->{_original_order}}, $field - if ($op eq 'PUSH' || !@old); + unless ($op eq 'SET' && @old); } elsif ($op ne 'PUSH') { delete $self->{$field}; @{$self->{_original_order}} = - grep !/\Q$field\E/, @{$self->{_original_order}}; + grep !/^\Q$field\E$/, @{$self->{_original_order}}; } } @old; -- 1.5.5.3
PGP.sig
(application/pgp-signature, 186 B) - not displayed