diff --git a/gunicorn.conf.py b/gunicorn.conf.py index 7f23553a1de..0f1d93a8638 100644 --- a/gunicorn.conf.py +++ b/gunicorn.conf.py @@ -1,11 +1,15 @@ # Gunicorn sample configuration file. # See http://gunicorn.org/configure.html for more details. # -# To run OpenERP via Gunicorn, change the appropriate +# To run the OpenERP server via Gunicorn, change the appropriate # settings below, in order to provide the parameters that # would normally be passed in the command-line, # (at least `bind` and `conf['addons_path']`), then execute: -# $ gunicorn openerp:wsgi.application -c gunicorn.conf.py +# $ gunicorn openerp:wsgi.core.application -c gunicorn.conf.py +# or if you want to run it behind a reverse proxy, add the line +# import openerp.wsgi.proxied +# in this file and execute: +# $ gunicorn openerp:wsgi.proxied.application -c gunicorn.conf.py import openerp @@ -20,10 +24,10 @@ pidfile = '.gunicorn.pid' workers = 4 # Some application-wide initialization is needed. -on_starting = openerp.wsgi.on_starting -when_ready = openerp.wsgi.when_ready -pre_request = openerp.wsgi.pre_request -post_request = openerp.wsgi.post_request +on_starting = openerp.wsgi.core.on_starting +when_ready = openerp.wsgi.core.when_ready +pre_request = openerp.wsgi.core.pre_request +post_request = openerp.wsgi.core.post_request # openerp request-response cycle can be quite long for # big reports for example diff --git a/openerp/service/__init__.py b/openerp/service/__init__.py index 9fa1cf5c4f9..c387d272e26 100644 --- a/openerp/service/__init__.py +++ b/openerp/service/__init__.py @@ -71,7 +71,7 @@ def start_services(): openerp.netsvc.Server.startAll() # Start the WSGI server. - openerp.wsgi.start_server() + openerp.wsgi.core.start_server() def stop_services(): @@ -80,7 +80,7 @@ def stop_services(): openerp.cron.cancel_all() openerp.netsvc.Server.quitAll() - openerp.wsgi.stop_server() + openerp.wsgi.core.stop_server() config = openerp.tools.config _logger.info("Initiating shutdown") _logger.info("Hit CTRL-C again or send a second signal to force the shutdown.") diff --git a/openerp/tools/config.py b/openerp/tools/config.py index d628447a7a8..a92ad443c7b 100644 --- a/openerp/tools/config.py +++ b/openerp/tools/config.py @@ -3,6 +3,7 @@ # # OpenERP, Open Source Management Solution # Copyright (C) 2004-2009 Tiny SPRL (). +# Copyright (C) 2010-2012 OpenERP s.a. (). # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -115,6 +116,8 @@ class configmanager(object): help="specify the TCP port for the XML-RPC protocol", type="int") group.add_option("--no-xmlrpc", dest="xmlrpc", action="store_false", my_default=True, help="disable the XML-RPC protocol") + group.add_option("--proxy-mode", dest="proxy_mode", action="store_true", my_default=False, + help="Enable correct behavior when behind a reverse proxy") parser.add_option_group(group) # XML-RPC / HTTPS @@ -391,7 +394,7 @@ class configmanager(object): 'language', 'translate_out', 'translate_in', 'overwrite_existing_translations', 'debug_mode', 'smtp_ssl', 'load_language', 'stop_after_init', 'logrotate', 'without_demo', 'netrpc', 'xmlrpc', 'syslog', - 'list_db', 'xmlrpcs', + 'list_db', 'xmlrpcs', 'proxy_mode', 'test_file', 'test_disable', 'test_commit', 'test_report_directory', 'osv_memory_count_limit', 'osv_memory_age_limit', 'max_cron_threads', 'virtual_memory_limit', 'virtual_memory_reset', 'cpu_time_limit', 'unaccent', diff --git a/openerp/wsgi/__init__.py b/openerp/wsgi/__init__.py new file mode 100644 index 00000000000..a536ee57327 --- /dev/null +++ b/openerp/wsgi/__init__.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2012-2012 OpenERP s.a. (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +""" WSGI stack + +This module offers a WSGI interface to/from OpenERP. + +""" + +from . import core + +# TODO: This is for the web addons, can be removed later. +register_wsgi_handler = core.register_wsgi_handler + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/wsgi.py b/openerp/wsgi/core.py similarity index 97% rename from openerp/wsgi.py rename to openerp/wsgi/core.py index 32fb59f8d91..986222596e9 100644 --- a/openerp/wsgi.py +++ b/openerp/wsgi/core.py @@ -2,7 +2,7 @@ ############################################################################## # # OpenERP, Open Source Management Solution -# Copyright (C) 2011 OpenERP s.a. (). +# Copyright (C) 2011-2012 OpenERP s.a. (). # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -19,9 +19,9 @@ # ############################################################################## -""" WSGI stuffs (proof of concept for now) +""" -This module offers a WSGI interface to OpenERP. +WSGI stack, common code. """ @@ -41,7 +41,7 @@ import traceback import openerp import openerp.modules import openerp.tools.config as config -import service.websrv_lib as websrv_lib +from ..service import websrv_lib _logger = logging.getLogger(__name__) @@ -423,11 +423,20 @@ def serve(): port = config['xmlrpc_port'] try: import werkzeug.serving + if config['proxy_mode']: + from werkzeug.contrib.fixers import ProxyFix + app = ProxyFix(application) + suffix = ' (in proxy mode)' + else: + app = application + suffix = '' httpd = werkzeug.serving.make_server(interface, port, application, threaded=True) - _logger.info('HTTP service (werkzeug) running on %s:%s', interface, port) + _logger.info('HTTP service (werkzeug) running on %s:%s%s', interface, port, suffix) except ImportError: import wsgiref.simple_server _logger.warning('Werkzeug module unavailable, falling back to wsgiref.') + if config['proxy_mode']: + _logger.warning('Werkzeug module unavailable, not using proxy mode.') httpd = wsgiref.simple_server.make_server(interface, port, application) _logger.info('HTTP service (wsgiref) running on %s:%s', interface, port) @@ -438,7 +447,7 @@ def start_server(): The WSGI server can be shutdown with stop_server() below. """ - threading.Thread(target=openerp.wsgi.serve).start() + threading.Thread(target=serve).start() def stop_server(): """ Initiate the shutdown of the WSGI server. diff --git a/openerp/wsgi/proxied.py b/openerp/wsgi/proxied.py new file mode 100644 index 00000000000..658f6f29c55 --- /dev/null +++ b/openerp/wsgi/proxied.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2012 OpenERP s.a. (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +""" + +WSGI entry point with Proxy mode (from Werkzeug). + +""" + +from werkzeug.contrib.fixers import ProxyFix + +from . import core + +application = ProxyFix(core.application) + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: