<commit_before># This file is part of Indico.
# Copyright (C) 2002 - 2016 European Organization for Nuclear Research (CERN).
#
# Indico is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# Indico 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
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Indico; if not, see <http://www.gnu.org/licenses/>.

import logging
import errno
import urlparse
import os
import signal
import socket
import sys

import werkzeug.serving
from flask import current_app
from flask_script import Command, Option
from werkzeug.contrib.fixers import ProxyFix
from werkzeug.debug import DebuggedApplication
from werkzeug.exceptions import NotFound
from werkzeug.serving import WSGIRequestHandler
from werkzeug.wsgi import DispatcherMiddleware, SharedDataMiddleware

from indico.core.config import Config
from indico.core.logger import Logger
from indico.util import console


try:
    from OpenSSL import SSL
except ImportError:
    SSL = None


class IndicoDevServer(Command):
    """Runs the Flask development server"""

    def get_options(self):
        return (
            Option('--logging', action='store',
                   help='display logging messages for specified level'),
            Option('--host',
                   help='use a different host than the one in indico.conf'),
            Option('--port', type=int,
                   help='use a different port than the one in indico.conf'),
            Option('--keep-base-url', action='store_true',
                   help='do not update the base url with the given host/port'),
            Option('--with-ssl', action='store_true',
                   help='enable ssl support for web server'),
            Option('--ssl-key', help='path to the ssl private key file'),
            Option('--ssl-cert', help='path to the ssl certificate file'),
            Option('--disable-reloader', action='store_true',
                   help='restart the server whenever a file changes (does not work for legacy code)'),
            Option('--enable-evalex', action='store_true',
                   help="enable the werkzeug debugger's python shell in tracebacks and via /console)"),
            Option('--evalex-from', action='append', metavar='IP',
                   help="restricts the evalex shell to the given ips (can be used multiple times)"),
            Option('--quiet', action='store_true',
                   help="don't log successful requests for common static files")
        )

    def run(self, **args):
        if args['logging']:
            setup_logging(args['logging'])

        app = current_app._get_current_object()
        start_web_server(app, host=args['host'], port=args['port'], keep_base_url=args['keep_base_url'],
                         with_ssl=args['with_ssl'], ssl_cert=args['ssl_cert'], ssl_key=args['ssl_key'],
                         enable_evalex=args['enable_evalex'], evalex_from=args['evalex_from'],
                         reload_on_change=not args['disable_reloader'], quiet=args['quiet'])


def make_indico_dispatcher(wsgi_app):
    config = Config.getInstance()
    baseURL = config.getBaseURL()
    path = urlparse.urlparse(baseURL)[2].rstrip('/')
    if not path:
        # Nothing to dispatch
        return wsgi_app
    else:
        return DispatcherMiddleware(NotFound(), {
            path: wsgi_app
        })


class DebuggedIndico(DebuggedApplication):
    def __init__(self, *args, **kwargs):
        self._evalex_whitelist = None
        self._request_ip = None
        super(DebuggedIndico, self).__init__(*args, **kwargs)

    @property
    def evalex(self):
        if not self._evalex_whitelist:
            return False
        elif self._evalex_whitelist is True:  # explicitly check against True!
            return True
        else:
            return self._request_ip in self._evalex_whitelist

    @evalex.setter
    def evalex(self, value):
        self._evalex_whitelist = value

    def __call__(self, environ, start_response):
        self._request_ip = environ['REMOTE_ADDR']
        return super(DebuggedIndico, self).__call__(environ, start_response)


class QuietWSGIRequestHandler(WSGIRequestHandler):
    INDICO_URL_PREFIX = ''  # set from outside based on BaseURL
    IGNORED_PATH_PREFIXES = {'/vars.js', '/js/', '/css/', '/static/', '/images/'}

    def log_request(self, code='-', size='-'):
        if code not in (304, 200):
            super(QuietWSGIRequestHandler, self).log_request(code, size)
        elif '?__debugger__=yes&cmd=resource' in self.path:
            pass  # don't log debugger resources, they are quite uninteresting
        elif not any(self.path.startswith(self.INDICO_URL_PREFIX + x) for x in self.IGNORED_PATH_PREFIXES):
            super(QuietWSGIRequestHandler, self).log_request(code, size)


class WerkzeugServer(object):
    def __init__(self, app, host='localhost', port=8000, enable_ssl=False, ssl_key=None, ssl_cert=None,
                 reload_on_change=False, use_debugger=True, evalex_whitelist=None, quiet=False):
        """
        Run an Indico server based on the Werkzeug server
        """

        if not SSL and enable_ssl:
            console.error('You need pyopenssl to use SSL')
            sys.exit(1)

        self.app = app
        self.host = host
        self.port = port<commit_msg>Convert IPv6-style IPv4 addrs in evalex whitelist<commit_after># This file is part of Indico.
# Copyright (C) 2002 - 2016 European Organization for Nuclear Research (CERN).
#
# Indico is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# Indico 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
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Indico; if not, see <http://www.gnu.org/licenses/>.

import logging
import errno
import urlparse
import os
import signal
import socket
import sys

import werkzeug.serving
from flask import current_app
from flask_script import Command, Option
from werkzeug.contrib.fixers import ProxyFix
from werkzeug.debug import DebuggedApplication
from werkzeug.exceptions import NotFound
from werkzeug.serving import WSGIRequestHandler
from werkzeug.wsgi import DispatcherMiddleware, SharedDataMiddleware

from indico.core.config import Config
from indico.core.logger import Logger
from indico.util import console


try:
    from OpenSSL import SSL
except ImportError:
    SSL = None


class IndicoDevServer(Command):
    """Runs the Flask development server"""

    def get_options(self):
        return (
            Option('--logging', action='store',
                   help='display logging messages for specified level'),
            Option('--host',
                   help='use a different host than the one in indico.conf'),
            Option('--port', type=int,
                   help='use a different port than the one in indico.conf'),
            Option('--keep-base-url', action='store_true',
                   help='do not update the base url with the given host/port'),
            Option('--with-ssl', action='store_true',
                   help='enable ssl support for web server'),
            Option('--ssl-key', help='path to the ssl private key file'),
            Option('--ssl-cert', help='path to the ssl certificate file'),
            Option('--disable-reloader', action='store_true',
                   help='restart the server whenever a file changes (does not work for legacy code)'),
            Option('--enable-evalex', action='store_true',
                   help="enable the werkzeug debugger's python shell in tracebacks and via /console)"),
            Option('--evalex-from', action='append', metavar='IP',
                   help="restricts the evalex shell to the given ips (can be used multiple times)"),
            Option('--quiet', action='store_true',
                   help="don't log successful requests for common static files")
        )

    def run(self, **args):
        if args['logging']:
            setup_logging(args['logging'])

        app = current_app._get_current_object()
        start_web_server(app, host=args['host'], port=args['port'], keep_base_url=args['keep_base_url'],
                         with_ssl=args['with_ssl'], ssl_cert=args['ssl_cert'], ssl_key=args['ssl_key'],
                         enable_evalex=args['enable_evalex'], evalex_from=args['evalex_from'],
                         reload_on_change=not args['disable_reloader'], quiet=args['quiet'])


def make_indico_dispatcher(wsgi_app):
    config = Config.getInstance()
    baseURL = config.getBaseURL()
    path = urlparse.urlparse(baseURL)[2].rstrip('/')
    if not path:
        # Nothing to dispatch
        return wsgi_app
    else:
        return DispatcherMiddleware(NotFound(), {
            path: wsgi_app
        })


class DebuggedIndico(DebuggedApplication):
    def __init__(self, *args, **kwargs):
        self._evalex_whitelist = None
        self._request_ip = None
        super(DebuggedIndico, self).__init__(*args, **kwargs)

    @property
    def evalex(self):
        if not self._evalex_whitelist:
            return False
        elif self._evalex_whitelist is True:  # explicitly check against True!
            return True
        else:
            return self._request_ip in self._evalex_whitelist

    @evalex.setter
    def evalex(self, value):
        self._evalex_whitelist = value

    def __call__(self, environ, start_response):
        self._request_ip = environ['REMOTE_ADDR']
        if self._request_ip.startswith('::ffff:'):
            # convert ipv6-style ipv4 to the regular ipv4 notation
            self._request_ip = self._request_ip[7:]
        return super(DebuggedIndico, self).__call__(environ, start_response)


class QuietWSGIRequestHandler(WSGIRequestHandler):
    INDICO_URL_PREFIX = ''  # set from outside based on BaseURL
    IGNORED_PATH_PREFIXES = {'/vars.js', '/js/', '/css/', '/static/', '/images/'}

    def log_request(self, code='-', size='-'):
        if code not in (304, 200):
            super(QuietWSGIRequestHandler, self).log_request(code, size)
        elif '?__debugger__=yes&cmd=resource' in self.path:
            pass  # don't log debugger resources, they are quite uninteresting
        elif not any(self.path.startswith(self.INDICO_URL_PREFIX + x) for x in self.IGNORED_PATH_PREFIXES):
            super(QuietWSGIRequestHandler, self).log_request(code, size)


class WerkzeugServer(object):
    def __init__(self, app, host='localhost', port=8000, enable_ssl=False, ssl_key=None, ssl_cert=None,
                 reload_on_change=False, use_debugger=True, evalex_whitelist=None, quiet=False):
        """
        Run an Indico server based on the Werkzeug server
        """

        if not SSL and enable_ssl:
            console.error('You need pyopenssl to use SSL')
            sys.exit(1)

        self.app = app
        self.host = host
        self.port = port
{'fraction_non_alphanumeric': 0.09932804962095107, 'fraction_numerical': 0.004135079255685734, 'mean_word_length': 2.840224942110486, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5132645', 'n_tokens_mistral': 3314, 'n_tokens_neox': 3191, 'n_words': 1005}