Opened 5 years ago
Closed 5 years ago
#13701 closed defect (fixed)
TypeError: http header key must be a string
Reported by: | Massimo | Owned by: | matobaa |
---|---|---|---|
Priority: | normal | Component: | FieldTooltipPlugin |
Severity: | blocker | Keywords: | |
Cc: | Trac Release: | 1.4 |
Description
The current version in PyPI (0.8.3) leads to
2019-11-29 10:14:46,122 Trac[main] ERROR: [10.190.226.173] Internal Server Error: <RequestWithSession "POST '/tracfieldtooltip/tooltip.jsonrpc'">, referrer 'https://project-pb/trac-pp/ticket/155' Traceback (most recent call last): File "/mnt/data/trac/.local/lib64/python2.7/site-packages/trac/web/main.py", line 639, in dispatch_request dispatcher.dispatch(req) File "/mnt/data/trac/.local/lib64/python2.7/site-packages/trac/web/main.py", line 250, in dispatch resp = chosen_handler.process_request(req) File "build/bdist.linux-x86_64/egg/tracfieldtooltip/tooltip.py", line 176, in process_request req.end_headers() File "/mnt/data/trac/.local/lib64/python2.7/site-packages/trac/web/api.py", line 732, in end_headers exc_info) TypeError: http header key must be a string
I double checked with the build from last SVN version TracFieldTooltip-0.8.3-py2.7.egg, same issue. Last working version is FieldTooltip-0.7.3-py2.7.egg
Attachments (0)
Change History (8)
comment:1 Changed 5 years ago by
comment:2 Changed 5 years ago by
The error message is used in uwsgi at https://github.com/unbit/uwsgi/blob/master/plugins/python/wsgi_headers.c#L118.
comment:3 Changed 5 years ago by
BTW, according to https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag, ETag
header should be ETag: W/"<etag_value>"
or ETag: "<etag_value>"
.
I think the value should be enclosed with double quote characters.
source:fieldtooltipplugin/0.12/tracfieldtooltip/tooltip.py@17587:175#L175
- req.send_header('ETag', "%s" % id(self.pages)) + req.send_header('ETag', '"%s"' % id(self.pages))
comment:5 follow-up: 6 Changed 5 years ago by
When If-None-Match
header is missing, AttributeError
occurs.
Traceback (most recent call last): File "/dev/shm/venv/lib/python2.7/site-packages/trac/web/main.py", line 647, in _dispatch_request dispatcher.dispatch(req) File "/dev/shm/venv/lib/python2.7/site-packages/trac/web/main.py", line 248, in dispatch resp = chosen_handler.process_request(req) File "/dev/shm/venv/lib/python2.7/site-packages/tracfieldtooltip/tooltip.py", line 164, in process_request if req.get_header('If-None-Match').strip('"') == str(id(self.pages)): AttributeError: 'NoneType' object has no attribute 'strip'
Another issue, the ETag
value is not stable if web server is multiprocess (e.g. mod_wsgi, uwsgi, ...).
I don't think id()
should be used for ETag
value because id()
returns the address of the object in memory. See also https://docs.python.org/2/library/functions.html#id. hashlib.sha1()
should be used rather than id()
.
Also, trivial thing, we could use b'header'
rather than str('header')
.
$ for i in $(seq 1 10); do > curl -v -o /dev/null -X POST \ > -H 'Content-Type: application/json' -H 'If-None-Match: X' \ > -d '{"method":"wiki.getPage"}' \ > http://127.0.0.1:3000/tracenv/tracfieldtooltip/tooltip.jsonrpc 2>&1 \ > | grep '^< ETag:' > done < ETag: "140066037392280" < ETag: "140066037441152" < ETag: "140066037392280" < ETag: "140066037441152" < ETag: "140066037392280" < ETag: "140066037441152" < ETag: "140066037392280" < ETag: "140066037441152" < ETag: "140066037392280" < ETag: "140066037441152"
Proposed patch:
-
fieldtooltipplugin/0.12/tracfieldtooltip/tooltip.py
diff --git a/fieldtooltipplugin/0.12/tracfieldtooltip/tooltip.py b/fieldtooltipplugin/0.12/tracfieldtooltip/tooltip.py index 5bfee0968..72361d120 100644
a b from pkg_resources import ResourceManager 12 12 from trac.cache import cached 13 13 from trac.core import Component, implements 14 14 from trac.util import arity 15 from trac.util.text import to_utf8 15 16 from trac.web.api import IRequestHandler, IRequestFilter 16 17 from trac.web.chrome import ITemplateProvider, add_script, add_stylesheet, web_context 17 18 from trac.wiki.api import IWikiChangeListener, WikiSystem 18 19 from trac.wiki.formatter import format_to_html 19 20 from trac.wiki.model import WikiPage 21 import binascii 22 import hashlib 20 23 import json 21 24 22 25 … … class Tooltip(Component): 156 159 def process_request(self, req): 157 160 def to_html(dom): 158 161 return format_to_html(self.env, web_context(req), dom, False) 162 def build_etag(pages): 163 h = hashlib.sha1() 164 for name in sorted(pages): 165 h.update(to_utf8(name)) 166 h.update(b'\0') 167 h.update(to_utf8(pages[name])) 168 h.update(b'\0') 169 return '"%s"' % binascii.hexlify(h.digest()) 159 170 payload = json.load(req) 160 171 if 'method' not in payload or not payload['method'] == 'wiki.getPage': 161 172 req.send_response(501) # Method Not Implemented 162 173 req.end_headers() 163 174 return 164 if req.get_header('If-None-Match').strip('"') == str(id(self.pages)): 175 etag = build_etag(self.pages) 176 if req.get_header('If-None-Match') == etag: 165 177 req.send_response(304) # Not Modified 166 178 req.end_headers() 167 179 return … … class Tooltip(Component): 170 182 'defaults': {page: to_html(self._default_pages[page]) for page in self._default_pages}, 171 183 }, indent=4) 172 184 req.send_response(200) 173 req.send_header( str('Content-Type'), 'application/json')174 req.send_header( str('Content-Length'), len(content))175 req.send_header( str('ETag'), '"%s"' % id(self.pages))185 req.send_header(b'Content-Type', 'application/json') 186 req.send_header(b'Content-Length', len(content)) 187 req.send_header(b'ETag', etag) 176 188 req.end_headers() 177 189 req.write(content) 178 190
comment:6 Changed 5 years ago by
Replying to Jun Omae:
When
If-None-Match
header is missing,AttributeError
occurs. ...
If this is still blocking this ticket, please reopen or open a new one.
comment:7 Changed 5 years ago by
Resolution: | fixed |
---|---|
Status: | closed → reopened |
comment:8 Changed 5 years ago by
Resolution: | → fixed |
---|---|
Status: | reopened → closed |
In [17606]:
FieldTooltipPlugin: Closes #13701
Worksforme. (python 2.7.16 64bit on windows 10)
Could you show your "System Information" at "about trac" and
/etc/*-release
?