etwist/server.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Fri, 01 Jul 2011 15:26:44 +0200
changeset 7606 01b49ec8fe80
parent 7570 648bf83945a5
child 7619 0d0344fd5231
permissions -rw-r--r--
[facets] allow to specify on which rqlst's variable facets should be applied. Closes #1795915
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7344
5290b5c586ec [etwist] fix bug w/ new resources concantenation and https-url enabled sites
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7309
diff changeset
     1
# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5325
diff changeset
     2
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5325
diff changeset
     3
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5325
diff changeset
     4
# This file is part of CubicWeb.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5325
diff changeset
     5
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5325
diff changeset
     6
# CubicWeb is free software: you can redistribute it and/or modify it under the
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5325
diff changeset
     7
# terms of the GNU Lesser General Public License as published by the Free
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5325
diff changeset
     8
# Software Foundation, either version 2.1 of the License, or (at your option)
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5325
diff changeset
     9
# any later version.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5325
diff changeset
    10
#
5424
8ecbcbff9777 replace logilab-common by CubicWeb in disclaimer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5421
diff changeset
    11
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5325
diff changeset
    12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5325
diff changeset
    13
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5325
diff changeset
    14
# details.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5325
diff changeset
    15
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5325
diff changeset
    16
# You should have received a copy of the GNU Lesser General Public License along
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5325
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
5814
51cc4b61f9ae [repo] fix 'c-c start --loglevel LEVEL' for repository only configuration. Closes #1058269.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5762
diff changeset
    18
"""twisted server for CubicWeb web instances"""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
7276
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
    20
from __future__ import with_statement
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
    21
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    22
__docformat__ = "restructuredtext en"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    23
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    24
import sys
2654
6512522860aa [twisted] don't use twistd anymore, all-in-one.py file is needed anymore
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2476
diff changeset
    25
import os
7273
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
    26
import os.path as osp
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    27
import select
4398
4e7e74918631 add missing errno import in etwist/server.py
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4221
diff changeset
    28
import errno
5243
1ab7acb9abe9 [etwist] we must call all error not handled in _render_request, else the thread fail silently and nothing ends up on the ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5223
diff changeset
    29
import traceback
5652
904091dc4c7e [etwist] twisted won't install signal handler outside the main thread.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 5553
diff changeset
    30
import threading
7276
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
    31
import re
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
    32
import hashlib
5216
4f4369e63f5e [twisted] fix LongTimeExpiringFile and getChild implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5155
diff changeset
    33
from os.path import join
1016
26387b836099 use datetime instead of mx.DateTime
sylvain.thenault@logilab.fr
parents: 151
diff changeset
    34
from time import mktime
26387b836099 use datetime instead of mx.DateTime
sylvain.thenault@logilab.fr
parents: 151
diff changeset
    35
from datetime import date, timedelta
1520
b097057e629d provide an option to substitute the base-url (left-most part) subdomain by the one of the current http query to easy multiple subdomains website management
Florent <florent@secondweb.fr>
parents: 1420
diff changeset
    36
from urlparse import urlsplit, urlunsplit
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    37
from cgi import FieldStorage, parse_header
5243
1ab7acb9abe9 [etwist] we must call all error not handled in _render_request, else the thread fail silently and nothing ends up on the ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5223
diff changeset
    38
from cStringIO import StringIO
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    39
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    40
from twisted.internet import reactor, task, threads
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    41
from twisted.internet.defer import maybeDeferred
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    42
from twisted.web import http, server
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    43
from twisted.web import static, resource
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    44
from twisted.web.server import NOT_DONE_YET
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    45
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    46
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    47
from logilab.common.decorators import monkeypatch
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    48
7276
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
    49
from cubicweb import (AuthenticationError, ConfigurationError,
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
    50
                      CW_EVENT_MANAGER, CubicWebException)
5940
0e3ae19b181a [uilib] refactor json_dumps code organization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5933
diff changeset
    51
from cubicweb.utils import json_dumps
5223
6abd6e3599f4 #773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5216
diff changeset
    52
from cubicweb.web import Redirect, DirectResponse, StatusResponse, LogOut
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    53
from cubicweb.web.application import CubicWebPublisher
5216
4f4369e63f5e [twisted] fix LongTimeExpiringFile and getChild implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5155
diff changeset
    54
from cubicweb.web.http_headers import generateDateTime
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    55
from cubicweb.etwist.request import CubicWebTwistedRequestAdapter
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    56
from cubicweb.etwist.http import HTTPResponse
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    57
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    58
def start_task(interval, func):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    59
    lc = task.LoopingCall(func)
3493
3e4603678d4e use default repo looping task so they are started in thread, else we get blocking task
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3198
diff changeset
    60
    # wait until interval has expired to actually start the task, else we have
3e4603678d4e use default repo looping task so they are started in thread, else we get blocking task
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3198
diff changeset
    61
    # to wait all task to be finished for the server to be actually started
3e4603678d4e use default repo looping task so they are started in thread, else we get blocking task
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3198
diff changeset
    62
    lc.start(interval, now=False)
1420
25c13e5b12bd stop complaining about empty response, remove trailing spaces
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
    63
1543
dca9817bb337 fix use-request-subdomain option behaviour and add tests
Florent <florent@secondweb.fr>
parents: 1542
diff changeset
    64
def host_prefixed_baseurl(baseurl, host):
dca9817bb337 fix use-request-subdomain option behaviour and add tests
Florent <florent@secondweb.fr>
parents: 1542
diff changeset
    65
    scheme, netloc, url, query, fragment = urlsplit(baseurl)
dca9817bb337 fix use-request-subdomain option behaviour and add tests
Florent <florent@secondweb.fr>
parents: 1542
diff changeset
    66
    netloc_domain = '.' + '.'.join(netloc.split('.')[-2:])
dca9817bb337 fix use-request-subdomain option behaviour and add tests
Florent <florent@secondweb.fr>
parents: 1542
diff changeset
    67
    if host.endswith(netloc_domain):
dca9817bb337 fix use-request-subdomain option behaviour and add tests
Florent <florent@secondweb.fr>
parents: 1542
diff changeset
    68
        netloc = host
dca9817bb337 fix use-request-subdomain option behaviour and add tests
Florent <florent@secondweb.fr>
parents: 1542
diff changeset
    69
    baseurl = urlunsplit((scheme, netloc, url, query, fragment))
dca9817bb337 fix use-request-subdomain option behaviour and add tests
Florent <florent@secondweb.fr>
parents: 1542
diff changeset
    70
    return baseurl
dca9817bb337 fix use-request-subdomain option behaviour and add tests
Florent <florent@secondweb.fr>
parents: 1542
diff changeset
    71
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    72
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    73
class ForbiddenDirectoryLister(resource.Resource):
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    74
    def render(self, request):
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    75
        return HTTPResponse(twisted_request=request,
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    76
                            code=http.FORBIDDEN,
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    77
                            stream='Access forbidden')
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    78
7273
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
    79
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
    80
class NoListingFile(static.File):
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    81
    def directoryListing(self):
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    82
        return ForbiddenDirectoryLister()
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    83
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    84
7273
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
    85
class DataLookupDirectory(NoListingFile):
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
    86
    def __init__(self, config, path):
7276
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
    87
        self.md5_version = config.instance_md5_version()
7273
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
    88
        NoListingFile.__init__(self, path)
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
    89
        self.config = config
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
    90
        self.here = path
7275
bb3bb8104134 put data version md5 into a new url segment to ease static serving
Florent Cayré <florent.cayre@gmail.com>
parents: 7273
diff changeset
    91
        self._defineChildResources()
7276
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
    92
        if self.config.debugmode:
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
    93
            self.data_modconcat_basepath = '/data/??'
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
    94
        else:
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
    95
            self.data_modconcat_basepath = '/data/%s/??' % self.md5_version
7275
bb3bb8104134 put data version md5 into a new url segment to ease static serving
Florent Cayré <florent.cayre@gmail.com>
parents: 7273
diff changeset
    96
bb3bb8104134 put data version md5 into a new url segment to ease static serving
Florent Cayré <florent.cayre@gmail.com>
parents: 7273
diff changeset
    97
    def _defineChildResources(self):
7276
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
    98
        self.putChild(self.md5_version, self)
7273
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
    99
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   100
    def getChild(self, path, request):
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   101
        if not path:
7344
5290b5c586ec [etwist] fix bug w/ new resources concantenation and https-url enabled sites
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7309
diff changeset
   102
            uri = request.uri
5290b5c586ec [etwist] fix bug w/ new resources concantenation and https-url enabled sites
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7309
diff changeset
   103
            if uri.startswith('/https/'):
5290b5c586ec [etwist] fix bug w/ new resources concantenation and https-url enabled sites
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7309
diff changeset
   104
                uri = uri[6:]
5290b5c586ec [etwist] fix bug w/ new resources concantenation and https-url enabled sites
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7309
diff changeset
   105
            if uri.startswith(self.data_modconcat_basepath):
5290b5c586ec [etwist] fix bug w/ new resources concantenation and https-url enabled sites
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7309
diff changeset
   106
                resource_relpath = uri[len(self.data_modconcat_basepath):]
7276
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
   107
                if resource_relpath:
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
   108
                    paths = resource_relpath.split(',')
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
   109
                    try:
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
   110
                        return ConcatFiles(self.config, paths)
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
   111
                    except ConcatFileNotFoundError:
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
   112
                        return self.childNotFound
7273
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   113
            return self.directoryListing()
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   114
        childpath = join(self.here, path)
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   115
        dirpath, rid = self.config.locate_resource(childpath)
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   116
        if dirpath is None:
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   117
            # resource not found
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   118
            return self.childNotFound
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   119
        filepath = os.path.join(dirpath, rid)
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   120
        if os.path.isdir(filepath):
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   121
            resource = DataLookupDirectory(self.config, childpath)
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   122
            # cache resource for this segment path to avoid recomputing
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   123
            # directory lookup
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   124
            self.putChild(path, resource)
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   125
            return resource
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   126
        else:
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   127
            return NoListingFile(filepath)
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   128
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   129
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   130
class FCKEditorResource(NoListingFile):
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   131
    def __init__(self, config, path):
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   132
        NoListingFile.__init__(self, path)
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   133
        self.config = config
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   134
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   135
    def getChild(self, path, request):
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   136
        pre_path = request.path.split('/')[1:]
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   137
        if pre_path[0] == 'https':
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   138
            pre_path.pop(0)
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   139
            uiprops = self.config.https_uiprops
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   140
        else:
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   141
            uiprops = self.config.uiprops
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   142
        return static.File(osp.join(uiprops['FCKEDITOR_PATH'], path))
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   143
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   144
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   145
class LongTimeExpiringFile(DataLookupDirectory):
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   146
    """overrides static.File and sets a far future ``Expires`` date
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   147
    on the resouce.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   148
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   149
    versions handling is done by serving static files by different
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   150
    URLs for each version. For instance::
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   151
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   152
      http://localhost:8080/data-2.48.2/cubicweb.css
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   153
      http://localhost:8080/data-2.49.0/cubicweb.css
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   154
      etc.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   155
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   156
    """
7275
bb3bb8104134 put data version md5 into a new url segment to ease static serving
Florent Cayré <florent.cayre@gmail.com>
parents: 7273
diff changeset
   157
    def _defineChildResources(self):
bb3bb8104134 put data version md5 into a new url segment to ease static serving
Florent Cayré <florent.cayre@gmail.com>
parents: 7273
diff changeset
   158
        pass
bb3bb8104134 put data version md5 into a new url segment to ease static serving
Florent Cayré <florent.cayre@gmail.com>
parents: 7273
diff changeset
   159
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   160
    def render(self, request):
5216
4f4369e63f5e [twisted] fix LongTimeExpiringFile and getChild implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5155
diff changeset
   161
        # XXX: Don't provide additional resource information to error responses
4f4369e63f5e [twisted] fix LongTimeExpiringFile and getChild implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5155
diff changeset
   162
        #
4f4369e63f5e [twisted] fix LongTimeExpiringFile and getChild implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5155
diff changeset
   163
        # the HTTP RFC recommands not going further than 1 year ahead
4f4369e63f5e [twisted] fix LongTimeExpiringFile and getChild implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5155
diff changeset
   164
        expires = date.today() + timedelta(days=6*30)
4f4369e63f5e [twisted] fix LongTimeExpiringFile and getChild implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5155
diff changeset
   165
        request.setHeader('Expires', generateDateTime(mktime(expires.timetuple())))
7273
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   166
        return DataLookupDirectory.render(self, request)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   167
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   168
7276
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
   169
class ConcatFileNotFoundError(CubicWebException):
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
   170
    pass
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
   171
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
   172
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
   173
class ConcatFiles(LongTimeExpiringFile):
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
   174
    def __init__(self, config, paths):
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
   175
        _, ext = osp.splitext(paths[0])
7565
b355d9dd43df [js/css concat] do not return 404 when resources of a concatenated data URL does not exist, unless in debugmode; closes #1745644
Florent Cayré <florent.cayre@gmail.com>
parents: 7344
diff changeset
   176
        self._resources = {}
7276
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
   177
        # create a unique / predictable filename
7309
22403d5c3da4 fix ajax loading of concatenated js/ css + prefix concat cache files to ease cache clearing
Florent Cayré <florent.cayre@gmail.com>
parents: 7283
diff changeset
   178
        fname = 'cache_concat_' + hashlib.md5(';'.join(paths)).hexdigest() + ext
7276
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
   179
        filepath = osp.join(config.appdatahome, 'uicache', fname)
7283
1699393372b3 [etwist] in debug-mode, concat-file is rebuilt if one of the concatenated file is more recent
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7277
diff changeset
   180
        LongTimeExpiringFile.__init__(self, config, filepath)
1699393372b3 [etwist] in debug-mode, concat-file is rebuilt if one of the concatenated file is more recent
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7277
diff changeset
   181
        self._concat_cached_filepath(filepath, paths)
1699393372b3 [etwist] in debug-mode, concat-file is rebuilt if one of the concatenated file is more recent
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7277
diff changeset
   182
7565
b355d9dd43df [js/css concat] do not return 404 when resources of a concatenated data URL does not exist, unless in debugmode; closes #1745644
Florent Cayré <florent.cayre@gmail.com>
parents: 7344
diff changeset
   183
    def _resource(self, path):
b355d9dd43df [js/css concat] do not return 404 when resources of a concatenated data URL does not exist, unless in debugmode; closes #1745644
Florent Cayré <florent.cayre@gmail.com>
parents: 7344
diff changeset
   184
        try:
b355d9dd43df [js/css concat] do not return 404 when resources of a concatenated data URL does not exist, unless in debugmode; closes #1745644
Florent Cayré <florent.cayre@gmail.com>
parents: 7344
diff changeset
   185
            return self._resources[path]
b355d9dd43df [js/css concat] do not return 404 when resources of a concatenated data URL does not exist, unless in debugmode; closes #1745644
Florent Cayré <florent.cayre@gmail.com>
parents: 7344
diff changeset
   186
        except KeyError:
b355d9dd43df [js/css concat] do not return 404 when resources of a concatenated data URL does not exist, unless in debugmode; closes #1745644
Florent Cayré <florent.cayre@gmail.com>
parents: 7344
diff changeset
   187
            self._resources[path] = self.config.locate_resource(path)
b355d9dd43df [js/css concat] do not return 404 when resources of a concatenated data URL does not exist, unless in debugmode; closes #1745644
Florent Cayré <florent.cayre@gmail.com>
parents: 7344
diff changeset
   188
            return self._resources[path]
b355d9dd43df [js/css concat] do not return 404 when resources of a concatenated data URL does not exist, unless in debugmode; closes #1745644
Florent Cayré <florent.cayre@gmail.com>
parents: 7344
diff changeset
   189
7283
1699393372b3 [etwist] in debug-mode, concat-file is rebuilt if one of the concatenated file is more recent
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7277
diff changeset
   190
    def _concat_cached_filepath(self, filepath, paths):
1699393372b3 [etwist] in debug-mode, concat-file is rebuilt if one of the concatenated file is more recent
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7277
diff changeset
   191
        if not self._up_to_date(filepath, paths):
7276
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
   192
            concat_data = []
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
   193
            for path in paths:
7565
b355d9dd43df [js/css concat] do not return 404 when resources of a concatenated data URL does not exist, unless in debugmode; closes #1745644
Florent Cayré <florent.cayre@gmail.com>
parents: 7344
diff changeset
   194
                dirpath, rid = self._resource(path)
7276
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
   195
                if rid is None:
7570
648bf83945a5 [etwist] log missing file even in debug mode
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7565
diff changeset
   196
                    # In production mode log an error, do not return a 404
648bf83945a5 [etwist] log missing file even in debug mode
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7565
diff changeset
   197
                    # XXX the erroneous content is cached anyway
648bf83945a5 [etwist] log missing file even in debug mode
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7565
diff changeset
   198
                    LOGGER.error('concatenated data url error: %r file '
648bf83945a5 [etwist] log missing file even in debug mode
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7565
diff changeset
   199
                                 'does not exist', path)
7565
b355d9dd43df [js/css concat] do not return 404 when resources of a concatenated data URL does not exist, unless in debugmode; closes #1745644
Florent Cayré <florent.cayre@gmail.com>
parents: 7344
diff changeset
   200
                    if self.config.debugmode:
b355d9dd43df [js/css concat] do not return 404 when resources of a concatenated data URL does not exist, unless in debugmode; closes #1745644
Florent Cayré <florent.cayre@gmail.com>
parents: 7344
diff changeset
   201
                        raise ConcatFileNotFoundError(path)
b355d9dd43df [js/css concat] do not return 404 when resources of a concatenated data URL does not exist, unless in debugmode; closes #1745644
Florent Cayré <florent.cayre@gmail.com>
parents: 7344
diff changeset
   202
                else:
b355d9dd43df [js/css concat] do not return 404 when resources of a concatenated data URL does not exist, unless in debugmode; closes #1745644
Florent Cayré <florent.cayre@gmail.com>
parents: 7344
diff changeset
   203
                    concat_data.append(open(osp.join(dirpath, rid)).read())
7276
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
   204
            with open(filepath, 'wb') as f:
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
   205
                f.write('\n'.join(concat_data))
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
   206
7283
1699393372b3 [etwist] in debug-mode, concat-file is rebuilt if one of the concatenated file is more recent
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7277
diff changeset
   207
    def _up_to_date(self, filepath, paths):
1699393372b3 [etwist] in debug-mode, concat-file is rebuilt if one of the concatenated file is more recent
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7277
diff changeset
   208
        """
1699393372b3 [etwist] in debug-mode, concat-file is rebuilt if one of the concatenated file is more recent
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7277
diff changeset
   209
        The concat-file is considered up-to-date if it exists.
1699393372b3 [etwist] in debug-mode, concat-file is rebuilt if one of the concatenated file is more recent
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7277
diff changeset
   210
        In debug mode, an additional check is performed to make sure that
1699393372b3 [etwist] in debug-mode, concat-file is rebuilt if one of the concatenated file is more recent
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7277
diff changeset
   211
        concat-file is more recent than all concatenated files
1699393372b3 [etwist] in debug-mode, concat-file is rebuilt if one of the concatenated file is more recent
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7277
diff changeset
   212
        """
1699393372b3 [etwist] in debug-mode, concat-file is rebuilt if one of the concatenated file is more recent
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7277
diff changeset
   213
        if not osp.isfile(filepath):
1699393372b3 [etwist] in debug-mode, concat-file is rebuilt if one of the concatenated file is more recent
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7277
diff changeset
   214
            return False
1699393372b3 [etwist] in debug-mode, concat-file is rebuilt if one of the concatenated file is more recent
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7277
diff changeset
   215
        if self.config.debugmode:
1699393372b3 [etwist] in debug-mode, concat-file is rebuilt if one of the concatenated file is more recent
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7277
diff changeset
   216
            concat_lastmod = os.stat(filepath).st_mtime
1699393372b3 [etwist] in debug-mode, concat-file is rebuilt if one of the concatenated file is more recent
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7277
diff changeset
   217
            for path in paths:
7565
b355d9dd43df [js/css concat] do not return 404 when resources of a concatenated data URL does not exist, unless in debugmode; closes #1745644
Florent Cayré <florent.cayre@gmail.com>
parents: 7344
diff changeset
   218
                dirpath, rid = self._resource(path)
7283
1699393372b3 [etwist] in debug-mode, concat-file is rebuilt if one of the concatenated file is more recent
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7277
diff changeset
   219
                if rid is None:
1699393372b3 [etwist] in debug-mode, concat-file is rebuilt if one of the concatenated file is more recent
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7277
diff changeset
   220
                    raise ConcatFileNotFoundError(path)
1699393372b3 [etwist] in debug-mode, concat-file is rebuilt if one of the concatenated file is more recent
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7277
diff changeset
   221
                path = osp.join(dirpath, rid)
1699393372b3 [etwist] in debug-mode, concat-file is rebuilt if one of the concatenated file is more recent
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7277
diff changeset
   222
                if os.stat(path).st_mtime > concat_lastmod:
1699393372b3 [etwist] in debug-mode, concat-file is rebuilt if one of the concatenated file is more recent
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7277
diff changeset
   223
                    return False
1699393372b3 [etwist] in debug-mode, concat-file is rebuilt if one of the concatenated file is more recent
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7277
diff changeset
   224
        return True
7276
f9a68136eb87 handle js/ css file concatenation with twisted
Florent Cayré <florent.cayre@gmail.com>
parents: 7275
diff changeset
   225
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   226
class CubicWebRootResource(resource.Resource):
5653
c562791df9d2 [web server] vregistry may now be passed as named argument in CubicWebRootResource constructor
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5555
diff changeset
   227
    def __init__(self, config, vreg=None):
7273
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   228
        resource.Resource.__init__(self)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   229
        self.config = config
3828
335e40fdb5a5 when instance is started normally (eg not in debug mode), check versions before daemonization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3791
diff changeset
   230
        # instantiate publisher here and not in init_publisher to get some
335e40fdb5a5 when instance is started normally (eg not in debug mode), check versions before daemonization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3791
diff changeset
   231
        # checks done before daemonization (eg versions consistency)
5653
c562791df9d2 [web server] vregistry may now be passed as named argument in CubicWebRootResource constructor
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5555
diff changeset
   232
        self.appli = CubicWebPublisher(config, vreg=vreg)
4909
a13c1d1ecc5b [web server] simplify base-url handling on startup. Ensure config['base-url'] is correctly set once started
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4436
diff changeset
   233
        self.base_url = config['base-url']
a13c1d1ecc5b [web server] simplify base-url handling on startup. Ensure config['base-url'] is correctly set once started
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4436
diff changeset
   234
        self.https_url = config['https-url']
5270
6297d5265572 [etwist] allow to specify max size for POST request in the configuration. We should deal with this nicely on the js form validation code.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5243
diff changeset
   235
        global MAX_POST_LENGTH
5330
19bc44f5f9d1 [web] no more needed with the bytes option type
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5328
diff changeset
   236
        MAX_POST_LENGTH = config['max-post-length']
7273
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   237
        self.putChild('static', NoListingFile(config.static_directory))
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   238
        self.putChild('fckeditor', FCKEditorResource(self.config, ''))
a949fc438029 [etwist] refactor child resources management
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6817
diff changeset
   239
        self.putChild('data', DataLookupDirectory(self.config, ''))
3606
8326aceecb46 fix startup as a daemon
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3558
diff changeset
   240
8326aceecb46 fix startup as a daemon
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3558
diff changeset
   241
    def init_publisher(self):
8326aceecb46 fix startup as a daemon
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3558
diff changeset
   242
        config = self.config
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   243
        # when we have an in-memory repository, clean unused sessions every XX
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   244
        # seconds and properly shutdown the server
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   245
        if config.repo_method == 'inmemory':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   246
            if config.pyro_enabled():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   247
                # if pyro is enabled, we have to register to the pyro name
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   248
                # server, create a pyro daemon, and create a task to handle pyro
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   249
                # requests
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   250
                self.pyro_daemon = self.appli.repo.pyro_register()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   251
                self.pyro_listen_timeout = 0.02
3502
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3493
diff changeset
   252
                self.appli.repo.looping_task(1, self.pyro_loop_event)
5654
8bb34548be86 [web test] Add a CubicWebServerTC class to run test with a cw web serveur available.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 5653
diff changeset
   253
            if config.mode != 'test':
8bb34548be86 [web test] Add a CubicWebServerTC class to run test with a cw web serveur available.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 5653
diff changeset
   254
                reactor.addSystemEventTrigger('before', 'shutdown',
8bb34548be86 [web test] Add a CubicWebServerTC class to run test with a cw web serveur available.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 5653
diff changeset
   255
                                              self.shutdown_event)
8bb34548be86 [web test] Add a CubicWebServerTC class to run test with a cw web serveur available.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 5653
diff changeset
   256
                self.appli.repo.start_looping_tasks()
2685
0518ca8f63e3 [autoreload] recompute urlresolver / urlrewriter after autoreload
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2670
diff changeset
   257
        self.set_url_rewriter()
2705
30bcdbd92820 [events] renamed source-reload into registry-reload to avoid potential confusions with datasources
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2694
diff changeset
   258
        CW_EVENT_MANAGER.bind('after-registry-reload', self.set_url_rewriter)
3606
8326aceecb46 fix startup as a daemon
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3558
diff changeset
   259
8326aceecb46 fix startup as a daemon
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3558
diff changeset
   260
    def start_service(self):
5325
f1c660e1169e [web] consistent cleanup session interval time
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5279
diff changeset
   261
        start_task(self.appli.session_handler.clean_sessions_interval,
f1c660e1169e [web] consistent cleanup session interval time
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5279
diff changeset
   262
                   self.appli.session_handler.clean_sessions)
1420
25c13e5b12bd stop complaining about empty response, remove trailing spaces
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   263
2685
0518ca8f63e3 [autoreload] recompute urlresolver / urlrewriter after autoreload
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2670
diff changeset
   264
    def set_url_rewriter(self):
2770
356e9d7c356d R propagate registry API changes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2711
diff changeset
   265
        self.url_rewriter = self.appli.vreg['components'].select_or_none('urlrewriter')
2685
0518ca8f63e3 [autoreload] recompute urlresolver / urlrewriter after autoreload
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2670
diff changeset
   266
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   267
    def shutdown_event(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   268
        """callback fired when the server is shutting down to properly
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   269
        clean opened sessions
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   270
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   271
        self.appli.repo.shutdown()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   272
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   273
    def pyro_loop_event(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   274
        """listen for pyro events"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   275
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   276
            self.pyro_daemon.handleRequests(self.pyro_listen_timeout)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   277
        except select.error:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   278
            return
1420
25c13e5b12bd stop complaining about empty response, remove trailing spaces
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   279
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   280
    def getChild(self, path, request):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   281
        """Indicate which resource to use to process down the URL's path"""
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   282
        return self
1420
25c13e5b12bd stop complaining about empty response, remove trailing spaces
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   283
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   284
    def render(self, request):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   285
        """Render a page from the root resource"""
3638
648d6dbec630 system/user modes + CWDEV instead of installed/dev mixed modes. Fix behaviour when setting CW_MODE explicitly
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3618
diff changeset
   286
        # reload modified files in debug mode
5442
3ed8afbbdf70 [webconfig] refactor/cleanup debug mode management on startup: simply use config.debugmode instead of debug argument everywhere...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   287
        if self.config.debugmode:
5445
4467ed43d97d [web] use uiprops value to compile css transparently, handlig cache and reloading in debug mode
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5442
diff changeset
   288
            self.config.uiprops.reload_if_needed()
5467
57372dbfd114 [https] fix resource urls in https version of a site: should use the https version as well to avoid warnings from the nrowser
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5445
diff changeset
   289
            if self.https_url:
57372dbfd114 [https] fix resource urls in https version of a site: should use the https version as well to avoid warnings from the nrowser
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5445
diff changeset
   290
                self.config.https_uiprops.reload_if_needed()
5273
c4caef6f09c9 [vreg] refactor the [re]loading process so things get clearer and fix spurious errors on edge cases
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5252
diff changeset
   291
            self.appli.vreg.reload_if_needed()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   292
        if self.config['profile']: # default profiler don't trace threads
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   293
            return self.render_request(request)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   294
        else:
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   295
            deferred = threads.deferToThread(self.render_request, request)
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   296
            return NOT_DONE_YET
1420
25c13e5b12bd stop complaining about empty response, remove trailing spaces
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   297
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   298
    def render_request(self, request):
5243
1ab7acb9abe9 [etwist] we must call all error not handled in _render_request, else the thread fail silently and nothing ends up on the ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5223
diff changeset
   299
        try:
5759
5db529e0a3ee imported patch asynchronous multipart parsing.diff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5660
diff changeset
   300
            # processing HUGE files (hundred of megabytes) in http.processReceived
5db529e0a3ee imported patch asynchronous multipart parsing.diff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5660
diff changeset
   301
            # blocks other HTTP requests processing
5db529e0a3ee imported patch asynchronous multipart parsing.diff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5660
diff changeset
   302
            # due to the clumsy & slow parsing algorithm of cgi.FieldStorage
5db529e0a3ee imported patch asynchronous multipart parsing.diff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5660
diff changeset
   303
            # so we deferred that part to the cubicweb thread
5db529e0a3ee imported patch asynchronous multipart parsing.diff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5660
diff changeset
   304
            request.process_multipart()
5243
1ab7acb9abe9 [etwist] we must call all error not handled in _render_request, else the thread fail silently and nothing ends up on the ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5223
diff changeset
   305
            return self._render_request(request)
1ab7acb9abe9 [etwist] we must call all error not handled in _render_request, else the thread fail silently and nothing ends up on the ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5223
diff changeset
   306
        except:
1ab7acb9abe9 [etwist] we must call all error not handled in _render_request, else the thread fail silently and nothing ends up on the ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5223
diff changeset
   307
            errorstream = StringIO()
1ab7acb9abe9 [etwist] we must call all error not handled in _render_request, else the thread fail silently and nothing ends up on the ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5223
diff changeset
   308
            traceback.print_exc(file=errorstream)
1ab7acb9abe9 [etwist] we must call all error not handled in _render_request, else the thread fail silently and nothing ends up on the ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5223
diff changeset
   309
            return HTTPResponse(stream='<pre>%s</pre>' % errorstream.getvalue(),
1ab7acb9abe9 [etwist] we must call all error not handled in _render_request, else the thread fail silently and nothing ends up on the ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5223
diff changeset
   310
                                code=500, twisted_request=request)
1ab7acb9abe9 [etwist] we must call all error not handled in _render_request, else the thread fail silently and nothing ends up on the ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5223
diff changeset
   311
1ab7acb9abe9 [etwist] we must call all error not handled in _render_request, else the thread fail silently and nothing ends up on the ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5223
diff changeset
   312
    def _render_request(self, request):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   313
        origpath = request.path
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   314
        host = request.host
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   315
        # dual http/https access handling: expect a rewrite rule to prepend
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   316
        # 'https' to the path to detect https access
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   317
        if origpath.split('/', 2)[1] == 'https':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   318
            origpath = origpath[6:]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   319
            request.uri = request.uri[6:]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   320
            https = True
1420
25c13e5b12bd stop complaining about empty response, remove trailing spaces
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   321
            baseurl = self.https_url or self.base_url
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   322
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   323
            https = False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   324
            baseurl = self.base_url
1520
b097057e629d provide an option to substitute the base-url (left-most part) subdomain by the one of the current http query to easy multiple subdomains website management
Florent <florent@secondweb.fr>
parents: 1420
diff changeset
   325
        if self.config['use-request-subdomain']:
1543
dca9817bb337 fix use-request-subdomain option behaviour and add tests
Florent <florent@secondweb.fr>
parents: 1542
diff changeset
   326
            baseurl = host_prefixed_baseurl(baseurl, host)
dca9817bb337 fix use-request-subdomain option behaviour and add tests
Florent <florent@secondweb.fr>
parents: 1542
diff changeset
   327
            self.warning('used baseurl is %s for this request', baseurl)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   328
        req = CubicWebTwistedRequestAdapter(request, self.appli.vreg, https, baseurl)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   329
        if req.authmode == 'http':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   330
            # activate realm-based auth
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   331
            realm = self.config['realm']
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   332
            req.set_header('WWW-Authenticate', [('Basic', {'realm' : realm })], raw=False)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   333
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   334
            self.appli.connect(req)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   335
        except Redirect, ex:
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   336
            return self.redirect(request=req, location=ex.location)
5223
6abd6e3599f4 #773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5216
diff changeset
   337
        if https and req.session.anonymous_session:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   338
            # don't allow anonymous on https connection
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   339
            return self.request_auth(request=req)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   340
        if self.url_rewriter is not None:
1115
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 151
diff changeset
   341
            # XXX should occur before authentication?
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   342
            try:
1936
c5af2fbda5b6 pass request to ApacheRewriter rewrite method
Florent <florent@secondweb.fr>
parents: 1543
diff changeset
   343
                path = self.url_rewriter.rewrite(host, origpath, req)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   344
            except Redirect, ex:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   345
                return self.redirect(req, ex.location)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   346
            request.uri.replace(origpath, path, 1)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   347
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   348
            path = origpath
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   349
        if not path or path == "/":
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   350
            path = 'view'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   351
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   352
            result = self.appli.publish(path, req)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   353
        except DirectResponse, ex:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   354
            return ex.response
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   355
        except StatusResponse, ex:
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   356
            return HTTPResponse(stream=ex.content, code=ex.status,
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   357
                                twisted_request=req._twreq,
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   358
                                headers=req.headers_out)
5223
6abd6e3599f4 #773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5216
diff changeset
   359
        except AuthenticationError:
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   360
            return self.request_auth(request=req)
5223
6abd6e3599f4 #773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5216
diff changeset
   361
        except LogOut, ex:
6abd6e3599f4 #773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5216
diff changeset
   362
            if self.config['auth-mode'] == 'cookie' and ex.url:
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   363
                return self.redirect(request=req, location=ex.url)
4911
898c35be5873 #750055: make it easier to change post logout url
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4909
diff changeset
   364
            # in http we have to request auth to flush current http auth
898c35be5873 #750055: make it easier to change post logout url
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4909
diff changeset
   365
            # information
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   366
            return self.request_auth(request=req, loggedout=True)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   367
        except Redirect, ex:
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   368
            return self.redirect(request=req, location=ex.location)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   369
        # request may be referenced by "onetime callback", so clear its entity
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   370
        # cache to avoid memory usage
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   371
        req.drop_entity_cache()
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   372
        return HTTPResponse(twisted_request=req._twreq, code=http.OK,
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   373
                            stream=result, headers=req.headers_out)
1420
25c13e5b12bd stop complaining about empty response, remove trailing spaces
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   374
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   375
    def redirect(self, request, location):
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   376
        self.debug('redirecting to %s', str(location))
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   377
        request.headers_out.setHeader('location', str(location))
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   378
        # 303 See other
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   379
        return HTTPResponse(twisted_request=request._twreq, code=303,
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   380
                            headers=request.headers_out)
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   381
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   382
    def request_auth(self, request, loggedout=False):
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   383
        if self.https_url and request.base_url() != self.https_url:
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   384
            return self.redirect(request, self.https_url + 'login')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   385
        if self.config['auth-mode'] == 'http':
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   386
            code = http.UNAUTHORIZED
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   387
        else:
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   388
            code = http.FORBIDDEN
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   389
        if loggedout:
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   390
            if request.https:
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   391
                request._base_url =  self.base_url
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   392
                request.https = False
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   393
            content = self.appli.loggedout_content(request)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   394
        else:
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   395
            content = self.appli.need_login_content(request)
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   396
        return HTTPResponse(twisted_request=request._twreq,
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   397
                            stream=content, code=code,
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   398
                            headers=request.headers_out)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   399
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   400
5335
9aed0b607130 [etwist] nicer, thouhg really not perferct) request max size exceeded support of json/frame posts
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5330
diff changeset
   401
JSON_PATHS = set(('json',))
9aed0b607130 [etwist] nicer, thouhg really not perferct) request max size exceeded support of json/frame posts
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5330
diff changeset
   402
FRAME_POST_PATHS = set(('validateform',))
1420
25c13e5b12bd stop complaining about empty response, remove trailing spaces
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   403
5270
6297d5265572 [etwist] allow to specify max size for POST request in the configuration. We should deal with this nicely on the js form validation code.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5243
diff changeset
   404
orig_gotLength = http.Request.gotLength
6297d5265572 [etwist] allow to specify max size for POST request in the configuration. We should deal with this nicely on the js form validation code.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5243
diff changeset
   405
@monkeypatch(http.Request)
6297d5265572 [etwist] allow to specify max size for POST request in the configuration. We should deal with this nicely on the js form validation code.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5243
diff changeset
   406
def gotLength(self, length):
6297d5265572 [etwist] allow to specify max size for POST request in the configuration. We should deal with this nicely on the js form validation code.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5243
diff changeset
   407
    orig_gotLength(self, length)
6297d5265572 [etwist] allow to specify max size for POST request in the configuration. We should deal with this nicely on the js form validation code.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5243
diff changeset
   408
    if length > MAX_POST_LENGTH: # length is 0 on GET
5335
9aed0b607130 [etwist] nicer, thouhg really not perferct) request max size exceeded support of json/frame posts
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5330
diff changeset
   409
        path = self.channel._path.split('?', 1)[0].rstrip('/').rsplit('/', 1)[-1]
5270
6297d5265572 [etwist] allow to specify max size for POST request in the configuration. We should deal with this nicely on the js form validation code.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5243
diff changeset
   410
        self.clientproto = 'HTTP/1.1' # not yet initialized
6297d5265572 [etwist] allow to specify max size for POST request in the configuration. We should deal with this nicely on the js form validation code.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5243
diff changeset
   411
        self.channel.persistent = 0   # force connection close on cleanup
6297d5265572 [etwist] allow to specify max size for POST request in the configuration. We should deal with this nicely on the js form validation code.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5243
diff changeset
   412
        self.setResponseCode(http.BAD_REQUEST)
5335
9aed0b607130 [etwist] nicer, thouhg really not perferct) request max size exceeded support of json/frame posts
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5330
diff changeset
   413
        if path in JSON_PATHS: # XXX better json path detection
9aed0b607130 [etwist] nicer, thouhg really not perferct) request max size exceeded support of json/frame posts
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5330
diff changeset
   414
            self.setHeader('content-type',"application/json")
5940
0e3ae19b181a [uilib] refactor json_dumps code organization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5933
diff changeset
   415
            body = json_dumps({'reason': 'request max size exceeded'})
5335
9aed0b607130 [etwist] nicer, thouhg really not perferct) request max size exceeded support of json/frame posts
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5330
diff changeset
   416
        elif path in FRAME_POST_PATHS: # XXX better frame post path detection
9aed0b607130 [etwist] nicer, thouhg really not perferct) request max size exceeded support of json/frame posts
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5330
diff changeset
   417
            self.setHeader('content-type',"text/html")
9aed0b607130 [etwist] nicer, thouhg really not perferct) request max size exceeded support of json/frame posts
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5330
diff changeset
   418
            body = ('<script type="text/javascript">'
9aed0b607130 [etwist] nicer, thouhg really not perferct) request max size exceeded support of json/frame posts
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5330
diff changeset
   419
                    'window.parent.handleFormValidationResponse(null, null, null, %s, null);'
5940
0e3ae19b181a [uilib] refactor json_dumps code organization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5933
diff changeset
   420
                    '</script>' % json_dumps( (False, 'request max size exceeded', None) ))
5335
9aed0b607130 [etwist] nicer, thouhg really not perferct) request max size exceeded support of json/frame posts
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5330
diff changeset
   421
        else:
9aed0b607130 [etwist] nicer, thouhg really not perferct) request max size exceeded support of json/frame posts
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5330
diff changeset
   422
            self.setHeader('content-type',"text/html")
9aed0b607130 [etwist] nicer, thouhg really not perferct) request max size exceeded support of json/frame posts
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5330
diff changeset
   423
            body = ("<html><head><title>Processing Failed</title></head><body>"
9aed0b607130 [etwist] nicer, thouhg really not perferct) request max size exceeded support of json/frame posts
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5330
diff changeset
   424
                    "<b>request max size exceeded</b></body></html>")
5270
6297d5265572 [etwist] allow to specify max size for POST request in the configuration. We should deal with this nicely on the js form validation code.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5243
diff changeset
   425
        self.setHeader('content-length', str(len(body)))
6297d5265572 [etwist] allow to specify max size for POST request in the configuration. We should deal with this nicely on the js form validation code.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5243
diff changeset
   426
        self.write(body)
6297d5265572 [etwist] allow to specify max size for POST request in the configuration. We should deal with this nicely on the js form validation code.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5243
diff changeset
   427
        # see request.finish(). Done here since we get error due to not full
6297d5265572 [etwist] allow to specify max size for POST request in the configuration. We should deal with this nicely on the js form validation code.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5243
diff changeset
   428
        # initialized request
6297d5265572 [etwist] allow to specify max size for POST request in the configuration. We should deal with this nicely on the js form validation code.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5243
diff changeset
   429
        self.finished = 1
6297d5265572 [etwist] allow to specify max size for POST request in the configuration. We should deal with this nicely on the js form validation code.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5243
diff changeset
   430
        if not self.queued:
6297d5265572 [etwist] allow to specify max size for POST request in the configuration. We should deal with this nicely on the js form validation code.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5243
diff changeset
   431
            self._cleanup()
6297d5265572 [etwist] allow to specify max size for POST request in the configuration. We should deal with this nicely on the js form validation code.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5243
diff changeset
   432
        for d in self.notifications:
6297d5265572 [etwist] allow to specify max size for POST request in the configuration. We should deal with this nicely on the js form validation code.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5243
diff changeset
   433
            d.callback(None)
6297d5265572 [etwist] allow to specify max size for POST request in the configuration. We should deal with this nicely on the js form validation code.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5243
diff changeset
   434
        self.notifications = []
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   435
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   436
@monkeypatch(http.Request)
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   437
def requestReceived(self, command, path, version):
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   438
    """Called by channel when all data has been received.
1420
25c13e5b12bd stop complaining about empty response, remove trailing spaces
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   439
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   440
    This method is not intended for users.
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   441
    """
5272
f7d2df59231a cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5270
diff changeset
   442
    self.content.seek(0, 0)
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   443
    self.args = {}
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   444
    self.files = {}
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   445
    self.stack = []
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   446
    self.method, self.uri = command, path
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   447
    self.clientproto = version
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   448
    x = self.uri.split('?', 1)
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   449
    if len(x) == 1:
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   450
        self.path = self.uri
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   451
    else:
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   452
        self.path, argstring = x
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   453
        self.args = http.parse_qs(argstring, 1)
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   454
    # cache the client and server information, we'll need this later to be
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   455
    # serialized and sent with the request so CGIs will work remotely
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   456
    self.client = self.channel.transport.getPeer()
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   457
    self.host = self.channel.transport.getHost()
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   458
    # Argument processing
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   459
    ctype = self.getHeader('content-type')
5759
5db529e0a3ee imported patch asynchronous multipart parsing.diff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5660
diff changeset
   460
    self._do_process_multipart = False
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   461
    if self.method == "POST" and ctype:
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   462
        key, pdict = parse_header(ctype)
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   463
        if key == 'application/x-www-form-urlencoded':
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   464
            self.args.update(http.parse_qs(self.content.read(), 1))
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   465
        elif key == 'multipart/form-data':
5759
5db529e0a3ee imported patch asynchronous multipart parsing.diff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5660
diff changeset
   466
            # defer this as it can be extremely time consumming
5db529e0a3ee imported patch asynchronous multipart parsing.diff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5660
diff changeset
   467
            # with big files
5db529e0a3ee imported patch asynchronous multipart parsing.diff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5660
diff changeset
   468
            self._do_process_multipart = True
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   469
    self.process()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   470
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   471
5759
5db529e0a3ee imported patch asynchronous multipart parsing.diff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5660
diff changeset
   472
@monkeypatch(http.Request)
5db529e0a3ee imported patch asynchronous multipart parsing.diff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5660
diff changeset
   473
def process_multipart(self):
5db529e0a3ee imported patch asynchronous multipart parsing.diff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5660
diff changeset
   474
    if not self._do_process_multipart:
5db529e0a3ee imported patch asynchronous multipart parsing.diff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5660
diff changeset
   475
        return
5db529e0a3ee imported patch asynchronous multipart parsing.diff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5660
diff changeset
   476
    form = FieldStorage(self.content, self.received_headers,
5db529e0a3ee imported patch asynchronous multipart parsing.diff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5660
diff changeset
   477
                        environ={'REQUEST_METHOD': 'POST'},
5db529e0a3ee imported patch asynchronous multipart parsing.diff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5660
diff changeset
   478
                        keep_blank_values=1,
5db529e0a3ee imported patch asynchronous multipart parsing.diff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5660
diff changeset
   479
                        strict_parsing=1)
5db529e0a3ee imported patch asynchronous multipart parsing.diff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5660
diff changeset
   480
    for key in form:
5db529e0a3ee imported patch asynchronous multipart parsing.diff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5660
diff changeset
   481
        value = form[key]
5db529e0a3ee imported patch asynchronous multipart parsing.diff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5660
diff changeset
   482
        if isinstance(value, list):
5db529e0a3ee imported patch asynchronous multipart parsing.diff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5660
diff changeset
   483
            self.args[key] = [v.value for v in value]
5db529e0a3ee imported patch asynchronous multipart parsing.diff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5660
diff changeset
   484
        elif value.filename:
5db529e0a3ee imported patch asynchronous multipart parsing.diff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5660
diff changeset
   485
            if value.done != -1: # -1 is transfer has been interrupted
5db529e0a3ee imported patch asynchronous multipart parsing.diff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5660
diff changeset
   486
                self.files[key] = (value.filename, value.file)
5db529e0a3ee imported patch asynchronous multipart parsing.diff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5660
diff changeset
   487
            else:
5db529e0a3ee imported patch asynchronous multipart parsing.diff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5660
diff changeset
   488
                self.files[key] = (None, None)
5db529e0a3ee imported patch asynchronous multipart parsing.diff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5660
diff changeset
   489
        else:
5db529e0a3ee imported patch asynchronous multipart parsing.diff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5660
diff changeset
   490
            self.args[key] = value.value
5db529e0a3ee imported patch asynchronous multipart parsing.diff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5660
diff changeset
   491
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   492
from logging import getLogger
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   493
from cubicweb import set_log_methods
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   494
LOGGER = getLogger('cubicweb.twisted')
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   495
set_log_methods(CubicWebRootResource, LOGGER)
2654
6512522860aa [twisted] don't use twistd anymore, all-in-one.py file is needed anymore
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2476
diff changeset
   496
5653
c562791df9d2 [web server] vregistry may now be passed as named argument in CubicWebRootResource constructor
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5555
diff changeset
   497
def run(config, vreg=None, debug=None):
c562791df9d2 [web server] vregistry may now be passed as named argument in CubicWebRootResource constructor
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5555
diff changeset
   498
    if debug is not None:
c562791df9d2 [web server] vregistry may now be passed as named argument in CubicWebRootResource constructor
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5555
diff changeset
   499
        config.debugmode = debug
5933
3d707b8f8a4d [web configuration] ensure data home directory / uicache file belong to daemon user and are writeable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5907
diff changeset
   500
    config.check_writeable_uid_directory(config.appdatahome)
2654
6512522860aa [twisted] don't use twistd anymore, all-in-one.py file is needed anymore
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2476
diff changeset
   501
    # create the site
5653
c562791df9d2 [web server] vregistry may now be passed as named argument in CubicWebRootResource constructor
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5555
diff changeset
   502
    root_resource = CubicWebRootResource(config, vreg=vreg)
2654
6512522860aa [twisted] don't use twistd anymore, all-in-one.py file is needed anymore
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2476
diff changeset
   503
    website = server.Site(root_resource)
6512522860aa [twisted] don't use twistd anymore, all-in-one.py file is needed anymore
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2476
diff changeset
   504
    # serve it via standard HTTP on port set in the configuration
6512522860aa [twisted] don't use twistd anymore, all-in-one.py file is needed anymore
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2476
diff changeset
   505
    port = config['port'] or 8080
6817
1959d97ebf2e [etwist] add an 'interface' config option (passed to reactor.listenTCP)
david.douard@logilab.fr
parents: 6779
diff changeset
   506
    interface = config['interface']
1959d97ebf2e [etwist] add an 'interface' config option (passed to reactor.listenTCP)
david.douard@logilab.fr
parents: 6779
diff changeset
   507
    reactor.listenTCP(port, website, interface=interface)
5442
3ed8afbbdf70 [webconfig] refactor/cleanup debug mode management on startup: simply use config.debugmode instead of debug argument everywhere...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   508
    if not config.debugmode:
4219
87203a0a3a81 do not attempt to daemonize under windows
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4212
diff changeset
   509
        if sys.platform == 'win32':
4221
da84ca26896d raising ConfigurationError is cleaner; remove some unused imports
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4219
diff changeset
   510
            raise ConfigurationError("Under windows, you must use the service management "
da84ca26896d raising ConfigurationError is cleaner; remove some unused imports
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4219
diff changeset
   511
                                     "commands (e.g : 'net start my_instance)'")
5659
755f56f01c9d [win32] defer import of logilab.common.daemon
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5553
diff changeset
   512
        from logilab.common.daemon import daemonize
5679
0f2ded880d01 backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5655 5660
diff changeset
   513
        LOGGER.info('instance started in the background on %s', root_resource.base_url)
6779
accf5978a440 [daemon] make process umask configurable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6778
diff changeset
   514
        whichproc = daemonize(config['pid-file'], umask=config['umask'])
6778
7dd4835d5198 properly tell we've started an instance (close #1391262)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5940
diff changeset
   515
        if whichproc: # 1 = orig process, 2 = first fork, None = second fork (eg daemon process)
7dd4835d5198 properly tell we've started an instance (close #1391262)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5940
diff changeset
   516
            return whichproc # parent process
3606
8326aceecb46 fix startup as a daemon
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3558
diff changeset
   517
    root_resource.init_publisher() # before changing uid
3193
c1a8456cb5f9 should change process'user once pid file has been written
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3181
diff changeset
   518
    if config['uid'] is not None:
c1a8456cb5f9 should change process'user once pid file has been written
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3181
diff changeset
   519
        try:
c1a8456cb5f9 should change process'user once pid file has been written
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3181
diff changeset
   520
            uid = int(config['uid'])
c1a8456cb5f9 should change process'user once pid file has been written
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3181
diff changeset
   521
        except ValueError:
c1a8456cb5f9 should change process'user once pid file has been written
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3181
diff changeset
   522
            from pwd import getpwnam
c1a8456cb5f9 should change process'user once pid file has been written
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3181
diff changeset
   523
            uid = getpwnam(config['uid']).pw_uid
c1a8456cb5f9 should change process'user once pid file has been written
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3181
diff changeset
   524
        os.setuid(uid)
3606
8326aceecb46 fix startup as a daemon
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3558
diff changeset
   525
    root_resource.start_service()
5679
0f2ded880d01 backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5655 5660
diff changeset
   526
    LOGGER.info('instance started on %s', root_resource.base_url)
5652
904091dc4c7e [etwist] twisted won't install signal handler outside the main thread.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 5553
diff changeset
   527
    # avoid annoying warnign if not in Main Thread
904091dc4c7e [etwist] twisted won't install signal handler outside the main thread.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 5553
diff changeset
   528
    signals = threading.currentThread().getName() == 'MainThread'
2654
6512522860aa [twisted] don't use twistd anymore, all-in-one.py file is needed anymore
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2476
diff changeset
   529
    if config['profile']:
4960
26b2468a1e73 [etwist] cleanup, use cProfile instead of hotshot
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4914
diff changeset
   530
        import cProfile
5652
904091dc4c7e [etwist] twisted won't install signal handler outside the main thread.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 5553
diff changeset
   531
        cProfile.runctx('reactor.run(installSignalHandlers=%s)' % signals,
904091dc4c7e [etwist] twisted won't install signal handler outside the main thread.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 5553
diff changeset
   532
                        globals(), locals(), config['profile'])
2654
6512522860aa [twisted] don't use twistd anymore, all-in-one.py file is needed anymore
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2476
diff changeset
   533
    else:
5652
904091dc4c7e [etwist] twisted won't install signal handler outside the main thread.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 5553
diff changeset
   534
        reactor.run(installSignalHandlers=signals)