On Tue, Jul 4, 2017 at 8:36 PM, Olaf Alders <o...@wundersolutions.com> wrote:
> > > On Jul 4, 2017, at 4:41 PM, Bill Moseley <mose...@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 mose...@hank.org