etwist/server.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 29 Apr 2010 14:21:57 +0200
changeset 5442 3ed8afbbdf70
parent 5426 0d4853a6e5ee
child 5445 4467ed43d97d
permissions -rw-r--r--
[webconfig] refactor/cleanup debug mode management on startup: simply use config.debugmode instead of debug argument everywhere...
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
     1
# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
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/>.
2476
1294a6bdf3bf application -> instance where it makes sense
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2181
diff changeset
    18
"""twisted server for CubicWeb web instances
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    20
"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    21
__docformat__ = "restructuredtext en"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    22
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    23
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
    24
import os
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    25
import select
4398
4e7e74918631 add missing errno import in etwist/server.py
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4221
diff changeset
    26
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
    27
import traceback
5216
4f4369e63f5e [twisted] fix LongTimeExpiringFile and getChild implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5155
diff changeset
    28
from os.path import join
1016
26387b836099 use datetime instead of mx.DateTime
sylvain.thenault@logilab.fr
parents: 151
diff changeset
    29
from time import mktime
26387b836099 use datetime instead of mx.DateTime
sylvain.thenault@logilab.fr
parents: 151
diff changeset
    30
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
    31
from urlparse import urlsplit, urlunsplit
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    32
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
    33
from cStringIO import StringIO
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    34
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    35
from twisted.internet import reactor, task, threads
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    36
from twisted.internet.defer import maybeDeferred
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    37
from twisted.web import http, server
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    38
from twisted.web import static, resource
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    39
from twisted.web.server import NOT_DONE_YET
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    40
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
    41
from simplejson import dumps
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    42
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    43
from logilab.common.decorators import monkeypatch
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    44
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
    45
from cubicweb import AuthenticationError, ConfigurationError, CW_EVENT_MANAGER
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
    46
from cubicweb.web import Redirect, DirectResponse, StatusResponse, LogOut
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    47
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
    48
from cubicweb.web.http_headers import generateDateTime
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    49
from cubicweb.etwist.request import CubicWebTwistedRequestAdapter
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    50
from cubicweb.etwist.http import HTTPResponse
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    51
3193
c1a8456cb5f9 should change process'user once pid file has been written
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3181
diff changeset
    52
def daemonize():
3181
735c5f9fcded fix daemonize: set umask, move to /, consider uid
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2711
diff changeset
    53
    # XXX unix specific
735c5f9fcded fix daemonize: set umask, move to /, consider uid
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2711
diff changeset
    54
    # XXX factorize w/ code in cw.server.server and cw.server.serverctl
735c5f9fcded fix daemonize: set umask, move to /, consider uid
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2711
diff changeset
    55
    # (start-repository command)
735c5f9fcded fix daemonize: set umask, move to /, consider uid
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2711
diff changeset
    56
    # See http://www.erlenstar.demon.co.uk/unix/faq_toc.html#TOC16
735c5f9fcded fix daemonize: set umask, move to /, consider uid
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2711
diff changeset
    57
    if os.fork():   # launch child and...
3606
8326aceecb46 fix startup as a daemon
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3558
diff changeset
    58
        return 1
3181
735c5f9fcded fix daemonize: set umask, move to /, consider uid
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2711
diff changeset
    59
    os.setsid()
3606
8326aceecb46 fix startup as a daemon
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3558
diff changeset
    60
    if os.fork():   # launch child again.
8326aceecb46 fix startup as a daemon
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3558
diff changeset
    61
        return 1
3181
735c5f9fcded fix daemonize: set umask, move to /, consider uid
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2711
diff changeset
    62
    # move to the root to avoit mount pb
735c5f9fcded fix daemonize: set umask, move to /, consider uid
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2711
diff changeset
    63
    os.chdir('/')
735c5f9fcded fix daemonize: set umask, move to /, consider uid
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2711
diff changeset
    64
    # set paranoid umask
735c5f9fcded fix daemonize: set umask, move to /, consider uid
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2711
diff changeset
    65
    os.umask(077)
735c5f9fcded fix daemonize: set umask, move to /, consider uid
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2711
diff changeset
    66
    null = os.open('/dev/null', os.O_RDWR)
735c5f9fcded fix daemonize: set umask, move to /, consider uid
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2711
diff changeset
    67
    for i in range(3):
735c5f9fcded fix daemonize: set umask, move to /, consider uid
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2711
diff changeset
    68
        try:
735c5f9fcded fix daemonize: set umask, move to /, consider uid
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2711
diff changeset
    69
            os.dup2(null, i)
735c5f9fcded fix daemonize: set umask, move to /, consider uid
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2711
diff changeset
    70
        except OSError, e:
735c5f9fcded fix daemonize: set umask, move to /, consider uid
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2711
diff changeset
    71
            if e.errno != errno.EBADF:
735c5f9fcded fix daemonize: set umask, move to /, consider uid
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2711
diff changeset
    72
                raise
735c5f9fcded fix daemonize: set umask, move to /, consider uid
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2711
diff changeset
    73
    os.close(null)
735c5f9fcded fix daemonize: set umask, move to /, consider uid
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2711
diff changeset
    74
    return None
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    75
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    76
def start_task(interval, func):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    77
    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
    78
    # 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
    79
    # 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
    80
    lc.start(interval, now=False)
1420
25c13e5b12bd stop complaining about empty response, remove trailing spaces
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
    81
1543
dca9817bb337 fix use-request-subdomain option behaviour and add tests
Florent <florent@secondweb.fr>
parents: 1542
diff changeset
    82
def host_prefixed_baseurl(baseurl, host):
dca9817bb337 fix use-request-subdomain option behaviour and add tests
Florent <florent@secondweb.fr>
parents: 1542
diff changeset
    83
    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
    84
    netloc_domain = '.' + '.'.join(netloc.split('.')[-2:])
dca9817bb337 fix use-request-subdomain option behaviour and add tests
Florent <florent@secondweb.fr>
parents: 1542
diff changeset
    85
    if host.endswith(netloc_domain):
dca9817bb337 fix use-request-subdomain option behaviour and add tests
Florent <florent@secondweb.fr>
parents: 1542
diff changeset
    86
        netloc = host
dca9817bb337 fix use-request-subdomain option behaviour and add tests
Florent <florent@secondweb.fr>
parents: 1542
diff changeset
    87
    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
    88
    return baseurl
dca9817bb337 fix use-request-subdomain option behaviour and add tests
Florent <florent@secondweb.fr>
parents: 1542
diff changeset
    89
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    90
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    91
class ForbiddenDirectoryLister(resource.Resource):
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    92
    def render(self, request):
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    93
        return HTTPResponse(twisted_request=request,
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    94
                            code=http.FORBIDDEN,
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    95
                            stream='Access forbidden')
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    96
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    97
class File(static.File):
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    98
    """Prevent from listing directories"""
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
    99
    def directoryListing(self):
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   100
        return ForbiddenDirectoryLister()
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   101
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   102
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   103
class LongTimeExpiringFile(File):
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   104
    """overrides static.File and sets a far future ``Expires`` date
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   105
    on the resouce.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   106
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   107
    versions handling is done by serving static files by different
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   108
    URLs for each version. For instance::
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   109
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   110
      http://localhost:8080/data-2.48.2/cubicweb.css
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   111
      http://localhost:8080/data-2.49.0/cubicweb.css
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   112
      etc.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   113
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   114
    """
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   115
    def render(self, request):
5216
4f4369e63f5e [twisted] fix LongTimeExpiringFile and getChild implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5155
diff changeset
   116
        # 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
   117
        #
4f4369e63f5e [twisted] fix LongTimeExpiringFile and getChild implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5155
diff changeset
   118
        # 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
   119
        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
   120
        request.setHeader('Expires', generateDateTime(mktime(expires.timetuple())))
4f4369e63f5e [twisted] fix LongTimeExpiringFile and getChild implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5155
diff changeset
   121
        return File.render(self, request)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   122
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   123
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   124
class CubicWebRootResource(resource.Resource):
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
   125
    def __init__(self, config):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   126
        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
   127
        # 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
   128
        # checks done before daemonization (eg versions consistency)
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
   129
        self.appli = CubicWebPublisher(config)
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
   130
        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
   131
        self.https_url = config['https-url']
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   132
        self.children = {}
5216
4f4369e63f5e [twisted] fix LongTimeExpiringFile and getChild implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5155
diff changeset
   133
        self.static_directories = set(('data%s' % config.instance_md5_version(),
4f4369e63f5e [twisted] fix LongTimeExpiringFile and getChild implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5155
diff changeset
   134
                                       'data', 'static', 'fckeditor'))
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
   135
        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
   136
        MAX_POST_LENGTH = config['max-post-length']
3606
8326aceecb46 fix startup as a daemon
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3558
diff changeset
   137
8326aceecb46 fix startup as a daemon
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3558
diff changeset
   138
    def init_publisher(self):
8326aceecb46 fix startup as a daemon
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3558
diff changeset
   139
        config = self.config
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   140
        # when we have an in-memory repository, clean unused sessions every XX
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   141
        # seconds and properly shutdown the server
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   142
        if config.repo_method == 'inmemory':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   143
            reactor.addSystemEventTrigger('before', 'shutdown',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   144
                                          self.shutdown_event)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   145
            if config.pyro_enabled():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   146
                # if pyro is enabled, we have to register to the pyro name
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   147
                # server, create a pyro daemon, and create a task to handle pyro
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   148
                # requests
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   149
                self.pyro_daemon = self.appli.repo.pyro_register()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   150
                self.pyro_listen_timeout = 0.02
3502
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3493
diff changeset
   151
                self.appli.repo.looping_task(1, self.pyro_loop_event)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   152
            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
   153
        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
   154
        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
   155
8326aceecb46 fix startup as a daemon
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3558
diff changeset
   156
    def start_service(self):
5325
f1c660e1169e [web] consistent cleanup session interval time
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5279
diff changeset
   157
        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
   158
                   self.appli.session_handler.clean_sessions)
1420
25c13e5b12bd stop complaining about empty response, remove trailing spaces
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   159
2685
0518ca8f63e3 [autoreload] recompute urlresolver / urlrewriter after autoreload
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2670
diff changeset
   160
    def set_url_rewriter(self):
2770
356e9d7c356d R propagate registry API changes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2711
diff changeset
   161
        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
   162
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   163
    def shutdown_event(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   164
        """callback fired when the server is shutting down to properly
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   165
        clean opened sessions
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   166
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   167
        self.appli.repo.shutdown()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   168
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   169
    def pyro_loop_event(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   170
        """listen for pyro events"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   171
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   172
            self.pyro_daemon.handleRequests(self.pyro_listen_timeout)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   173
        except select.error:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   174
            return
1420
25c13e5b12bd stop complaining about empty response, remove trailing spaces
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   175
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   176
    def getChild(self, path, request):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   177
        """Indicate which resource to use to process down the URL's path"""
5216
4f4369e63f5e [twisted] fix LongTimeExpiringFile and getChild implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5155
diff changeset
   178
        pre_path = request.path.split('/')[1:]
4f4369e63f5e [twisted] fix LongTimeExpiringFile and getChild implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5155
diff changeset
   179
        if pre_path[0] == 'https':
4f4369e63f5e [twisted] fix LongTimeExpiringFile and getChild implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5155
diff changeset
   180
            pre_path.pop(0)
4f4369e63f5e [twisted] fix LongTimeExpiringFile and getChild implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5155
diff changeset
   181
        directory = pre_path[0]
4f4369e63f5e [twisted] fix LongTimeExpiringFile and getChild implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5155
diff changeset
   182
        # Anything in data/, static/, fckeditor/ and the generated versioned
4f4369e63f5e [twisted] fix LongTimeExpiringFile and getChild implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5155
diff changeset
   183
        # data directory is treated as static files
4f4369e63f5e [twisted] fix LongTimeExpiringFile and getChild implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5155
diff changeset
   184
        if directory in self.static_directories:
5337
c3a037550e1f [etwist] proper getChild implementation (eventually): fix fckeditor resources locating bugs by properly using file resources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5335
diff changeset
   185
            # take care fckeditor may appears as root directory or as a data
c3a037550e1f [etwist] proper getChild implementation (eventually): fix fckeditor resources locating bugs by properly using file resources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5335
diff changeset
   186
            # subdirectory
c3a037550e1f [etwist] proper getChild implementation (eventually): fix fckeditor resources locating bugs by properly using file resources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5335
diff changeset
   187
            if directory == 'static':
c3a037550e1f [etwist] proper getChild implementation (eventually): fix fckeditor resources locating bugs by properly using file resources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5335
diff changeset
   188
                return File(self.config.static_directory)
c3a037550e1f [etwist] proper getChild implementation (eventually): fix fckeditor resources locating bugs by properly using file resources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5335
diff changeset
   189
            if directory == 'fckeditor':
c3a037550e1f [etwist] proper getChild implementation (eventually): fix fckeditor resources locating bugs by properly using file resources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5335
diff changeset
   190
                return File(self.config.ext_resources['FCKEDITOR_PATH'])
c3a037550e1f [etwist] proper getChild implementation (eventually): fix fckeditor resources locating bugs by properly using file resources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5335
diff changeset
   191
            if directory != 'data':
c3a037550e1f [etwist] proper getChild implementation (eventually): fix fckeditor resources locating bugs by properly using file resources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5335
diff changeset
   192
                # versioned directory, use specific file with http cache
c3a037550e1f [etwist] proper getChild implementation (eventually): fix fckeditor resources locating bugs by properly using file resources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5335
diff changeset
   193
                # headers so their are cached for a very long time
c3a037550e1f [etwist] proper getChild implementation (eventually): fix fckeditor resources locating bugs by properly using file resources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5335
diff changeset
   194
                cls = LongTimeExpiringFile
c3a037550e1f [etwist] proper getChild implementation (eventually): fix fckeditor resources locating bugs by properly using file resources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5335
diff changeset
   195
            else:
c3a037550e1f [etwist] proper getChild implementation (eventually): fix fckeditor resources locating bugs by properly using file resources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5335
diff changeset
   196
                cls = File
c3a037550e1f [etwist] proper getChild implementation (eventually): fix fckeditor resources locating bugs by properly using file resources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5335
diff changeset
   197
            if path == 'fckeditor':
c3a037550e1f [etwist] proper getChild implementation (eventually): fix fckeditor resources locating bugs by properly using file resources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5335
diff changeset
   198
                return cls(self.config.ext_resources['FCKEDITOR_PATH'])
5216
4f4369e63f5e [twisted] fix LongTimeExpiringFile and getChild implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5155
diff changeset
   199
            if path == directory: # recurse
4f4369e63f5e [twisted] fix LongTimeExpiringFile and getChild implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5155
diff changeset
   200
                return self
5337
c3a037550e1f [etwist] proper getChild implementation (eventually): fix fckeditor resources locating bugs by properly using file resources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5335
diff changeset
   201
            datadir = self.config.locate_resource(path)
c3a037550e1f [etwist] proper getChild implementation (eventually): fix fckeditor resources locating bugs by properly using file resources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5335
diff changeset
   202
            if datadir is None:
c3a037550e1f [etwist] proper getChild implementation (eventually): fix fckeditor resources locating bugs by properly using file resources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5335
diff changeset
   203
                return self # recurse
5216
4f4369e63f5e [twisted] fix LongTimeExpiringFile and getChild implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5155
diff changeset
   204
            self.debug('static file %s from %s', path, datadir)
4f4369e63f5e [twisted] fix LongTimeExpiringFile and getChild implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5155
diff changeset
   205
            return cls(join(datadir, path))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   206
        # Otherwise we use this single resource
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   207
        return self
1420
25c13e5b12bd stop complaining about empty response, remove trailing spaces
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   208
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   209
    def render(self, request):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   210
        """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
   211
        # 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
   212
        if self.config.debugmode:
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
   213
            self.appli.vreg.reload_if_needed()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   214
        if self.config['profile']: # default profiler don't trace threads
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   215
            return self.render_request(request)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   216
        else:
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   217
            deferred = threads.deferToThread(self.render_request, request)
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   218
            return NOT_DONE_YET
1420
25c13e5b12bd stop complaining about empty response, remove trailing spaces
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   219
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   220
    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
   221
        try:
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
   222
            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
   223
        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
   224
            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
   225
            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
   226
            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
   227
                                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
   228
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
   229
    def _render_request(self, request):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   230
        origpath = request.path
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   231
        host = request.host
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   232
        # dual http/https access handling: expect a rewrite rule to prepend
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   233
        # 'https' to the path to detect https access
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   234
        if origpath.split('/', 2)[1] == 'https':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   235
            origpath = origpath[6:]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   236
            request.uri = request.uri[6:]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   237
            https = True
1420
25c13e5b12bd stop complaining about empty response, remove trailing spaces
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   238
            baseurl = self.https_url or self.base_url
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   239
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   240
            https = False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   241
            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
   242
        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
   243
            baseurl = host_prefixed_baseurl(baseurl, host)
dca9817bb337 fix use-request-subdomain option behaviour and add tests
Florent <florent@secondweb.fr>
parents: 1542
diff changeset
   244
            self.warning('used baseurl is %s for this request', baseurl)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   245
        req = CubicWebTwistedRequestAdapter(request, self.appli.vreg, https, baseurl)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   246
        if req.authmode == 'http':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   247
            # activate realm-based auth
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   248
            realm = self.config['realm']
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   249
            req.set_header('WWW-Authenticate', [('Basic', {'realm' : realm })], raw=False)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   250
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   251
            self.appli.connect(req)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   252
        except Redirect, ex:
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   253
            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
   254
        if https and req.session.anonymous_session:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   255
            # don't allow anonymous on https connection
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   256
            return self.request_auth(request=req)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   257
        if self.url_rewriter is not None:
1115
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 151
diff changeset
   258
            # XXX should occur before authentication?
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   259
            try:
1936
c5af2fbda5b6 pass request to ApacheRewriter rewrite method
Florent <florent@secondweb.fr>
parents: 1543
diff changeset
   260
                path = self.url_rewriter.rewrite(host, origpath, req)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   261
            except Redirect, ex:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   262
                return self.redirect(req, ex.location)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   263
            request.uri.replace(origpath, path, 1)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   264
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   265
            path = origpath
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   266
        if not path or path == "/":
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   267
            path = 'view'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   268
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   269
            result = self.appli.publish(path, req)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   270
        except DirectResponse, ex:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   271
            return ex.response
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   272
        except StatusResponse, ex:
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   273
            return HTTPResponse(stream=ex.content, code=ex.status,
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   274
                                twisted_request=req._twreq,
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   275
                                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
   276
        except AuthenticationError:
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   277
            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
   278
        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
   279
            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
   280
                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
   281
            # 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
   282
            # information
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   283
            return self.request_auth(request=req, loggedout=True)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   284
        except Redirect, ex:
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   285
            return self.redirect(request=req, location=ex.location)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   286
        # request may be referenced by "onetime callback", so clear its entity
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   287
        # cache to avoid memory usage
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   288
        req.drop_entity_cache()
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   289
        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
   290
                            stream=result, headers=req.headers_out)
1420
25c13e5b12bd stop complaining about empty response, remove trailing spaces
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   291
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   292
    def redirect(self, request, location):
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   293
        self.debug('redirecting to %s', str(location))
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   294
        request.headers_out.setHeader('location', str(location))
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   295
        # 303 See other
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   296
        return HTTPResponse(twisted_request=request._twreq, code=303,
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   297
                            headers=request.headers_out)
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   298
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   299
    def request_auth(self, request, loggedout=False):
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   300
        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
   301
            return self.redirect(request, self.https_url + 'login')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   302
        if self.config['auth-mode'] == 'http':
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   303
            code = http.UNAUTHORIZED
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   304
        else:
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   305
            code = http.FORBIDDEN
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   306
        if loggedout:
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   307
            if request.https:
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   308
                request._base_url =  self.base_url
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   309
                request.https = False
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   310
            content = self.appli.loggedout_content(request)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   311
        else:
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   312
            content = self.appli.need_login_content(request)
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   313
        return HTTPResponse(twisted_request=request._twreq,
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   314
                            stream=content, code=code,
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   315
                            headers=request.headers_out)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   316
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   317
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
   318
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
   319
FRAME_POST_PATHS = set(('validateform',))
1420
25c13e5b12bd stop complaining about empty response, remove trailing spaces
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   320
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
   321
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
   322
@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
   323
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
   324
    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
   325
    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
   326
        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
   327
        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
   328
        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
   329
        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
   330
        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
   331
            self.setHeader('content-type',"application/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
   332
            body = dumps({'reason': 'request max size exceeded'})
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
   333
        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
   334
            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
   335
            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
   336
                    'window.parent.handleFormValidationResponse(null, null, null, %s, null);'
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
   337
                    '</script>' % dumps( (False, 'request max size exceeded', None) ))
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
   338
        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
   339
            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
   340
            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
   341
                    "<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
   342
        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
   343
        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
   344
        # 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
   345
        # 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
   346
        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
   347
        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
   348
            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
   349
        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
   350
            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
   351
        self.notifications = []
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   352
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   353
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   354
@monkeypatch(http.Request)
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   355
def requestReceived(self, command, path, version):
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   356
    """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
   357
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   358
    This method is not intended for users.
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   359
    """
5272
f7d2df59231a cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5270
diff changeset
   360
    self.content.seek(0, 0)
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   361
    self.args = {}
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   362
    self.files = {}
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   363
    self.stack = []
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   364
    self.method, self.uri = command, path
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   365
    self.clientproto = version
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   366
    x = self.uri.split('?', 1)
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   367
    if len(x) == 1:
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   368
        self.path = self.uri
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   369
    else:
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   370
        self.path, argstring = x
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   371
        self.args = http.parse_qs(argstring, 1)
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   372
    # 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
   373
    # 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
   374
    self.client = self.channel.transport.getPeer()
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   375
    self.host = self.channel.transport.getHost()
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   376
    # Argument processing
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   377
    ctype = self.getHeader('content-type')
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   378
    if self.method == "POST" and ctype:
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   379
        key, pdict = parse_header(ctype)
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   380
        if key == 'application/x-www-form-urlencoded':
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   381
            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
   382
        elif key == 'multipart/form-data':
5272
f7d2df59231a cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5270
diff changeset
   383
            self.content.seek(0, 0)
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   384
            form = FieldStorage(self.content, self.received_headers,
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   385
                                environ={'REQUEST_METHOD': 'POST'},
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   386
                                keep_blank_values=1,
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   387
                                strict_parsing=1)
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   388
            for key in form:
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   389
                value = form[key]
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   390
                if isinstance(value, list):
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   391
                    self.args[key] = [v.value for v in value]
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   392
                elif value.filename:
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   393
                    if value.done != -1: # -1 is transfer has been interrupted
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   394
                        self.files[key] = (value.filename, value.file)
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   395
                    else:
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   396
                        self.files[key] = (None, None)
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   397
                else:
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   398
                    self.args[key] = value.value
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   399
    self.process()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   400
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   401
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   402
from logging import getLogger
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   403
from cubicweb import set_log_methods
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   404
LOGGER = getLogger('cubicweb.twisted')
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   405
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
   406
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
   407
def run(config):
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
   408
    # create the site
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
   409
    root_resource = CubicWebRootResource(config)
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
   410
    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
   411
    # 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
   412
    port = config['port'] or 8080
5155
1dea6e0fdfc1 Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents: 5062
diff changeset
   413
    reactor.listenTCP(port, website)
2694
4303ff921a9b [twisted] use cubicweb.twisted.logger instead of print to notify when the instance is started
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2685
diff changeset
   414
    logger = getLogger('cubicweb.twisted')
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
   415
    if not config.debugmode:
4219
87203a0a3a81 do not attempt to daemonize under windows
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4212
diff changeset
   416
        if sys.platform == 'win32':
4221
da84ca26896d raising ConfigurationError is cleaner; remove some unused imports
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4219
diff changeset
   417
            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
   418
                                     "commands (e.g : 'net start my_instance)'")
3558
0e478957a9d4 smallest possible change to fix #472806
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3502
diff changeset
   419
        print 'instance starting in the background'
3606
8326aceecb46 fix startup as a daemon
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3558
diff changeset
   420
        if daemonize():
8326aceecb46 fix startup as a daemon
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3558
diff changeset
   421
            return # child process
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
   422
        if config['pid-file']:
2711
7aee3bd7a704 ensure runtime dir exists
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2708
diff changeset
   423
            # ensure the directory where the pid-file should be set exists (for
3791
62d6ab877694 put back url info started at the end of initialisations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3641
diff changeset
   424
            # instance /var/run/cubicweb may be deleted on computer restart)
2711
7aee3bd7a704 ensure runtime dir exists
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2708
diff changeset
   425
            piddir = os.path.dirname(config['pid-file'])
7aee3bd7a704 ensure runtime dir exists
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2708
diff changeset
   426
            if not os.path.exists(piddir):
7aee3bd7a704 ensure runtime dir exists
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2708
diff changeset
   427
                os.makedirs(piddir)
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
   428
            file(config['pid-file'], 'w').write(str(os.getpid()))
3606
8326aceecb46 fix startup as a daemon
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3558
diff changeset
   429
    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
   430
    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
   431
        try:
c1a8456cb5f9 should change process'user once pid file has been written
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3181
diff changeset
   432
            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
   433
        except ValueError:
c1a8456cb5f9 should change process'user once pid file has been written
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3181
diff changeset
   434
            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
   435
            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
   436
        os.setuid(uid)
3606
8326aceecb46 fix startup as a daemon
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3558
diff changeset
   437
    root_resource.start_service()
3791
62d6ab877694 put back url info started at the end of initialisations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3641
diff changeset
   438
    logger.info('instance started on %s', root_resource.base_url)
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
   439
    if config['profile']:
4960
26b2468a1e73 [etwist] cleanup, use cProfile instead of hotshot
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4914
diff changeset
   440
        import cProfile
26b2468a1e73 [etwist] cleanup, use cProfile instead of hotshot
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4914
diff changeset
   441
        cProfile.runctx('reactor.run()', 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
   442
    else:
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
   443
        reactor.run()