Edgewall Software
Modify

Opened 4 weeks ago

Last modified 3 weeks ago

#13789 assigned defect

POST request to tracd with multipart 1.0.0 is stuck

Reported by: Jun Omae Owned by: Jun Omae
Priority: normal Milestone: 1.6.1
Component: web frontend/tracd Version: 1.6
Severity: normal Keywords:
Cc: Branch:
Release Notes:
API Changes:
Internal Changes:

Description

The form-data parser in multipart module attempts to read data from a Request instance more than Content-Length bytes. It is intent that an empty bytes is received if EOF reached, however, it is stuck when tracd is used.

Attachments (0)

Change History (2)

comment:1 by Jun Omae, 4 weeks ago

Workaround:

  • trac/web/wsgi.py

    diff --git a/trac/web/wsgi.py b/trac/web/wsgi.py
    index ade785756..848da63c7 100644
    a b class WSGIRequestHandler(BaseHTTPRequestHandler):  
    243243            self.rfile = None
    244244
    245245
     246class WSGIInput(object):
     247
     248    __slots__ = ('rfile', 'remaining')
     249
     250    def __init__(self, rfile, environ):
     251        length = environ.get('CONTENT_LENGTH')
     252        if length and length.isdigit():
     253            try:
     254                length = int(length)
     255            except:
     256                length = None
     257        else:
     258            length = None
     259        self.rfile = rfile
     260        self.remaining = length
     261
     262    def __repr__(self):
     263        return '<{} rfile={!r} remaining={!r}>'.format(self.__class__.__name__,
     264                                                       self.rfile,
     265                                                       self.remaining)
     266
     267    def __iter__(self):
     268        return self
     269
     270    def __next__(self):
     271        return self.readline()
     272
     273    def read(self, size=-1):
     274        if self.remaining is None:
     275            data = self.rfile.read(size)
     276        else:
     277            if size < 0:
     278                size = self.remaining
     279            elif size > self.remaining:
     280                size = self.remaining
     281            data = self.rfile.read(size)
     282            self.remaining -= len(data)
     283        return data
     284
     285    def readline(self, size=-1):
     286        if size < 0:
     287            size = self.remaining
     288        elif size > self.remaining:
     289            size = self.remaining
     290        line = self.rfile.readline(size)
     291        self.remaining -= len(line)
     292        return line
     293
     294    def readlines(self, hint=-1):
     295        raise NotImplementedError
     296
     297
    246298class WSGIServerGateway(WSGIGateway):
    247299
    248300    def __init__(self, handler, environ):
    249         WSGIGateway.__init__(self, environ, handler.rfile,
     301        wsgi_input = WSGIInput(handler, environ)
     302        WSGIGateway.__init__(self, environ, wsgi_input,
    250303                             _ErrorsWrapper(lambda x: handler.log_error('%s', x)))
    251304        self.handler = handler
    252305
Last edited 4 weeks ago by Jun Omae (previous) (diff)

in reply to:  1 comment:2 by Jun Omae, 3 weeks ago

Replying to Jun Omae:

Workaround:

WSGI specification, PEP 3333 – Python Web Server Gateway Interface v1.0.1 | peps.python.org, says:

The server is not required to read past the client’s specified Content-Length, and should simulate an end-of-file condition if the application attempts to read past that point. The application should not attempt to read more data than is specified by the CONTENT_LENGTH variable.

So that, we should provide WSGIInput class in the workaround to simulate EOF condition.

Modify Ticket

Change Properties
Set your email in Preferences
Action
as assigned The owner will remain Jun Omae.
The ticket will be disowned. Next status will be 'new'.
as The resolution will be set. Next status will be 'closed'.
to The owner will be changed from Jun Omae to the specified user.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.