##// END OF EJS Templates
svn: Activate the svn_support module. #4082
Martin Bornhold -
r561:35012271 default
parent child Browse files
Show More
@@ -1,403 +1,404 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 RhodeCode GmbH
3 # Copyright (C) 2010-2016 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 """
21 """
22 Pylons middleware initialization
22 Pylons middleware initialization
23 """
23 """
24 import logging
24 import logging
25 from collections import OrderedDict
25 from collections import OrderedDict
26
26
27 from paste.registry import RegistryManager
27 from paste.registry import RegistryManager
28 from paste.gzipper import make_gzip_middleware
28 from paste.gzipper import make_gzip_middleware
29 from pylons.wsgiapp import PylonsApp
29 from pylons.wsgiapp import PylonsApp
30 from pyramid.authorization import ACLAuthorizationPolicy
30 from pyramid.authorization import ACLAuthorizationPolicy
31 from pyramid.config import Configurator
31 from pyramid.config import Configurator
32 from pyramid.static import static_view
32 from pyramid.static import static_view
33 from pyramid.settings import asbool, aslist
33 from pyramid.settings import asbool, aslist
34 from pyramid.wsgi import wsgiapp
34 from pyramid.wsgi import wsgiapp
35 from pyramid.httpexceptions import HTTPError, HTTPInternalServerError
35 from pyramid.httpexceptions import HTTPError, HTTPInternalServerError
36 from pylons.controllers.util import abort, redirect
36 from pylons.controllers.util import abort, redirect
37 import pyramid.httpexceptions as httpexceptions
37 import pyramid.httpexceptions as httpexceptions
38 from pyramid.renderers import render_to_response, render
38 from pyramid.renderers import render_to_response, render
39 from routes.middleware import RoutesMiddleware
39 from routes.middleware import RoutesMiddleware
40 import routes.util
40 import routes.util
41
41
42 import rhodecode
42 import rhodecode
43 import rhodecode.integrations # do not remove this as it registers celery tasks
43 import rhodecode.integrations # do not remove this as it registers celery tasks
44 from rhodecode.config import patches
44 from rhodecode.config import patches
45 from rhodecode.config.routing import STATIC_FILE_PREFIX
45 from rhodecode.config.routing import STATIC_FILE_PREFIX
46 from rhodecode.config.environment import (
46 from rhodecode.config.environment import (
47 load_environment, load_pyramid_environment)
47 load_environment, load_pyramid_environment)
48 from rhodecode.lib.middleware import csrf
48 from rhodecode.lib.middleware import csrf
49 from rhodecode.lib.middleware.appenlight import wrap_in_appenlight_if_enabled
49 from rhodecode.lib.middleware.appenlight import wrap_in_appenlight_if_enabled
50 from rhodecode.lib.middleware.disable_vcs import DisableVCSPagesWrapper
50 from rhodecode.lib.middleware.disable_vcs import DisableVCSPagesWrapper
51 from rhodecode.lib.middleware.https_fixup import HttpsFixup
51 from rhodecode.lib.middleware.https_fixup import HttpsFixup
52 from rhodecode.lib.middleware.vcs import VCSMiddleware
52 from rhodecode.lib.middleware.vcs import VCSMiddleware
53 from rhodecode.lib.plugins.utils import register_rhodecode_plugin
53 from rhodecode.lib.plugins.utils import register_rhodecode_plugin
54
54
55
55
56 log = logging.getLogger(__name__)
56 log = logging.getLogger(__name__)
57
57
58
58
59 # this is used to avoid avoid the route lookup overhead in routesmiddleware
59 # this is used to avoid avoid the route lookup overhead in routesmiddleware
60 # for certain routes which won't go to pylons to - eg. static files, debugger
60 # for certain routes which won't go to pylons to - eg. static files, debugger
61 # it is only needed for the pylons migration and can be removed once complete
61 # it is only needed for the pylons migration and can be removed once complete
62 class SkippableRoutesMiddleware(RoutesMiddleware):
62 class SkippableRoutesMiddleware(RoutesMiddleware):
63 """ Routes middleware that allows you to skip prefixes """
63 """ Routes middleware that allows you to skip prefixes """
64
64
65 def __init__(self, *args, **kw):
65 def __init__(self, *args, **kw):
66 self.skip_prefixes = kw.pop('skip_prefixes', [])
66 self.skip_prefixes = kw.pop('skip_prefixes', [])
67 super(SkippableRoutesMiddleware, self).__init__(*args, **kw)
67 super(SkippableRoutesMiddleware, self).__init__(*args, **kw)
68
68
69 def __call__(self, environ, start_response):
69 def __call__(self, environ, start_response):
70 for prefix in self.skip_prefixes:
70 for prefix in self.skip_prefixes:
71 if environ['PATH_INFO'].startswith(prefix):
71 if environ['PATH_INFO'].startswith(prefix):
72 # added to avoid the case when a missing /_static route falls
72 # added to avoid the case when a missing /_static route falls
73 # through to pylons and causes an exception as pylons is
73 # through to pylons and causes an exception as pylons is
74 # expecting wsgiorg.routingargs to be set in the environ
74 # expecting wsgiorg.routingargs to be set in the environ
75 # by RoutesMiddleware.
75 # by RoutesMiddleware.
76 if 'wsgiorg.routing_args' not in environ:
76 if 'wsgiorg.routing_args' not in environ:
77 environ['wsgiorg.routing_args'] = (None, {})
77 environ['wsgiorg.routing_args'] = (None, {})
78 return self.app(environ, start_response)
78 return self.app(environ, start_response)
79
79
80 return super(SkippableRoutesMiddleware, self).__call__(
80 return super(SkippableRoutesMiddleware, self).__call__(
81 environ, start_response)
81 environ, start_response)
82
82
83
83
84 def make_app(global_conf, full_stack=True, static_files=True, **app_conf):
84 def make_app(global_conf, full_stack=True, static_files=True, **app_conf):
85 """Create a Pylons WSGI application and return it
85 """Create a Pylons WSGI application and return it
86
86
87 ``global_conf``
87 ``global_conf``
88 The inherited configuration for this application. Normally from
88 The inherited configuration for this application. Normally from
89 the [DEFAULT] section of the Paste ini file.
89 the [DEFAULT] section of the Paste ini file.
90
90
91 ``full_stack``
91 ``full_stack``
92 Whether or not this application provides a full WSGI stack (by
92 Whether or not this application provides a full WSGI stack (by
93 default, meaning it handles its own exceptions and errors).
93 default, meaning it handles its own exceptions and errors).
94 Disable full_stack when this application is "managed" by
94 Disable full_stack when this application is "managed" by
95 another WSGI middleware.
95 another WSGI middleware.
96
96
97 ``app_conf``
97 ``app_conf``
98 The application's local configuration. Normally specified in
98 The application's local configuration. Normally specified in
99 the [app:<name>] section of the Paste ini file (where <name>
99 the [app:<name>] section of the Paste ini file (where <name>
100 defaults to main).
100 defaults to main).
101
101
102 """
102 """
103 # Apply compatibility patches
103 # Apply compatibility patches
104 patches.kombu_1_5_1_python_2_7_11()
104 patches.kombu_1_5_1_python_2_7_11()
105 patches.inspect_getargspec()
105 patches.inspect_getargspec()
106
106
107 # Configure the Pylons environment
107 # Configure the Pylons environment
108 config = load_environment(global_conf, app_conf)
108 config = load_environment(global_conf, app_conf)
109
109
110 # The Pylons WSGI app
110 # The Pylons WSGI app
111 app = PylonsApp(config=config)
111 app = PylonsApp(config=config)
112 if rhodecode.is_test:
112 if rhodecode.is_test:
113 app = csrf.CSRFDetector(app)
113 app = csrf.CSRFDetector(app)
114
114
115 expected_origin = config.get('expected_origin')
115 expected_origin = config.get('expected_origin')
116 if expected_origin:
116 if expected_origin:
117 # The API can be accessed from other Origins.
117 # The API can be accessed from other Origins.
118 app = csrf.OriginChecker(app, expected_origin,
118 app = csrf.OriginChecker(app, expected_origin,
119 skip_urls=[routes.util.url_for('api')])
119 skip_urls=[routes.util.url_for('api')])
120
120
121
121
122 if asbool(full_stack):
122 if asbool(full_stack):
123
123
124 # Appenlight monitoring and error handler
124 # Appenlight monitoring and error handler
125 app, appenlight_client = wrap_in_appenlight_if_enabled(app, config)
125 app, appenlight_client = wrap_in_appenlight_if_enabled(app, config)
126
126
127 # we want our low level middleware to get to the request ASAP. We don't
127 # we want our low level middleware to get to the request ASAP. We don't
128 # need any pylons stack middleware in them
128 # need any pylons stack middleware in them
129 app = VCSMiddleware(app, config, appenlight_client)
129 app = VCSMiddleware(app, config, appenlight_client)
130
130
131 # Establish the Registry for this application
131 # Establish the Registry for this application
132 app = RegistryManager(app)
132 app = RegistryManager(app)
133
133
134 app.config = config
134 app.config = config
135
135
136 return app
136 return app
137
137
138
138
139 def make_pyramid_app(global_config, **settings):
139 def make_pyramid_app(global_config, **settings):
140 """
140 """
141 Constructs the WSGI application based on Pyramid and wraps the Pylons based
141 Constructs the WSGI application based on Pyramid and wraps the Pylons based
142 application.
142 application.
143
143
144 Specials:
144 Specials:
145
145
146 * We migrate from Pylons to Pyramid. While doing this, we keep both
146 * We migrate from Pylons to Pyramid. While doing this, we keep both
147 frameworks functional. This involves moving some WSGI middlewares around
147 frameworks functional. This involves moving some WSGI middlewares around
148 and providing access to some data internals, so that the old code is
148 and providing access to some data internals, so that the old code is
149 still functional.
149 still functional.
150
150
151 * The application can also be integrated like a plugin via the call to
151 * The application can also be integrated like a plugin via the call to
152 `includeme`. This is accompanied with the other utility functions which
152 `includeme`. This is accompanied with the other utility functions which
153 are called. Changing this should be done with great care to not break
153 are called. Changing this should be done with great care to not break
154 cases when these fragments are assembled from another place.
154 cases when these fragments are assembled from another place.
155
155
156 """
156 """
157 # The edition string should be available in pylons too, so we add it here
157 # The edition string should be available in pylons too, so we add it here
158 # before copying the settings.
158 # before copying the settings.
159 settings.setdefault('rhodecode.edition', 'Community Edition')
159 settings.setdefault('rhodecode.edition', 'Community Edition')
160
160
161 # As long as our Pylons application does expect "unprepared" settings, make
161 # As long as our Pylons application does expect "unprepared" settings, make
162 # sure that we keep an unmodified copy. This avoids unintentional change of
162 # sure that we keep an unmodified copy. This avoids unintentional change of
163 # behavior in the old application.
163 # behavior in the old application.
164 settings_pylons = settings.copy()
164 settings_pylons = settings.copy()
165
165
166 sanitize_settings_and_apply_defaults(settings)
166 sanitize_settings_and_apply_defaults(settings)
167 config = Configurator(settings=settings)
167 config = Configurator(settings=settings)
168 add_pylons_compat_data(config.registry, global_config, settings_pylons)
168 add_pylons_compat_data(config.registry, global_config, settings_pylons)
169
169
170 load_pyramid_environment(global_config, settings)
170 load_pyramid_environment(global_config, settings)
171
171
172 includeme_first(config)
172 includeme_first(config)
173 includeme(config)
173 includeme(config)
174 pyramid_app = config.make_wsgi_app()
174 pyramid_app = config.make_wsgi_app()
175 pyramid_app = wrap_app_in_wsgi_middlewares(pyramid_app, config)
175 pyramid_app = wrap_app_in_wsgi_middlewares(pyramid_app, config)
176 return pyramid_app
176 return pyramid_app
177
177
178
178
179 def add_pylons_compat_data(registry, global_config, settings):
179 def add_pylons_compat_data(registry, global_config, settings):
180 """
180 """
181 Attach data to the registry to support the Pylons integration.
181 Attach data to the registry to support the Pylons integration.
182 """
182 """
183 registry._pylons_compat_global_config = global_config
183 registry._pylons_compat_global_config = global_config
184 registry._pylons_compat_settings = settings
184 registry._pylons_compat_settings = settings
185
185
186
186
187 def webob_to_pyramid_http_response(webob_response):
187 def webob_to_pyramid_http_response(webob_response):
188 ResponseClass = httpexceptions.status_map[webob_response.status_int]
188 ResponseClass = httpexceptions.status_map[webob_response.status_int]
189 pyramid_response = ResponseClass(webob_response.status)
189 pyramid_response = ResponseClass(webob_response.status)
190 pyramid_response.status = webob_response.status
190 pyramid_response.status = webob_response.status
191 pyramid_response.headers.update(webob_response.headers)
191 pyramid_response.headers.update(webob_response.headers)
192 if pyramid_response.headers['content-type'] == 'text/html':
192 if pyramid_response.headers['content-type'] == 'text/html':
193 pyramid_response.headers['content-type'] = 'text/html; charset=UTF-8'
193 pyramid_response.headers['content-type'] = 'text/html; charset=UTF-8'
194 return pyramid_response
194 return pyramid_response
195
195
196
196
197 def error_handler(exception, request):
197 def error_handler(exception, request):
198 # TODO: dan: replace the old pylons error controller with this
198 # TODO: dan: replace the old pylons error controller with this
199 from rhodecode.model.settings import SettingsModel
199 from rhodecode.model.settings import SettingsModel
200 from rhodecode.lib.utils2 import AttributeDict
200 from rhodecode.lib.utils2 import AttributeDict
201
201
202 try:
202 try:
203 rc_config = SettingsModel().get_all_settings()
203 rc_config = SettingsModel().get_all_settings()
204 except Exception:
204 except Exception:
205 log.exception('failed to fetch settings')
205 log.exception('failed to fetch settings')
206 rc_config = {}
206 rc_config = {}
207
207
208 base_response = HTTPInternalServerError()
208 base_response = HTTPInternalServerError()
209 # prefer original exception for the response since it may have headers set
209 # prefer original exception for the response since it may have headers set
210 if isinstance(exception, HTTPError):
210 if isinstance(exception, HTTPError):
211 base_response = exception
211 base_response = exception
212
212
213 c = AttributeDict()
213 c = AttributeDict()
214 c.error_message = base_response.status
214 c.error_message = base_response.status
215 c.error_explanation = base_response.explanation or str(base_response)
215 c.error_explanation = base_response.explanation or str(base_response)
216 c.visual = AttributeDict()
216 c.visual = AttributeDict()
217
217
218 c.visual.rhodecode_support_url = (
218 c.visual.rhodecode_support_url = (
219 request.registry.settings.get('rhodecode_support_url') or
219 request.registry.settings.get('rhodecode_support_url') or
220 request.route_url('rhodecode_support')
220 request.route_url('rhodecode_support')
221 )
221 )
222 c.redirect_time = 0
222 c.redirect_time = 0
223 c.rhodecode_name = rc_config.get('rhodecode_title', '')
223 c.rhodecode_name = rc_config.get('rhodecode_title', '')
224 if not c.rhodecode_name:
224 if not c.rhodecode_name:
225 c.rhodecode_name = 'Rhodecode'
225 c.rhodecode_name = 'Rhodecode'
226
226
227 response = render_to_response(
227 response = render_to_response(
228 '/errors/error_document.html', {'c': c}, request=request,
228 '/errors/error_document.html', {'c': c}, request=request,
229 response=base_response)
229 response=base_response)
230
230
231 return response
231 return response
232
232
233
233
234 def includeme(config):
234 def includeme(config):
235 settings = config.registry.settings
235 settings = config.registry.settings
236
236
237 # plugin information
237 # plugin information
238 config.registry.rhodecode_plugins = OrderedDict()
238 config.registry.rhodecode_plugins = OrderedDict()
239
239
240 config.add_directive(
240 config.add_directive(
241 'register_rhodecode_plugin', register_rhodecode_plugin)
241 'register_rhodecode_plugin', register_rhodecode_plugin)
242
242
243 if asbool(settings.get('appenlight', 'false')):
243 if asbool(settings.get('appenlight', 'false')):
244 config.include('appenlight_client.ext.pyramid_tween')
244 config.include('appenlight_client.ext.pyramid_tween')
245
245
246 # Includes which are required. The application would fail without them.
246 # Includes which are required. The application would fail without them.
247 config.include('pyramid_mako')
247 config.include('pyramid_mako')
248 config.include('pyramid_beaker')
248 config.include('pyramid_beaker')
249 config.include('rhodecode.channelstream')
249 config.include('rhodecode.channelstream')
250 config.include('rhodecode.admin')
250 config.include('rhodecode.admin')
251 config.include('rhodecode.authentication')
251 config.include('rhodecode.authentication')
252 config.include('rhodecode.integrations')
252 config.include('rhodecode.integrations')
253 config.include('rhodecode.login')
253 config.include('rhodecode.login')
254 config.include('rhodecode.tweens')
254 config.include('rhodecode.tweens')
255 config.include('rhodecode.api')
255 config.include('rhodecode.api')
256 config.include('rhodecode.svn_support')
256 config.add_route(
257 config.add_route(
257 'rhodecode_support', 'https://rhodecode.com/help/', static=True)
258 'rhodecode_support', 'https://rhodecode.com/help/', static=True)
258
259
259 # Set the authorization policy.
260 # Set the authorization policy.
260 authz_policy = ACLAuthorizationPolicy()
261 authz_policy = ACLAuthorizationPolicy()
261 config.set_authorization_policy(authz_policy)
262 config.set_authorization_policy(authz_policy)
262
263
263 # Set the default renderer for HTML templates to mako.
264 # Set the default renderer for HTML templates to mako.
264 config.add_mako_renderer('.html')
265 config.add_mako_renderer('.html')
265
266
266 # include RhodeCode plugins
267 # include RhodeCode plugins
267 includes = aslist(settings.get('rhodecode.includes', []))
268 includes = aslist(settings.get('rhodecode.includes', []))
268 for inc in includes:
269 for inc in includes:
269 config.include(inc)
270 config.include(inc)
270
271
271 pylons_app = make_app(
272 pylons_app = make_app(
272 config.registry._pylons_compat_global_config,
273 config.registry._pylons_compat_global_config,
273 **config.registry._pylons_compat_settings)
274 **config.registry._pylons_compat_settings)
274 config.registry._pylons_compat_config = pylons_app.config
275 config.registry._pylons_compat_config = pylons_app.config
275
276
276 pylons_app_as_view = wsgiapp(pylons_app)
277 pylons_app_as_view = wsgiapp(pylons_app)
277
278
278 # Protect from VCS Server error related pages when server is not available
279 # Protect from VCS Server error related pages when server is not available
279 vcs_server_enabled = asbool(settings.get('vcs.server.enable', 'true'))
280 vcs_server_enabled = asbool(settings.get('vcs.server.enable', 'true'))
280 if not vcs_server_enabled:
281 if not vcs_server_enabled:
281 pylons_app_as_view = DisableVCSPagesWrapper(pylons_app_as_view)
282 pylons_app_as_view = DisableVCSPagesWrapper(pylons_app_as_view)
282
283
283
284
284 def pylons_app_with_error_handler(context, request):
285 def pylons_app_with_error_handler(context, request):
285 """
286 """
286 Handle exceptions from rc pylons app:
287 Handle exceptions from rc pylons app:
287
288
288 - old webob type exceptions get converted to pyramid exceptions
289 - old webob type exceptions get converted to pyramid exceptions
289 - pyramid exceptions are passed to the error handler view
290 - pyramid exceptions are passed to the error handler view
290 """
291 """
291 try:
292 try:
292 response = pylons_app_as_view(context, request)
293 response = pylons_app_as_view(context, request)
293 if 400 <= response.status_int <= 599: # webob type error responses
294 if 400 <= response.status_int <= 599: # webob type error responses
294 return error_handler(
295 return error_handler(
295 webob_to_pyramid_http_response(response), request)
296 webob_to_pyramid_http_response(response), request)
296 except HTTPError as e: # pyramid type exceptions
297 except HTTPError as e: # pyramid type exceptions
297 return error_handler(e, request)
298 return error_handler(e, request)
298 except Exception:
299 except Exception:
299 if settings.get('debugtoolbar.enabled', False):
300 if settings.get('debugtoolbar.enabled', False):
300 raise
301 raise
301 return error_handler(HTTPInternalServerError(), request)
302 return error_handler(HTTPInternalServerError(), request)
302 return response
303 return response
303
304
304 # This is the glue which allows us to migrate in chunks. By registering the
305 # This is the glue which allows us to migrate in chunks. By registering the
305 # pylons based application as the "Not Found" view in Pyramid, we will
306 # pylons based application as the "Not Found" view in Pyramid, we will
306 # fallback to the old application each time the new one does not yet know
307 # fallback to the old application each time the new one does not yet know
307 # how to handle a request.
308 # how to handle a request.
308 config.add_notfound_view(pylons_app_with_error_handler)
309 config.add_notfound_view(pylons_app_with_error_handler)
309
310
310 if not settings.get('debugtoolbar.enabled', False):
311 if not settings.get('debugtoolbar.enabled', False):
311 # if no toolbar, then any exception gets caught and rendered
312 # if no toolbar, then any exception gets caught and rendered
312 config.add_view(error_handler, context=Exception)
313 config.add_view(error_handler, context=Exception)
313
314
314 config.add_view(error_handler, context=HTTPError)
315 config.add_view(error_handler, context=HTTPError)
315
316
316
317
317 def includeme_first(config):
318 def includeme_first(config):
318 # redirect automatic browser favicon.ico requests to correct place
319 # redirect automatic browser favicon.ico requests to correct place
319 def favicon_redirect(context, request):
320 def favicon_redirect(context, request):
320 return redirect(
321 return redirect(
321 request.static_url('rhodecode:public/images/favicon.ico'))
322 request.static_url('rhodecode:public/images/favicon.ico'))
322
323
323 config.add_view(favicon_redirect, route_name='favicon')
324 config.add_view(favicon_redirect, route_name='favicon')
324 config.add_route('favicon', '/favicon.ico')
325 config.add_route('favicon', '/favicon.ico')
325
326
326 config.add_static_view(
327 config.add_static_view(
327 '_static/deform', 'deform:static')
328 '_static/deform', 'deform:static')
328 config.add_static_view(
329 config.add_static_view(
329 '_static/rhodecode', path='rhodecode:public', cache_max_age=3600 * 24)
330 '_static/rhodecode', path='rhodecode:public', cache_max_age=3600 * 24)
330
331
331 def wrap_app_in_wsgi_middlewares(pyramid_app, config):
332 def wrap_app_in_wsgi_middlewares(pyramid_app, config):
332 """
333 """
333 Apply outer WSGI middlewares around the application.
334 Apply outer WSGI middlewares around the application.
334
335
335 Part of this has been moved up from the Pylons layer, so that the
336 Part of this has been moved up from the Pylons layer, so that the
336 data is also available if old Pylons code is hit through an already ported
337 data is also available if old Pylons code is hit through an already ported
337 view.
338 view.
338 """
339 """
339 settings = config.registry.settings
340 settings = config.registry.settings
340
341
341 # enable https redirects based on HTTP_X_URL_SCHEME set by proxy
342 # enable https redirects based on HTTP_X_URL_SCHEME set by proxy
342 pyramid_app = HttpsFixup(pyramid_app, settings)
343 pyramid_app = HttpsFixup(pyramid_app, settings)
343
344
344 # Add RoutesMiddleware to support the pylons compatibility tween during
345 # Add RoutesMiddleware to support the pylons compatibility tween during
345 # migration to pyramid.
346 # migration to pyramid.
346 pyramid_app = SkippableRoutesMiddleware(
347 pyramid_app = SkippableRoutesMiddleware(
347 pyramid_app, config.registry._pylons_compat_config['routes.map'],
348 pyramid_app, config.registry._pylons_compat_config['routes.map'],
348 skip_prefixes=(STATIC_FILE_PREFIX, '/_debug_toolbar'))
349 skip_prefixes=(STATIC_FILE_PREFIX, '/_debug_toolbar'))
349
350
350 if asbool(settings.get('appenlight', 'false')):
351 if asbool(settings.get('appenlight', 'false')):
351 pyramid_app, _ = wrap_in_appenlight_if_enabled(
352 pyramid_app, _ = wrap_in_appenlight_if_enabled(
352 pyramid_app, config.registry._pylons_compat_config)
353 pyramid_app, config.registry._pylons_compat_config)
353
354
354 if asbool(settings.get('gzip_responses', 'true')):
355 if asbool(settings.get('gzip_responses', 'true')):
355 pyramid_app = make_gzip_middleware(
356 pyramid_app = make_gzip_middleware(
356 pyramid_app, settings, compress_level=1)
357 pyramid_app, settings, compress_level=1)
357
358
358 return pyramid_app
359 return pyramid_app
359
360
360
361
361 def sanitize_settings_and_apply_defaults(settings):
362 def sanitize_settings_and_apply_defaults(settings):
362 """
363 """
363 Applies settings defaults and does all type conversion.
364 Applies settings defaults and does all type conversion.
364
365
365 We would move all settings parsing and preparation into this place, so that
366 We would move all settings parsing and preparation into this place, so that
366 we have only one place left which deals with this part. The remaining parts
367 we have only one place left which deals with this part. The remaining parts
367 of the application would start to rely fully on well prepared settings.
368 of the application would start to rely fully on well prepared settings.
368
369
369 This piece would later be split up per topic to avoid a big fat monster
370 This piece would later be split up per topic to avoid a big fat monster
370 function.
371 function.
371 """
372 """
372
373
373 # Pyramid's mako renderer has to search in the templates folder so that the
374 # Pyramid's mako renderer has to search in the templates folder so that the
374 # old templates still work. Ported and new templates are expected to use
375 # old templates still work. Ported and new templates are expected to use
375 # real asset specifications for the includes.
376 # real asset specifications for the includes.
376 mako_directories = settings.setdefault('mako.directories', [
377 mako_directories = settings.setdefault('mako.directories', [
377 # Base templates of the original Pylons application
378 # Base templates of the original Pylons application
378 'rhodecode:templates',
379 'rhodecode:templates',
379 ])
380 ])
380 log.debug(
381 log.debug(
381 "Using the following Mako template directories: %s",
382 "Using the following Mako template directories: %s",
382 mako_directories)
383 mako_directories)
383
384
384 # Default includes, possible to change as a user
385 # Default includes, possible to change as a user
385 pyramid_includes = settings.setdefault('pyramid.includes', [
386 pyramid_includes = settings.setdefault('pyramid.includes', [
386 'rhodecode.lib.middleware.request_wrapper',
387 'rhodecode.lib.middleware.request_wrapper',
387 ])
388 ])
388 log.debug(
389 log.debug(
389 "Using the following pyramid.includes: %s",
390 "Using the following pyramid.includes: %s",
390 pyramid_includes)
391 pyramid_includes)
391
392
392 # TODO: johbo: Re-think this, usually the call to config.include
393 # TODO: johbo: Re-think this, usually the call to config.include
393 # should allow to pass in a prefix.
394 # should allow to pass in a prefix.
394 settings.setdefault('rhodecode.api.url', '/_admin/api')
395 settings.setdefault('rhodecode.api.url', '/_admin/api')
395
396
396 _bool_setting(settings, 'vcs.server.enable', 'true')
397 _bool_setting(settings, 'vcs.server.enable', 'true')
397 _bool_setting(settings, 'is_test', 'false')
398 _bool_setting(settings, 'is_test', 'false')
398
399
399 return settings
400 return settings
400
401
401
402
402 def _bool_setting(settings, name, default):
403 def _bool_setting(settings, name, default):
403 settings[name] = asbool(settings.get(name, default))
404 settings[name] = asbool(settings.get(name, default))
General Comments 0
You need to be logged in to leave comments. Login now