develooper Front page | perl.libwww | Postings from July 2017

Re: form-date with newline in filename

Thread Previous
From:
Bill Moseley
Date:
July 5, 2017 16:54
Subject:
Re: form-date with newline in filename
Message ID:
CAKhN_m7Mb24YVJXE3nC=1Gxwrwknja03v-2FqPJXw66UQ=btfw@mail.gmail.com
Oh, how did I start talking about HTTP headers?  Holiday daze. It's about
form-data.  I'll see what browsers do.

On Wed, Jul 5, 2017 at 09:20 Bill Moseley <moseley@hank.org> wrote:

> On Tue, Jul 4, 2017 at 8:36 PM, Olaf Alders <olaf@wundersolutions.com>
> wrote:
>
>>
>> > On Jul 4, 2017, at 4:41 PM, Bill Moseley <moseley@hank.org> wrote:
>> >
>> > I'm trying to understand if the Perl code is doing the right thing by
>> placing a newline directly in the double-quoted filename in the
>> Content-Disposition header.
>> >
>> > Even though it's probably a bad thing to do, POSIX allows newlines in
>> filenames. Receiving systems, of course, must be careful how that filename
>> is used -- but in this case it's never actually used in a filesystem (i.e.
>> it's just considered metadata).
>> >
>> > The code below does a full round-trip successfully (meaning the newline
>> in the filename is preserved), but that's all within Perl.
>> >
>> > I'm POSTing to a service written in Golang and that library is
>> complaining about malformed headers.
>> >
>> > My question: Is HTTP::Request not escaping correctly or is Golang
>> library not parsing correctly?
>> >
>> > use strict;
>> > use warnings;
>> > use HTTP::Request::Common;
>> > use HTTP::Response;
>> > use HTTP::Body;
>> > use Data::Dumper;
>> >
>> > my $filename = "name with\na newline";
>> >
>> > my $req = POST(
>> >     'http://example.com/post',
>> >     content_type => 'form-data',
>> >     Content => [
>> >         file => [
>> >             $0,
>> >             $filename,
>> >         ],
>> >         one => 1,
>> >         two => 2,
>> >     ],
>> > );
>> >
>> > my $res = HTTP::Response->parse( $req->as_string );
>> > my $body = HTTP::Body->new( join( ' ' ,$res->content_type),
>> $res->content_length );
>> > $body->add( $res->decoded_content );
>> > print Dumper $body->upload;
>> >
>> > Above returns:
>> >
>> > $VAR1 = {
>> >           'file' => {
>> >                       'filename' => 'name with
>> > a newline',
>> >                       'tempname' =>
>> '/var/folders/sz/w4rntlpx76vcy5xrp441m0qw0000gn/T/6QNv98gd5B',
>> >                       'size' => 561,
>> >                       'headers' => {
>> >                                      'Content-Disposition' =>
>> 'form-data; name="file"; filename="name with
>> > a newline"',
>> >                                      'Content-Type' => 'text/plain'
>> >                                    },
>> >                       'name' => 'file'
>> >                     }
>> >         };
>> >
>> > It seems like header folding is no longer allowed, but I'm not clear
>> that this is a case of header-folding:
>> >
>> >
>> https://stackoverflow.com/questions/521275/how-to-escape-a-line-break-literal-in-the-http-header
>> >
>> > Or asked another way, is Perl or Golang breaking Postel's law?
>>
>> Hi Bill,
>>
>> Is it possible for you to print the actual outgoing headers?  With the
>> newlines being involved, the order of the headers could make a difference
>> here.
>>
>> Best,
>>
>> Olaf
>>
>>
> Sure, but I think this is more of a question about how the header is
> created. I thought maybe an issue with header-folding, but maybe not.
>
> https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html say a header value
> ("field-content") can include a "quoted-string", which is what
> HTTP::Request (or HTTP::Headers) is doing.
>
> But https://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html says a
> quoted-string is:
>
> A string of text is parsed as a single word if it is quoted using
> double-quote marks.
>
>        quoted-string  = ( <"> *(qdtext | quoted-pair ) <"> )
>
>        qdtext         = <any TEXT except <">>
>
>
> And "TEXT" is:
>
>        TEXT           = <any OCTET except CTLs,
>                         but including LWS>
>
> And "CTL" is:
>
>        CTL            = <any US-ASCII control character
>                         (octets 0 - 31) and DEL (127)>
>
> So, that looks like newlines cannot be used.
>
> Is that the correct reading?
>
> I'm also not sure there is a standard way to escape the newlines -- i.e.
> might have to be an agreement between the sender and receiver.
>
> If the sender permits newlines in filenames it should be able to represent
> those in the header in a standard way -- even if not a good idea to use
> newlines in filenames.
>
> What is expected with HTTP::Request::Common?  Should the HTTP::* methods
> handle escaping or it expected that all escaping must be done be the caller?
>
>
>
>
>
>
> --
> Bill Moseley
> moseley@hank.org
>
-- 
Bill Moseley
moseley@hank.org

Thread Previous


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About