annotate kallithea/config/middleware/wrapper.py @ 8791:b3d8a3000a7f

lib: cleanup of _get_ip_addr
author Mads Kiilerich <mads@kiilerich.com>
date Tue, 10 Nov 2020 17:43:37 +0100
parents f8971422795e
children 4f0de9468da3
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3489
d997a314d18a moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
1 # -*- coding: utf-8 -*-
d997a314d18a moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
2 # This program is free software: you can redistribute it and/or modify
d997a314d18a moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
3 # it under the terms of the GNU General Public License as published by
d997a314d18a moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
4 # the Free Software Foundation, either version 3 of the License, or
d997a314d18a moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
5 # (at your option) any later version.
d997a314d18a moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
6 #
d997a314d18a moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
7 # This program is distributed in the hope that it will be useful,
d997a314d18a moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
d997a314d18a moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
d997a314d18a moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
10 # GNU General Public License for more details.
d997a314d18a moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
11 #
d997a314d18a moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
12 # You should have received a copy of the GNU General Public License
d997a314d18a moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
4116
ffd45b185016 Imported some of the GPLv3'd changes from RhodeCode v2.2.5.
Bradley M. Kuhn <bkuhn@sfconservancy.org>
parents: 3500
diff changeset
14 """
8771
f8971422795e scripts: introduce source_format.py to fix up the module name in file headers
Mads Kiilerich <mads@kiilerich.com>
parents: 8684
diff changeset
15 kallithea.config.middleware.wrapper
f8971422795e scripts: introduce source_format.py to fix up the module name in file headers
Mads Kiilerich <mads@kiilerich.com>
parents: 8684
diff changeset
16 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4116
ffd45b185016 Imported some of the GPLv3'd changes from RhodeCode v2.2.5.
Bradley M. Kuhn <bkuhn@sfconservancy.org>
parents: 3500
diff changeset
17
7907
b42ee1bdf082 wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7906
diff changeset
18 Wrap app to measure request and response time ... all the way to the response
b42ee1bdf082 wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7906
diff changeset
19 WSGI iterator has been closed.
4116
ffd45b185016 Imported some of the GPLv3'd changes from RhodeCode v2.2.5.
Bradley M. Kuhn <bkuhn@sfconservancy.org>
parents: 3500
diff changeset
20
4211
1948ede028ef RhodeCode GmbH is not the sole author of this work
Bradley M. Kuhn <bkuhn@sfconservancy.org>
parents: 4208
diff changeset
21 This file was forked by the Kallithea project in July 2014.
1948ede028ef RhodeCode GmbH is not the sole author of this work
Bradley M. Kuhn <bkuhn@sfconservancy.org>
parents: 4208
diff changeset
22 Original author and date, and relevant copyright and licensing information is below:
4116
ffd45b185016 Imported some of the GPLv3'd changes from RhodeCode v2.2.5.
Bradley M. Kuhn <bkuhn@sfconservancy.org>
parents: 3500
diff changeset
23 :created_on: May 23, 2013
ffd45b185016 Imported some of the GPLv3'd changes from RhodeCode v2.2.5.
Bradley M. Kuhn <bkuhn@sfconservancy.org>
parents: 3500
diff changeset
24 :author: marcink
4211
1948ede028ef RhodeCode GmbH is not the sole author of this work
Bradley M. Kuhn <bkuhn@sfconservancy.org>
parents: 4208
diff changeset
25 :copyright: (c) 2013 RhodeCode GmbH, and others.
4208
ad38f9f93b3b Correct licensing information in individual files.
Bradley M. Kuhn <bkuhn@sfconservancy.org>
parents: 4187
diff changeset
26 :license: GPLv3, see LICENSE.md for more details.
4116
ffd45b185016 Imported some of the GPLv3'd changes from RhodeCode v2.2.5.
Bradley M. Kuhn <bkuhn@sfconservancy.org>
parents: 3500
diff changeset
27 """
ffd45b185016 Imported some of the GPLv3'd changes from RhodeCode v2.2.5.
Bradley M. Kuhn <bkuhn@sfconservancy.org>
parents: 3500
diff changeset
28
7811
0a277465fddf scripts: initial run of import cleanup using isort
Mads Kiilerich <mads@kiilerich.com>
parents: 4918
diff changeset
29 import logging
3489
d997a314d18a moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
30 import time
7811
0a277465fddf scripts: initial run of import cleanup using isort
Mads Kiilerich <mads@kiilerich.com>
parents: 4918
diff changeset
31
8791
b3d8a3000a7f lib: cleanup of _get_ip_addr
Mads Kiilerich <mads@kiilerich.com>
parents: 8771
diff changeset
32 from kallithea.lib.base import get_ip_addr, get_path_info
3489
d997a314d18a moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
33
d997a314d18a moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
34
7906
5240fbde6ddb wsgi: reintroduce the "wrapper" middleware for logging request timing, but guarded by optional use_wsgi_wrapper=true
Mads Kiilerich <mads@kiilerich.com>
parents: 7811
diff changeset
35 log = logging.getLogger(__name__)
5240fbde6ddb wsgi: reintroduce the "wrapper" middleware for logging request timing, but guarded by optional use_wsgi_wrapper=true
Mads Kiilerich <mads@kiilerich.com>
parents: 7811
diff changeset
36
5240fbde6ddb wsgi: reintroduce the "wrapper" middleware for logging request timing, but guarded by optional use_wsgi_wrapper=true
Mads Kiilerich <mads@kiilerich.com>
parents: 7811
diff changeset
37
5240fbde6ddb wsgi: reintroduce the "wrapper" middleware for logging request timing, but guarded by optional use_wsgi_wrapper=true
Mads Kiilerich <mads@kiilerich.com>
parents: 7811
diff changeset
38 class Meter:
5240fbde6ddb wsgi: reintroduce the "wrapper" middleware for logging request timing, but guarded by optional use_wsgi_wrapper=true
Mads Kiilerich <mads@kiilerich.com>
parents: 7811
diff changeset
39
7908
19418a4c6c61 wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7907
diff changeset
40 def __init__(self, start_response):
19418a4c6c61 wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7907
diff changeset
41 self._start_response = start_response
7906
5240fbde6ddb wsgi: reintroduce the "wrapper" middleware for logging request timing, but guarded by optional use_wsgi_wrapper=true
Mads Kiilerich <mads@kiilerich.com>
parents: 7811
diff changeset
42 self._start = time.time()
8325
da39f9548758 middleware: HTTP status code logging in wrapper summaries
Mads Kiilerich <mads@kiilerich.com>
parents: 8177
diff changeset
43 self.status = None
7908
19418a4c6c61 wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7907
diff changeset
44 self._size = 0
7906
5240fbde6ddb wsgi: reintroduce the "wrapper" middleware for logging request timing, but guarded by optional use_wsgi_wrapper=true
Mads Kiilerich <mads@kiilerich.com>
parents: 7811
diff changeset
45
5240fbde6ddb wsgi: reintroduce the "wrapper" middleware for logging request timing, but guarded by optional use_wsgi_wrapper=true
Mads Kiilerich <mads@kiilerich.com>
parents: 7811
diff changeset
46 def duration(self):
5240fbde6ddb wsgi: reintroduce the "wrapper" middleware for logging request timing, but guarded by optional use_wsgi_wrapper=true
Mads Kiilerich <mads@kiilerich.com>
parents: 7811
diff changeset
47 return time.time() - self._start
5240fbde6ddb wsgi: reintroduce the "wrapper" middleware for logging request timing, but guarded by optional use_wsgi_wrapper=true
Mads Kiilerich <mads@kiilerich.com>
parents: 7811
diff changeset
48
7908
19418a4c6c61 wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7907
diff changeset
49 def start_response(self, status, response_headers, exc_info=None):
8325
da39f9548758 middleware: HTTP status code logging in wrapper summaries
Mads Kiilerich <mads@kiilerich.com>
parents: 8177
diff changeset
50 self.status = status
7908
19418a4c6c61 wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7907
diff changeset
51 write = self._start_response(status, response_headers, exc_info)
19418a4c6c61 wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7907
diff changeset
52 def metered_write(s):
19418a4c6c61 wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7907
diff changeset
53 self.measure(s)
19418a4c6c61 wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7907
diff changeset
54 write(s)
19418a4c6c61 wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7907
diff changeset
55 return metered_write
19418a4c6c61 wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7907
diff changeset
56
19418a4c6c61 wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7907
diff changeset
57 def measure(self, chunk):
19418a4c6c61 wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7907
diff changeset
58 self._size += len(chunk)
19418a4c6c61 wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7907
diff changeset
59
19418a4c6c61 wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7907
diff changeset
60 def size(self):
19418a4c6c61 wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7907
diff changeset
61 return self._size
19418a4c6c61 wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7907
diff changeset
62
7906
5240fbde6ddb wsgi: reintroduce the "wrapper" middleware for logging request timing, but guarded by optional use_wsgi_wrapper=true
Mads Kiilerich <mads@kiilerich.com>
parents: 7811
diff changeset
63
7907
b42ee1bdf082 wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7906
diff changeset
64 class ResultIter:
b42ee1bdf082 wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7906
diff changeset
65
b42ee1bdf082 wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7906
diff changeset
66 def __init__(self, result, meter, description):
b42ee1bdf082 wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7906
diff changeset
67 self._result_close = getattr(result, 'close', None) or (lambda: None)
8177
e26c0616e003 py3: use global next() function instead of .next() method
Mads Kiilerich <mads@kiilerich.com>
parents: 8068
diff changeset
68 self._next = iter(result).__next__
7907
b42ee1bdf082 wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7906
diff changeset
69 self._meter = meter
b42ee1bdf082 wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7906
diff changeset
70 self._description = description
b42ee1bdf082 wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7906
diff changeset
71
b42ee1bdf082 wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7906
diff changeset
72 def __iter__(self):
b42ee1bdf082 wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7906
diff changeset
73 return self
b42ee1bdf082 wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7906
diff changeset
74
8177
e26c0616e003 py3: use global next() function instead of .next() method
Mads Kiilerich <mads@kiilerich.com>
parents: 8068
diff changeset
75 def __next__(self):
7907
b42ee1bdf082 wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7906
diff changeset
76 chunk = self._next()
7908
19418a4c6c61 wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7907
diff changeset
77 self._meter.measure(chunk)
7907
b42ee1bdf082 wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7906
diff changeset
78 return chunk
b42ee1bdf082 wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7906
diff changeset
79
b42ee1bdf082 wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7906
diff changeset
80 def close(self):
b42ee1bdf082 wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7906
diff changeset
81 self._result_close()
8325
da39f9548758 middleware: HTTP status code logging in wrapper summaries
Mads Kiilerich <mads@kiilerich.com>
parents: 8177
diff changeset
82 log.info("%s responded %r after %.3fs with %s bytes", self._description, self._meter.status, self._meter.duration(), self._meter.size())
7907
b42ee1bdf082 wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7906
diff changeset
83
b42ee1bdf082 wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7906
diff changeset
84
3489
d997a314d18a moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
85 class RequestWrapper(object):
d997a314d18a moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
86
d997a314d18a moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
87 def __init__(self, app, config):
d997a314d18a moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
88 self.application = app
d997a314d18a moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
89 self.config = config
d997a314d18a moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
90
d997a314d18a moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
91 def __call__(self, environ, start_response):
7908
19418a4c6c61 wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7907
diff changeset
92 meter = Meter(start_response)
7906
5240fbde6ddb wsgi: reintroduce the "wrapper" middleware for logging request timing, but guarded by optional use_wsgi_wrapper=true
Mads Kiilerich <mads@kiilerich.com>
parents: 7811
diff changeset
93 description = "Request from %s for %s" % (
8791
b3d8a3000a7f lib: cleanup of _get_ip_addr
Mads Kiilerich <mads@kiilerich.com>
parents: 8771
diff changeset
94 get_ip_addr(environ),
8068
c82ef5ec8dcd lib: refactor _get_access_path as get_path_info
Mads Kiilerich <mads@kiilerich.com>
parents: 7908
diff changeset
95 get_path_info(environ),
7906
5240fbde6ddb wsgi: reintroduce the "wrapper" middleware for logging request timing, but guarded by optional use_wsgi_wrapper=true
Mads Kiilerich <mads@kiilerich.com>
parents: 7811
diff changeset
96 )
8350
5da95e8a2d07 wrapper: log clearly when request has been received
Mads Kiilerich <mads@kiilerich.com>
parents: 8325
diff changeset
97 log.info("%s received", description)
3489
d997a314d18a moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
98 try:
7908
19418a4c6c61 wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7907
diff changeset
99 result = self.application(environ, meter.start_response)
3489
d997a314d18a moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
100 finally:
8325
da39f9548758 middleware: HTTP status code logging in wrapper summaries
Mads Kiilerich <mads@kiilerich.com>
parents: 8177
diff changeset
101 log.info("%s responding %r after %.3fs", description, meter.status, meter.duration())
7907
b42ee1bdf082 wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents: 7906
diff changeset
102 return ResultIter(result, meter, description)