extension of a resource can get stripped

Bug #1465397 reported by Alfredo Deza
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
pecan
Invalid
Medium
Ryan Petrello

Bug Description

In a web application that deals with files on endpoints, when a client requests the following URL:

    /resource/binary_file.deb

Pecan understands that the canonical trailing slash has not been used and does a redirect to:

     /resource/binary_file.deb/

But in the process, the controller that handles 'binary_file.deb' does some checking to handle the possibility of not
having that binary, but when that request comes the first time, it only sees 'binary_file'. The extension gets stripped.

The second time around, the request does include the full name.

This happens because Pecan does an "attempt to guess the content type based on the file extension", and when it does, it strips the extension and uses the name without the extension to pass it to the routing mechanism.

When this is handled by _lookup() methods, it will passed the stripped name to the controller.

This means that the controller cannot do any housekeeping in __init__, and it needs to wait for the redirect that points to /resource/binary_file.deb/ so that the controller gets the full name.

The content-type gets correctly guessed:

    ipdb> guess_type('x' + extension)
    ('application/x-debian-package', None)

Is this something that can be overridden? I've never experienced this behavior before so I went ahead and described the issue as best as I could.

Below is a way to replicate the issue:

    from pecan import expose, abort

    class ResourceController(object):

        def __init__(self, name):
            self.name = name
            # if URL is requested like '/file_name.deb' it will trigger
            # the below 404
            if not name.endswith('.deb'):
                abort(404, detail='expected a DEB file, got: %s' % name)

        @expose('json')
        def index(self):
            # if the url is requested with '/file_name.deb/' this will work
            return dict(name=self.name)

    class RootController(object):

        @expose('json')
        def index(self):
            return dict()

        @expose()
        def _lookup(self, name, *remainder):
            print 'lookup name: ', name
            return ResourceController(name), remainder

Changed in pecan:
status: New → Won't Fix
status: Won't Fix → Invalid
assignee: nobody → Ryan Petrello (ryan-petrello)
importance: Undecided → Medium
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.