http://qs321.pair.com?node_id=831169


in reply to Re: Catalyst::Request::Upload inside-out-object weirdness
in thread Catalyst::Request::Upload inside-out-object weirdness

yes - that's what i suspect is happening somewhere inside catalyst - and i do get that warning - here's more (earlier) console output from the server

You can connect to your server at http://fishbone.local:3000 Use of uninitialized value in list assignment at /Library/Perl/5.8.6/C +atalyst/Engine/HTTP.pm line 371. Use of uninitialized value in list assignment at /Library/Perl/5.8.6/C +atalyst/Engine/HTTP.pm line 371. Odd number of elements in anonymous hash at generated method (unknown +origin) line 8. Use of uninitialized value in concatenation (.) or string at /Users/an +dye/PhotoApp/script/../lib/PhotoApp/Controller/Root.pm line 93. Use of uninitialized value in link at /Library/Perl/5.8.6/Catalyst/Req +uest/Upload.pm line 120. Use of uninitialized value in string eq at /System/Library/Perl/5.8.6/ +File/Copy.pm line 76. Use of uninitialized value in stat at /System/Library/Perl/5.8.6/File/ +Copy.pm line 82. Use of uninitialized value in -d at /System/Library/Perl/5.8.6/File/Co +py.pm line 91. Use of uninitialized value in -e at /Library/Perl/5.8.6/Catalyst/Engin +e.pm line 317.

after looking at the docs some more, I'm now doing this:

for my $field ( $c->req->upload ) { $c->log->warn("field is $field"); my $upload = $c->req->upload($field); my $filename = $upload->filename; my $target = $absGalleryPath . $filename; unless ( $upload->link_to($target) || $upload->copy_to($target +) ) { die( "Failed to copy '$filename' to '$target': $!" ); } }

as per the cookbook, but still no joy.

Replies are listed 'Best First'.
Re^3: Catalyst::Request::Upload inside-out-object weirdness
by ikegami (Patriarch) on Mar 26, 2010 at 15:09 UTC
    Why are you posting that snippet? You don't assign to any hashes in it
      Right. I don't assign the hash. It happens inside Catalyst.

      Looking at the source, it looks like it happens in Catalyst::Engine::prepare_uploads, which reads

      sub prepare_uploads { my ( $self, $c ) = @_; my $request = $c->request; return unless $request->_body; my $uploads = $request->_body->upload; my $parameters = $request->parameters; foreach my $name (keys %$uploads) { my $files = $uploads->{$name}; my @uploads; for my $upload (ref $files eq 'ARRAY' ? @$files : ($files)) { my $headers = HTTP::Headers->new( %{ $upload->{headers} } +); my $u = Catalyst::Request::Upload->new ( size => $upload->{size}, type => $headers->content_type, headers => $headers, tempname => $upload->{tempname}, filename => $upload->{filename}, ); push @uploads, $u; } $request->uploads->{$name} = @uploads > 1 ? \@uploads : $uploa +ds[0]; # support access to the filename as a normal param my @filenames = map { $_->{filename} } @uploads; # append, if there's already params with this name if (exists $parameters->{$name}) { if (ref $parameters->{$name} eq 'ARRAY') { push @{ $parameters->{$name} }, @filenames; } else { $parameters->{$name} = [ $parameters->{$name}, @filena +mes ]; } } else { $parameters->{$name} = @filenames > 1 ? \@filenames : $fil +enames[0]; } } }
        Looks like
        $headers->content_type
        can return more than one value. Replace it with
        scalar($headers->content_type)
      That's right, I don't.

      Looking at the source, it looks like that happens in Catalyst::Engine::prepare_uploads

      sub prepare_uploads { my ( $self, $c ) = @_; my $request = $c->request; return unless $request->_body; my $uploads = $request->_body->upload; my $parameters = $request->parameters; foreach my $name (keys %$uploads) { my $files = $uploads->{$name}; my @uploads; for my $upload (ref $files eq 'ARRAY' ? @$files : ($files)) { my $headers = HTTP::Headers->new( %{ $upload->{headers} } +); my $u = Catalyst::Request::Upload->new ( size => $upload->{size}, type => $headers->content_type, headers => $headers, tempname => $upload->{tempname}, filename => $upload->{filename}, ); push @uploads, $u; } $request->uploads->{$name} = @uploads > 1 ? \@uploads : $uploa +ds[0]; # support access to the filename as a normal param my @filenames = map { $_->{filename} } @uploads; # append, if there's already params with this name if (exists $parameters->{$name}) { if (ref $parameters->{$name} eq 'ARRAY') { push @{ $parameters->{$name} }, @filenames; } else { $parameters->{$name} = [ $parameters->{$name}, @filena +mes ]; } } else { $parameters->{$name} = @filenames > 1 ? \@filenames : $fil +enames[0]; } } }

        [The indexing is messed up for this thread. My earlier reply isn't showing, so I'm reposting it]

        Looks like

        $headers->content_type
        can return more than one value. Replace it with
        scalar($headers->content_type)