Opened 15 years ago
Closed 14 years ago
#6504 closed defect (fixed)
Get ExpatError using FastCGI
Reported by: | Owned by: | osimons | |
---|---|---|---|
Priority: | normal | Component: | XmlRpcPlugin |
Severity: | normal | Keywords: | |
Cc: | vyacheslav.slinko@…, Thijs Triemstra | Trac Release: | 0.11 |
Description
I install trac using FastCGI+Nginx and when I try run any XmlRpc method, I get this exception.
Traceback (most recent call last): File "/usr/lib/python2.6/dist-packages/trac/web/main.py", line 444, in _dispatch_request dispatcher.dispatch(req) File "/usr/lib/python2.6/dist-packages/trac/web/main.py", line 205, in dispatch resp = chosen_handler.process_request(req) File "/usr/local/lib/python2.6/dist-packages/TracXMLRPC-1.0.6-py2.6.egg/tracrpc/web_ui.py", line 172, in process_request self.process_xml_request(req, content_type) File "/usr/local/lib/python2.6/dist-packages/TracXMLRPC-1.0.6-py2.6.egg/tracrpc/web_ui.py", line 176, in process_xml_request args, method = xmlrpclib.loads(req.read(int(req.get_header('Content-Length')))) File "/usr/lib/python2.6/xmlrpclib.py", line 1183, in loads p.close() File "/usr/lib/python2.6/xmlrpclib.py", line 604, in close self._parser.Parse("", 1) # end of data ExpatError: no element found: line 1, column 0
Nginx configuration:
location / { auth_basic "Trac"; auth_basic_user_file /srv/trac/htpasswd; fastcgi_pass trac; fastcgi_param PATH_INFO $request_uri; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param SERVER_NAME $server_name; fastcgi_param SERVER_PORT $server_port; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param REMOTE_USER $remote_user; fastcgi_param QUERY_STRING $query_string; fastcgi_param SCRIPT_NAME ""; fastcgi_param AUTH_USER $remote_user; # Test fastcgi_param HTTP_CONTENT_LENGTH $content_length; }
Attachments (0)
Change History (11)
comment:1 Changed 15 years ago by
comment:2 Changed 15 years ago by
If visiting /xmlrpc
with regular browser gives you no such issues, it needs to be related to the custom _send_response()
that I use to shortcut the request handling and write direct responses. Could you perhaps try to make these two changes, please:
-
trunk/tracrpc/web_ui.py
a b 20 20 from trac.perm import PermissionError 21 21 from trac.util.datefmt import utc 22 22 from trac.util.text import to_unicode 23 from trac.web.main import IRequestHandler 23 from trac.web.main import IRequestHandler, RequestDone 24 24 from trac.web.chrome import ITemplateProvider, add_stylesheet 25 25 from trac.wiki.formatter import wiki_to_oneliner 26 26 … … 122 122 def _send_response(self, req, response, content_type='application/xml'): 123 123 response = to_unicode(response).encode("utf-8") 124 124 req.send_response(200) 125 if not 'charset=' in content_type: 126 content_type = content_type + '; charset=UTF-8' 125 127 req.send_header('Content-Type', content_type) 126 128 req.send_header('Content-Length', len(response)) 127 129 req.end_headers() 128 130 req.write(response) 131 raise RequestDone 129 132 130 133 def process_request(self, req): 131 134
That should take care of any ambiguity regarding request content and finalization.
comment:3 Changed 15 years ago by
After patch:
Python Traceback
Traceback (most recent call last): File "/usr/lib/python2.6/dist-packages/trac/web/main.py", line 444, in _dispatch_request dispatcher.dispatch(req) File "/usr/lib/python2.6/dist-packages/trac/web/main.py", line 205, in dispatch resp = chosen_handler.process_request(req) File "/usr/local/lib/python2.6/dist-packages/TracXMLRPC-1.0.6-py2.6.egg/tracrpc/web_ui.py", line 175, in process_request self.process_xml_request(req, content_type) File "/usr/local/lib/python2.6/dist-packages/TracXMLRPC-1.0.6-py2.6.egg/tracrpc/web_ui.py", line 179, in process_xml_request args, method = xmlrpclib.loads(req.read(int(req.get_header('Content-Length')))) File "/usr/lib/python2.6/xmlrpclib.py", line 1183, in loads p.close() File "/usr/lib/python2.6/xmlrpclib.py", line 604, in close self._parser.Parse("", 1) # end of data ExpatError: no element found: line 1, column 0
comment:4 Changed 15 years ago by
Oh, sorry - did not read your traceback properly. Presumed it was related to output, but it looks like this is an input issue where the Content-Length header is missing from client or removed by your config. It is unusual, but not impossible and the code does not deal with the possibility. Could you try making this change:
-
trunk/tracrpc/web_ui.py
a b 176 176 177 177 def process_xml_request(self, req, content_type): 178 178 """ Handles XML-RPC requests """ 179 args, method = xmlrpclib.loads(req.read( int(req.get_header('Content-Length'))))179 args, method = xmlrpclib.loads(req.read()) 180 180 self.log.debug("RPC(xml) call by '%s', method '%s' with args: %s" \ 181 181 % (req.authname, method, repr(args))) 182 182 args = self._normalize_xml_input(args)
comment:5 Changed 15 years ago by
I'm played with nginx configuration (like fastcgi_param CONTENT_LENGTH $content_length;) and no effect. After your changes:
Python Traceback
Traceback (most recent call last): File "/usr/lib/python2.6/dist-packages/trac/web/main.py", line 444, in _dispatch_request dispatcher.dispatch(req) File "/usr/lib/python2.6/dist-packages/trac/web/main.py", line 205, in dispatch resp = chosen_handler.process_request(req) File "/usr/local/lib/python2.6/dist-packages/TracXMLRPC-1.0.6-py2.6.egg/tracrpc/web_ui.py", line 172, in process_request self.process_xml_request(req, content_type) File "/usr/local/lib/python2.6/dist-packages/TracXMLRPC-1.0.6-py2.6.egg/tracrpc/web_ui.py", line 177, in process_xml_request args, method = xmlrpclib.loads(req.read()) File "/usr/lib/python2.6/xmlrpclib.py", line 1183, in loads p.close() File "/usr/lib/python2.6/xmlrpclib.py", line 604, in close self._parser.Parse("", 1) # end of data ExpatError: no element found: line 1, column 0
comment:6 Changed 15 years ago by
Nope, not input or output and likely your config is fine. I've read the traceback even more closely and also poked into the xmlrpclib
, and it seems to be a parsing error due to your client passing in empty information for some arguments (in xml body) and the parser raising the exception when nothing is there.
The code currently does not handle parsing errors which of course is a big omission - although it hasn't really been raised before as the XML-RPC spec is quite strict and the clients usually conform to it. What client are you using?
Could you add this to your modified file (keeping the other changes as well):
-
trunk/tracrpc/web_ui.py
a b 176 176 177 177 def process_xml_request(self, req, content_type): 178 178 """ Handles XML-RPC requests """ 179 args, method = xmlrpclib.loads(req.read()) 179 try: 180 args, method = xmlrpclib.loads(req.read()) 181 except Exception, e: 182 self.log.debug("RPC(xml) error parsing XML input: %s" % repr(e)) 183 self._send_response(req, xmlrpclib.dumps(xmlrpclib.Fault(1, to_unicode(e))), 184 content_type) 180 185 self.log.debug("RPC(xml) call by '%s', method '%s' with args: %s" \ 181 186 % (req.authname, method, repr(args))) 182 187 args = self._normalize_xml_input(args)
comment:9 Changed 15 years ago by
Cc: | Thijs Triemstra added |
---|
comment:10 Changed 14 years ago by
From what I can see, I think this has been integrated into the major change at [7916] when we introduced pluggable protocols. It certainly was my intention, and the new code should have improved error handling in general.
Could anyone please update to latest (1.1.10+ from trunk) and confirm that this is now working? If not, please provide me with a fresh traceback and error message.
comment:11 Changed 14 years ago by
Resolution: | → fixed |
---|---|
Status: | new → closed |
Closing. It should be fixed, and no recent feedback to say otherwise. Reopen if issue persists.
System Information
0.11.5
2.6.4 (r264:75706, Dec 7 2009, 18:43:55)
[GCC 4.4.1]
0.6c9
3.6.16
2.4.1
0.5.1
1.0
1.3.1
1.0.6