From dc2011109723b49437d741a56c8f5a8aab46260a Mon Sep 17 00:00:00 2001 From: crea Date: Sat, 27 May 2017 23:38:03 +0800 Subject: [PATCH 1/4] Defer response headers processing to finished callback --- CONTRIBUTORS.txt | 1 + pyramid_debugtoolbar/panels/headers.py | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 529a04c0..f42c739c 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -121,3 +121,4 @@ Contributors - Kashif Iftikhar, 2016-07-01 - Dan Clark, 2017-05-22 - Jens Carl, 2017-05-22 +- Andrey Tretyakov, 2017-05-27 \ No newline at end of file diff --git a/pyramid_debugtoolbar/panels/headers.py b/pyramid_debugtoolbar/panels/headers.py index 97f1010e..137b6566 100644 --- a/pyramid_debugtoolbar/panels/headers.py +++ b/pyramid_debugtoolbar/panels/headers.py @@ -15,16 +15,29 @@ class HeaderDebugPanel(DebugPanel): nav_title = title def __init__(self, request): + self.request = request self.request_headers = [ (text_(k), text_(v)) for k, v in sorted(request.headers.items()) ] def process_response(self, response): + def finished_callback(request): + self.process_response_deferred(response) + + def prepare_finished_callback(request): + """ Best effort to be the last in case there are other callbacks + mutating the response """ + self.request.add_finished_callback(finished_callback) + + self.request.add_finished_callback(prepare_finished_callback) + self.data = {'request_headers': self.request_headers, + 'response_headers': []} + + def process_response_deferred(self, response): response_headers = [ (text_(k), text_(v)) for k, v in sorted(response.headerlist) ] - self.data = {'request_headers': self.request_headers, - 'response_headers': response_headers} + self.data['response_headers'] = response_headers def includeme(config): config.add_debugtoolbar_panel(HeaderDebugPanel) From 5192241e1e85979d9683ffbc3cd527d294925844 Mon Sep 17 00:00:00 2001 From: crea Date: Sat, 27 May 2017 23:54:35 +0800 Subject: [PATCH 2/4] Included #309 bugfix in CHANGES.txt --- CHANGES.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 862c7bf4..ecf8f262 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,9 @@ unreleased ---------- +- Headers panel defers its processing to a finished callback. This is best + effort of displaying actual headers, since they could be modified by + a response callback or another finished callback. + See https://github.com/Pylons/pyramid_debugtoolbar/pull/310 - Debug squashed exceptions! If you register an exception view for an exception it will render a response. The toolbar will see the squashed exception and From 81f22556eb2f2a33a3839b3a5e336d2fbb00544b Mon Sep 17 00:00:00 2001 From: crea Date: Tue, 30 May 2017 12:43:44 +0800 Subject: [PATCH 3/4] Moved callbacks to __init__ and added a reference to the response --- pyramid_debugtoolbar/panels/headers.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/pyramid_debugtoolbar/panels/headers.py b/pyramid_debugtoolbar/panels/headers.py index 137b6566..8ca014d0 100644 --- a/pyramid_debugtoolbar/panels/headers.py +++ b/pyramid_debugtoolbar/panels/headers.py @@ -15,25 +15,26 @@ class HeaderDebugPanel(DebugPanel): nav_title = title def __init__(self, request): - self.request = request - self.request_headers = [ - (text_(k), text_(v)) for k, v in sorted(request.headers.items()) - ] - - def process_response(self, response): def finished_callback(request): - self.process_response_deferred(response) + self.process_response_deferred() def prepare_finished_callback(request): """ Best effort to be the last in case there are other callbacks mutating the response """ - self.request.add_finished_callback(finished_callback) + request.add_finished_callback(finished_callback) - self.request.add_finished_callback(prepare_finished_callback) + request.add_finished_callback(prepare_finished_callback) + self.request_headers = [ + (text_(k), text_(v)) for k, v in sorted(request.headers.items()) + ] + + def process_response(self, response): + self.response = response self.data = {'request_headers': self.request_headers, 'response_headers': []} - def process_response_deferred(self, response): + def process_response_deferred(self): + response = self.response response_headers = [ (text_(k), text_(v)) for k, v in sorted(response.headerlist) ] From 0d769b0ac2d73d5b5882fa03aa75cc2371ed3b12 Mon Sep 17 00:00:00 2001 From: crea Date: Tue, 30 May 2017 13:35:09 +0800 Subject: [PATCH 4/4] Use single finished callback --- pyramid_debugtoolbar/panels/headers.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/pyramid_debugtoolbar/panels/headers.py b/pyramid_debugtoolbar/panels/headers.py index 8ca014d0..0aa0b31a 100644 --- a/pyramid_debugtoolbar/panels/headers.py +++ b/pyramid_debugtoolbar/panels/headers.py @@ -17,13 +17,7 @@ class HeaderDebugPanel(DebugPanel): def __init__(self, request): def finished_callback(request): self.process_response_deferred() - - def prepare_finished_callback(request): - """ Best effort to be the last in case there are other callbacks - mutating the response """ - request.add_finished_callback(finished_callback) - - request.add_finished_callback(prepare_finished_callback) + request.add_finished_callback(finished_callback) self.request_headers = [ (text_(k), text_(v)) for k, v in sorted(request.headers.items()) ]