annotate roundup/cgi/client.py @ 4291:b1772fdb09d0

Fix traceback on .../msgN/ url... ...this requests the file content and for apache mod_wsgi produced a traceback because the mime type is None for messages, fixes issue2550586, thanks to ThomasAH for reporting and to Intevation for funding the fix.
author Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
date Mon, 30 Nov 2009 21:55:59 +0000
parents e24a6ca34448
children d51a9c498dc4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
1 """WWW request handler (also used in the stand-alone server).
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2 """
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
3 __docformat__ = 'restructuredtext'
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
4
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
5 import base64, binascii, cgi, codecs, httplib, mimetypes, os
4046
48be910ebda1 Fix typo in last checkin.
Stefan Seefeld <stefan@seefeld.name>
parents: 4045
diff changeset
6 import quopri, random, re, rfc822, stat, sys, time, urllib, urlparse
3628
ed76f7ee34c4 handle connection loss when responding to web requests
Richard Jones <richard@users.sourceforge.net>
parents: 3606
diff changeset
7 import Cookie, socket, errno
3916
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
8 from Cookie import CookieError, BaseCookie, SimpleCookie
4045
82213b1971b4 Only feed back traceback to web users if config.WEB_DEBUG is True
Stefan Seefeld <stefan@seefeld.name>
parents: 4027
diff changeset
9 from cStringIO import StringIO
2233
3d9bb1a052d1 fix random seeding for forking server
Richard Jones <richard@users.sourceforge.net>
parents: 2230
diff changeset
10
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 1987
diff changeset
11 from roundup import roundupdb, date, hyperdb, password
2557
ff02e9851592 translator object must be Roundup Translation Service...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2514
diff changeset
12 from roundup.cgi import templating, cgitb, TranslationService
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 1987
diff changeset
13 from roundup.cgi.actions import *
3396
Richard Jones <richard@users.sourceforge.net>
parents: 3388
diff changeset
14 from roundup.exceptions import *
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 1987
diff changeset
15 from roundup.cgi.exceptions import *
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 1987
diff changeset
16 from roundup.cgi.form_parser import FormParser
4114
da682f38bad3 bug introduced in the migration to the email package (issue 2550531)
Richard Jones <richard@users.sourceforge.net>
parents: 4109
diff changeset
17 from roundup.mailer import Mailer, MessageSendError, encode_quopri
3427
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
18 from roundup.cgi import accept_language
4079
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
19 from roundup import xmlrpc
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
20
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
21 def initialiseSecurity(security):
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
22 '''Create some Permissions and Roles on the security object
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
23
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
24 This function is directly invoked by security.Security.__init__()
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
25 as a part of the Security object instantiation.
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
26 '''
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
27 p = security.addPermission(name="Web Access",
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
28 description="User may access the web interface")
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
29 security.addPermissionToRole('Admin', p)
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
30
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
31 # doing Role stuff through the web - make sure Admin can
3276
3124e578db02 Email fixes:
Richard Jones <richard@users.sourceforge.net>
parents: 3069
diff changeset
32 # TODO: deprecate this and use a property-based control
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
33 p = security.addPermission(name="Web Roles",
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
34 description="User may manipulate user Roles through the web")
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
35 security.addPermissionToRole('Admin', p)
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
36
1684
b87c40d1b8fb fix hackish message escaping [SF#757128]
Richard Jones <richard@users.sourceforge.net>
parents: 1656
diff changeset
37 # used to clean messages passed through CGI variables - HTML-escape any tag
b87c40d1b8fb fix hackish message escaping [SF#757128]
Richard Jones <richard@users.sourceforge.net>
parents: 1656
diff changeset
38 # that isn't <a href="">, <i>, <b> and <br> (including XHTML variants) so
b87c40d1b8fb fix hackish message escaping [SF#757128]
Richard Jones <richard@users.sourceforge.net>
parents: 1656
diff changeset
39 # that people can't pass through nasties like <script>, <iframe>, ...
b87c40d1b8fb fix hackish message escaping [SF#757128]
Richard Jones <richard@users.sourceforge.net>
parents: 1656
diff changeset
40 CLEAN_MESSAGE_RE = r'(<(/?(.*?)(\s*href="[^"]")?\s*/?)>)'
b87c40d1b8fb fix hackish message escaping [SF#757128]
Richard Jones <richard@users.sourceforge.net>
parents: 1656
diff changeset
41 def clean_message(message, mc=re.compile(CLEAN_MESSAGE_RE, re.I)):
b87c40d1b8fb fix hackish message escaping [SF#757128]
Richard Jones <richard@users.sourceforge.net>
parents: 1656
diff changeset
42 return mc.sub(clean_message_callback, message)
b87c40d1b8fb fix hackish message escaping [SF#757128]
Richard Jones <richard@users.sourceforge.net>
parents: 1656
diff changeset
43 def clean_message_callback(match, ok={'a':1,'i':1,'b':1,'br':1}):
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
44 """ Strip all non <a>,<i>,<b> and <br> tags from a string
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
45 """
1684
b87c40d1b8fb fix hackish message escaping [SF#757128]
Richard Jones <richard@users.sourceforge.net>
parents: 1656
diff changeset
46 if ok.has_key(match.group(3).lower()):
1656
ee730d990989 fix cross-site-scripting bug
Richard Jones <richard@users.sourceforge.net>
parents: 1654
diff changeset
47 return match.group(1)
ee730d990989 fix cross-site-scripting bug
Richard Jones <richard@users.sourceforge.net>
parents: 1654
diff changeset
48 return '&lt;%s&gt;'%match.group(2)
ee730d990989 fix cross-site-scripting bug
Richard Jones <richard@users.sourceforge.net>
parents: 1654
diff changeset
49
3916
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
50
4109
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
51 error_message = ''"""<html><head><title>An error has occurred</title></head>
3554
5e70726a86dd fixed schema migration problem when Class keys were removed
Richard Jones <richard@users.sourceforge.net>
parents: 3551
diff changeset
52 <body><h1>An error has occurred</h1>
3551
3c70ab03c917 translate error message shown instead of tracebacks, add page title
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3548
diff changeset
53 <p>A problem was encountered processing your request.
3c70ab03c917 translate error message shown instead of tracebacks, add page title
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3548
diff changeset
54 The tracker maintainers have been notified of the problem.</p>
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
55 </body></html>"""
3548
61d48244e7a8 login may now be for a single session
Richard Jones <richard@users.sourceforge.net>
parents: 3494
diff changeset
56
3916
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
57
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
58 class LiberalCookie(SimpleCookie):
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
59 """ Python's SimpleCookie throws an exception if the cookie uses invalid
3916
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
60 syntax. Other applications on the same server may have done precisely
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
61 this, preventing roundup from working through no fault of roundup.
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
62 Numerous other python apps have run into the same problem:
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
63
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
64 trac: http://trac.edgewall.org/ticket/2256
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
65 mailman: http://bugs.python.org/issue472646
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
66
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
67 This particular implementation comes from trac's solution to the
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
68 problem. Unfortunately it requires some hackery in SimpleCookie's
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
69 internals to provide a more liberal __set method.
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
70 """
3916
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
71 def load(self, rawdata, ignore_parse_errors=True):
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
72 if ignore_parse_errors:
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
73 self.bad_cookies = []
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
74 self._BaseCookie__set = self._loose_set
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
75 SimpleCookie.load(self, rawdata)
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
76 if ignore_parse_errors:
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
77 self._BaseCookie__set = self._strict_set
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
78 for key in self.bad_cookies:
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
79 del self[key]
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
80
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
81 _strict_set = BaseCookie._BaseCookie__set
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
82
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
83 def _loose_set(self, key, real_value, coded_value):
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
84 try:
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
85 self._strict_set(key, real_value, coded_value)
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
86 except CookieError:
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
87 self.bad_cookies.append(key)
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
88 dict.__setitem__(self, key, None)
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
89
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
90
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
91 class Session:
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
92 """
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
93 Needs DB to be already opened by client
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
94
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
95 Session attributes at instantiation:
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
96
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
97 - "client" - reference to client for add_cookie function
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
98 - "session_db" - session DB manager
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
99 - "cookie_name" - name of the cookie with session id
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
100 - "_sid" - session id for current user
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
101 - "_data" - session data cache
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
102
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
103 session = Session(client)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
104 session.set(name=value)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
105 value = session.get(name)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
106
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
107 session.destroy() # delete current session
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
108 session.clean_up() # clean up session table
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
109
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
110 session.update(set_cookie=True, expire=3600*24*365)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
111 # refresh session expiration time, setting persistent
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
112 # cookie if needed to last for 'expire' seconds
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
113
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
114 """
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
115
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
116 def __init__(self, client):
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
117 self._data = {}
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
118 self._sid = None
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
119
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
120 self.client = client
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
121 self.session_db = client.db.getSessionManager()
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
122
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
123 # parse cookies for session id
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
124 self.cookie_name = 'roundup_session_%s' % \
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
125 re.sub('[^a-zA-Z]', '', client.instance.config.TRACKER_NAME)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
126 cookies = LiberalCookie(client.env.get('HTTP_COOKIE', ''))
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
127 if self.cookie_name in cookies:
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
128 if not self.session_db.exists(cookies[self.cookie_name].value):
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
129 self._sid = None
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
130 # remove old cookie
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
131 self.client.add_cookie(self.cookie_name, None)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
132 else:
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
133 self._sid = cookies[self.cookie_name].value
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
134 self._data = self.session_db.getall(self._sid)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
135
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
136 def _gen_sid(self):
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
137 """ generate a unique session key """
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
138 while 1:
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
139 s = '%s%s'%(time.time(), random.random())
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
140 s = binascii.b2a_base64(s).strip()
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
141 if not self.session_db.exists(s):
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
142 break
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
143
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
144 # clean up the base64
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
145 if s[-1] == '=':
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
146 if s[-2] == '=':
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
147 s = s[:-2]
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
148 else:
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
149 s = s[:-1]
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
150 return s
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
151
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
152 def clean_up(self):
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
153 """Remove expired sessions"""
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
154 self.session_db.clean()
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
155
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
156 def destroy(self):
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
157 self.client.add_cookie(self.cookie_name, None)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
158 self._data = {}
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
159 self.session_db.destroy(self._sid)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
160 self.client.db.commit()
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
161
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
162 def get(self, name, default=None):
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
163 return self._data.get(name, default)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
164
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
165 def set(self, **kwargs):
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
166 self._data.update(kwargs)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
167 if not self._sid:
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
168 self._sid = self._gen_sid()
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
169 self.session_db.set(self._sid, **self._data)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
170 # add session cookie
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
171 self.update(set_cookie=True)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
172
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
173 # XXX added when patching 1.4.4 for backward compatibility
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
174 # XXX remove
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
175 self.client.session = self._sid
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
176 else:
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
177 self.session_db.set(self._sid, **self._data)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
178 self.client.db.commit()
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
179
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
180 def update(self, set_cookie=False, expire=None):
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
181 """ update timestamp in db to avoid expiration
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
182
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
183 if 'set_cookie' is True, set cookie with 'expire' seconds lifetime
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
184 if 'expire' is None - session will be closed with the browser
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
185
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
186 XXX the session can be purged within a week even if a cookie
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
187 lifetime is longer
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
188 """
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
189 self.session_db.updateTimestamp(self._sid)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
190 self.client.db.commit()
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
191
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
192 if set_cookie:
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
193 self.client.add_cookie(self.cookie_name, self._sid, expire=expire)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
194
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
195
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
196
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
197 class Client:
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
198 """Instantiate to handle one CGI request.
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
199
1244
8dd4f736370b merge from maintenance branch
Richard Jones <richard@users.sourceforge.net>
parents: 1236
diff changeset
200 See inner_main for request processing.
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
201
1244
8dd4f736370b merge from maintenance branch
Richard Jones <richard@users.sourceforge.net>
parents: 1236
diff changeset
202 Client attributes at instantiation:
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
203
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
204 - "path" is the PATH_INFO inside the instance (with no leading '/')
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
205 - "base" is the base URL for the instance
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
206 - "form" is the cgi form, an instance of FieldStorage from the standard
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
207 cgi module
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
208 - "additional_headers" is a dictionary of additional HTTP headers that
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
209 should be sent to the client
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
210 - "response_code" is the HTTP response code to send to the client
2557
ff02e9851592 translator object must be Roundup Translation Service...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2514
diff changeset
211 - "translator" is TranslationService instance
1244
8dd4f736370b merge from maintenance branch
Richard Jones <richard@users.sourceforge.net>
parents: 1236
diff changeset
212
8dd4f736370b merge from maintenance branch
Richard Jones <richard@users.sourceforge.net>
parents: 1236
diff changeset
213 During the processing of a request, the following attributes are used:
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
214
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
215 - "db"
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
216 - "error_message" holds a list of error messages
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
217 - "ok_message" holds a list of OK messages
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
218 - "session" is deprecated in favor of session_api (XXX remove)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
219 - "session_api" is the interface to store data in session
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
220 - "user" is the current user's name
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
221 - "userid" is the current user's id
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
222 - "template" is the current :template context
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
223 - "classname" is the current class context name
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
224 - "nodeid" is the current context item id
1244
8dd4f736370b merge from maintenance branch
Richard Jones <richard@users.sourceforge.net>
parents: 1236
diff changeset
225
8dd4f736370b merge from maintenance branch
Richard Jones <richard@users.sourceforge.net>
parents: 1236
diff changeset
226 User Identification:
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
227 Users that are absent in session data are anonymous and are logged
1244
8dd4f736370b merge from maintenance branch
Richard Jones <richard@users.sourceforge.net>
parents: 1236
diff changeset
228 in as that user. This typically gives them all Permissions assigned to the
8dd4f736370b merge from maintenance branch
Richard Jones <richard@users.sourceforge.net>
parents: 1236
diff changeset
229 Anonymous Role.
8dd4f736370b merge from maintenance branch
Richard Jones <richard@users.sourceforge.net>
parents: 1236
diff changeset
230
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
231 Every user is assigned a session. "session_api" is the interface to work
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
232 with session data.
1420
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
233
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
234 Special form variables:
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
235 Note that in various places throughout this code, special form
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
236 variables of the form :<name> are used. The colon (":") part may
1436
2f6647cf5345 bugger, dropping support for "+" special char
Richard Jones <richard@users.sourceforge.net>
parents: 1435
diff changeset
237 actually be one of either ":" or "@".
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
238 """
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
239
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
240 # charset used for data storage and form templates
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
241 # Note: must be in lower case for comparisons!
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
242 # XXX take this from instance.config?
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
243 STORAGE_CHARSET = 'utf-8'
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
244
1421
90bb11eb40dc oops, forgot the templating :)
Richard Jones <richard@users.sourceforge.net>
parents: 1420
diff changeset
245 #
1420
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
246 # special form variables
1421
90bb11eb40dc oops, forgot the templating :)
Richard Jones <richard@users.sourceforge.net>
parents: 1420
diff changeset
247 #
1436
2f6647cf5345 bugger, dropping support for "+" special char
Richard Jones <richard@users.sourceforge.net>
parents: 1435
diff changeset
248 FV_TEMPLATE = re.compile(r'[@:]template')
2f6647cf5345 bugger, dropping support for "+" special char
Richard Jones <richard@users.sourceforge.net>
parents: 1435
diff changeset
249 FV_OK_MESSAGE = re.compile(r'[@:]ok_message')
2f6647cf5345 bugger, dropping support for "+" special char
Richard Jones <richard@users.sourceforge.net>
parents: 1435
diff changeset
250 FV_ERROR_MESSAGE = re.compile(r'[@:]error_message')
1421
90bb11eb40dc oops, forgot the templating :)
Richard Jones <richard@users.sourceforge.net>
parents: 1420
diff changeset
251
90bb11eb40dc oops, forgot the templating :)
Richard Jones <richard@users.sourceforge.net>
parents: 1420
diff changeset
252 # Note: index page stuff doesn't appear here:
90bb11eb40dc oops, forgot the templating :)
Richard Jones <richard@users.sourceforge.net>
parents: 1420
diff changeset
253 # columns, sort, sortdir, filter, group, groupdir, search_text,
90bb11eb40dc oops, forgot the templating :)
Richard Jones <richard@users.sourceforge.net>
parents: 1420
diff changeset
254 # pagesize, startwith
1420
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
255
3760
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
256 # list of network error codes that shouldn't be reported to tracker admin
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
257 # (error descriptions from FreeBSD intro(2))
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
258 IGNORE_NET_ERRORS = (
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
259 # A write on a pipe, socket or FIFO for which there is
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
260 # no process to read the data.
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
261 errno.EPIPE,
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
262 # A connection was forcibly closed by a peer.
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
263 # This normally results from a loss of the connection
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
264 # on the remote socket due to a timeout or a reboot.
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
265 errno.ECONNRESET,
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
266 # Software caused connection abort. A connection abort
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
267 # was caused internal to your host machine.
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
268 errno.ECONNABORTED,
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
269 # A connect or send request failed because the connected party
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
270 # did not properly respond after a period of time.
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
271 errno.ETIMEDOUT,
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
272 )
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
273
2467
76ead526113d client instances may be used as translation engines.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2366
diff changeset
274 def __init__(self, instance, request, env, form=None, translator=None):
2233
3d9bb1a052d1 fix random seeding for forking server
Richard Jones <richard@users.sourceforge.net>
parents: 2230
diff changeset
275 # re-seed the random number generator
3d9bb1a052d1 fix random seeding for forking server
Richard Jones <richard@users.sourceforge.net>
parents: 2230
diff changeset
276 random.seed()
2230
ca2664e095be disable forking server when os.fork() not available [SF#938586]
Richard Jones <richard@users.sourceforge.net>
parents: 2183
diff changeset
277 self.start = time.time()
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
278 self.instance = instance
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
279 self.request = request
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
280 self.env = env
2467
76ead526113d client instances may be used as translation engines.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2366
diff changeset
281 self.setTranslator(translator)
1799
071ea6fc803f Extracted duplicated mail-sending code...
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 1798
diff changeset
282 self.mailer = Mailer(instance.config)
1004
5f12d3259f31 logout works better now
Richard Jones <richard@users.sourceforge.net>
parents: 1003
diff changeset
283
1157
26c8cb2162d7 fixed various URL / base URL issues
Richard Jones <richard@users.sourceforge.net>
parents: 1153
diff changeset
284 # save off the path
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
285 self.path = env['PATH_INFO']
1004
5f12d3259f31 logout works better now
Richard Jones <richard@users.sourceforge.net>
parents: 1003
diff changeset
286
1398
b3e1e9ab0500 fixed cookie path to use TRACKER_WEB [SF#667020]
Richard Jones <richard@users.sourceforge.net>
parents: 1393
diff changeset
287 # this is the base URL for this tracker
1157
26c8cb2162d7 fixed various URL / base URL issues
Richard Jones <richard@users.sourceforge.net>
parents: 1153
diff changeset
288 self.base = self.instance.config.TRACKER_WEB
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
289
2183
ac24a9c74cca be paranoid about TRACKER_WEB
Richard Jones <richard@users.sourceforge.net>
parents: 2137
diff changeset
290 # check the tracker_we setting
ac24a9c74cca be paranoid about TRACKER_WEB
Richard Jones <richard@users.sourceforge.net>
parents: 2137
diff changeset
291 if not self.base.endswith('/'):
ac24a9c74cca be paranoid about TRACKER_WEB
Richard Jones <richard@users.sourceforge.net>
parents: 2137
diff changeset
292 self.base = self.base + '/'
ac24a9c74cca be paranoid about TRACKER_WEB
Richard Jones <richard@users.sourceforge.net>
parents: 2137
diff changeset
293
1398
b3e1e9ab0500 fixed cookie path to use TRACKER_WEB [SF#667020]
Richard Jones <richard@users.sourceforge.net>
parents: 1393
diff changeset
294 # this is the "cookie path" for this tracker (ie. the path part of
b3e1e9ab0500 fixed cookie path to use TRACKER_WEB [SF#667020]
Richard Jones <richard@users.sourceforge.net>
parents: 1393
diff changeset
295 # the "base" url)
b3e1e9ab0500 fixed cookie path to use TRACKER_WEB [SF#667020]
Richard Jones <richard@users.sourceforge.net>
parents: 1393
diff changeset
296 self.cookie_path = urlparse.urlparse(self.base)[2]
2946
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
297 # cookies to set in http responce
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
298 # {(path, name): (value, expire)}
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
299 self._cookies = {}
1398
b3e1e9ab0500 fixed cookie path to use TRACKER_WEB [SF#667020]
Richard Jones <richard@users.sourceforge.net>
parents: 1393
diff changeset
300
1157
26c8cb2162d7 fixed various URL / base URL issues
Richard Jones <richard@users.sourceforge.net>
parents: 1153
diff changeset
301 # see if we need to re-parse the environment for the form (eg Zope)
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
302 if form is None:
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
303 self.form = cgi.FieldStorage(environ=env)
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
304 else:
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
305 self.form = form
1157
26c8cb2162d7 fixed various URL / base URL issues
Richard Jones <richard@users.sourceforge.net>
parents: 1153
diff changeset
306
26c8cb2162d7 fixed various URL / base URL issues
Richard Jones <richard@users.sourceforge.net>
parents: 1153
diff changeset
307 # turn debugging on/off
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
308 try:
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
309 self.debug = int(env.get("ROUNDUP_DEBUG", 0))
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
310 except ValueError:
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
311 # someone gave us a non-int debug level, turn it off
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
312 self.debug = 0
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
313
1157
26c8cb2162d7 fixed various URL / base URL issues
Richard Jones <richard@users.sourceforge.net>
parents: 1153
diff changeset
314 # flag to indicate that the HTTP headers have been sent
26c8cb2162d7 fixed various URL / base URL issues
Richard Jones <richard@users.sourceforge.net>
parents: 1153
diff changeset
315 self.headers_done = 0
26c8cb2162d7 fixed various URL / base URL issues
Richard Jones <richard@users.sourceforge.net>
parents: 1153
diff changeset
316
1120
c26471971d18 Exposed the Batch mechanism through the top-level "utils" variable.
Richard Jones <richard@users.sourceforge.net>
parents: 1103
diff changeset
317 # additional headers to send with the request - must be registered
c26471971d18 Exposed the Batch mechanism through the top-level "utils" variable.
Richard Jones <richard@users.sourceforge.net>
parents: 1103
diff changeset
318 # before the first write
c26471971d18 Exposed the Batch mechanism through the top-level "utils" variable.
Richard Jones <richard@users.sourceforge.net>
parents: 1103
diff changeset
319 self.additional_headers = {}
c26471971d18 Exposed the Batch mechanism through the top-level "utils" variable.
Richard Jones <richard@users.sourceforge.net>
parents: 1103
diff changeset
320 self.response_code = 200
c26471971d18 Exposed the Batch mechanism through the top-level "utils" variable.
Richard Jones <richard@users.sourceforge.net>
parents: 1103
diff changeset
321
2947
e611be5ee6c4 initialize self.charset early to enable html output for tracebacks...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2946
diff changeset
322 # default character set
e611be5ee6c4 initialize self.charset early to enable html output for tracebacks...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2946
diff changeset
323 self.charset = self.STORAGE_CHARSET
e611be5ee6c4 initialize self.charset early to enable html output for tracebacks...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2946
diff changeset
324
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
325 # parse cookies (used for charset lookups)
3916
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
326 # use our own LiberalCookie to handle bad apps on the same
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
327 # server that have set cookies that are out of spec
57ad3e2c2545 handle bad cookies
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3900
diff changeset
328 self.cookie = LiberalCookie(self.env.get('HTTP_COOKIE', ''))
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
329
2928
81c99c857b57 applied patch [SF#1067690]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2923
diff changeset
330 self.user = None
81c99c857b57 applied patch [SF#1067690]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2923
diff changeset
331 self.userid = None
2948
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
332 self.nodeid = None
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
333 self.classname = None
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
334 self.template = None
2928
81c99c857b57 applied patch [SF#1067690]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2923
diff changeset
335
2467
76ead526113d client instances may be used as translation engines.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2366
diff changeset
336 def setTranslator(self, translator=None):
76ead526113d client instances may be used as translation engines.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2366
diff changeset
337 """Replace the translation engine
76ead526113d client instances may be used as translation engines.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2366
diff changeset
338
76ead526113d client instances may be used as translation engines.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2366
diff changeset
339 'translator'
2557
ff02e9851592 translator object must be Roundup Translation Service...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2514
diff changeset
340 is TranslationService instance.
ff02e9851592 translator object must be Roundup Translation Service...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2514
diff changeset
341 It must define methods 'translate' (TAL-compatible i18n),
ff02e9851592 translator object must be Roundup Translation Service...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2514
diff changeset
342 'gettext' and 'ngettext' (gettext-compatible i18n).
2467
76ead526113d client instances may be used as translation engines.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2366
diff changeset
343
2557
ff02e9851592 translator object must be Roundup Translation Service...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2514
diff changeset
344 If omitted, create default TranslationService.
2467
76ead526113d client instances may be used as translation engines.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2366
diff changeset
345 """
76ead526113d client instances may be used as translation engines.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2366
diff changeset
346 if translator is None:
2808
18c28d22b3b5 pass tracker home directory to get_translation()
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2800
diff changeset
347 translator = TranslationService.get_translation(
2923
29563959c026 language defaults to config option TRACKER_LANGUAGE
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2906
diff changeset
348 language=self.instance.config["TRACKER_LANGUAGE"],
2808
18c28d22b3b5 pass tracker home directory to get_translation()
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2800
diff changeset
349 tracker_home=self.instance.config["TRACKER_HOME"])
2467
76ead526113d client instances may be used as translation engines.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2366
diff changeset
350 self.translator = translator
76ead526113d client instances may be used as translation engines.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2366
diff changeset
351 self._ = self.gettext = translator.gettext
76ead526113d client instances may be used as translation engines.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2366
diff changeset
352 self.ngettext = translator.ngettext
76ead526113d client instances may be used as translation engines.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2366
diff changeset
353
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
354 def main(self):
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
355 """ Wrap the real main in a try/finally so we always close off the db.
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
356 """
1133
36ec30d286ea Cleaned up CHANGES/TODO
Richard Jones <richard@users.sourceforge.net>
parents: 1130
diff changeset
357 try:
4079
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
358 if self.env.get('CONTENT_TYPE') == 'text/xml':
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
359 self.handle_xmlrpc()
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
360 else:
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
361 self.inner_main()
1133
36ec30d286ea Cleaned up CHANGES/TODO
Richard Jones <richard@users.sourceforge.net>
parents: 1130
diff changeset
362 finally:
36ec30d286ea Cleaned up CHANGES/TODO
Richard Jones <richard@users.sourceforge.net>
parents: 1130
diff changeset
363 if hasattr(self, 'db'):
36ec30d286ea Cleaned up CHANGES/TODO
Richard Jones <richard@users.sourceforge.net>
parents: 1130
diff changeset
364 self.db.close()
4079
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
365
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
366
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
367 def handle_xmlrpc(self):
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
368
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
369 # Pull the raw XML out of the form. The "value" attribute
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
370 # will be the raw content of the POST request.
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
371 assert self.form.file
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
372 input = self.form.value
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
373 # So that the rest of Roundup can query the form in the
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
374 # usual way, we create an empty list of fields.
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
375 self.form.list = []
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
376
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
377 # Set the charset and language, since other parts of
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
378 # Roundup may depend upon that.
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
379 self.determine_charset()
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
380 self.determine_language()
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
381 # Open the database as the correct user.
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
382 self.determine_user()
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
383
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
384 # Call the appropriate XML-RPC method.
4083
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4079
diff changeset
385 handler = xmlrpc.RoundupDispatcher(self.db,
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4079
diff changeset
386 self.instance.actions,
bbab97f8ffb2 XMLRPC improvements:
Stefan Seefeld <stefan@seefeld.name>
parents: 4079
diff changeset
387 self.translator,
4079
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
388 allow_none=True)
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
389 output = handler.dispatch(input)
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
390
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
391 self.setHeader("Content-Type", "text/xml")
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
392 self.setHeader("Content-Length", str(len(output)))
edf526c91412 * Refactor XMLRPC interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4077
diff changeset
393 self.write(output)
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
394
1133
36ec30d286ea Cleaned up CHANGES/TODO
Richard Jones <richard@users.sourceforge.net>
parents: 1130
diff changeset
395 def inner_main(self):
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
396 """Process a request.
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
397
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
398 The most common requests are handled like so:
1054
3d8ea16347aa more explanatory docstring
Richard Jones <richard@users.sourceforge.net>
parents: 1053
diff changeset
399
3427
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
400 1. look for charset and language preferences, set up user locale
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
401 see determine_charset, determine_language
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
402 2. figure out who we are, defaulting to the "anonymous" user
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
403 see determine_user
3427
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
404 3. figure out what the request is for - the context
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
405 see determine_context
3427
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
406 4. handle any requested action (item edit, search, ...)
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
407 see handle_action
3427
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
408 5. render a template, resulting in HTML output
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
409
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
410 In some situations, exceptions occur:
1054
3d8ea16347aa more explanatory docstring
Richard Jones <richard@users.sourceforge.net>
parents: 1053
diff changeset
411
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
412 - HTTP Redirect (generally raised by an action)
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
413 - SendFile (generally raised by determine_context)
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
414 serve up a FileClass "content" property
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
415 - SendStaticFile (generally raised by determine_context)
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
416 serve up a file from the tracker "html" directory
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
417 - Unauthorised (generally raised by an action)
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
418 the action is cancelled, the request is rendered and an error
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
419 message is displayed indicating that permission was not
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
420 granted for the action to take place
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
421 - templating.Unauthorised (templating action not permitted)
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
422 raised by an attempted rendering of a template when the user
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
423 doesn't have permission
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
424 - NotFound (raised wherever it needs to be)
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
425 percolates up to the CGI interface that called the client
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
426 """
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
427 self.ok_message = []
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
428 self.error_message = []
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
429 try:
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
430 self.determine_charset()
3427
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
431 self.determine_language()
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
432
4109
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
433 try:
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
434 # make sure we're identified (even anonymously)
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
435 self.determine_user()
2938
463902a0fbbb determine user before context:
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2937
diff changeset
436
4109
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
437 # figure out the context and desired content template
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
438 self.determine_context()
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
439
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
440 # possibly handle a form submit action (may change self.classname
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
441 # and self.template, and may also append error/ok_messages)
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
442 html = self.handle_action()
1697
c9f67f2f7ba7 don't open the database for static files
Richard Jones <richard@users.sourceforge.net>
parents: 1692
diff changeset
443
4109
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
444 if html:
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
445 self.write_html(html)
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
446 return
2045
d124af927369 Forward-porting of fixes from the maintenance branch.
Richard Jones <richard@users.sourceforge.net>
parents: 2032
diff changeset
447
4109
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
448 # now render the page
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
449 # we don't want clients caching our dynamic pages
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
450 self.additional_headers['Cache-Control'] = 'no-cache'
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
451 # Pragma: no-cache makes Mozilla and its ilk
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
452 # double-load all pages!!
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
453 # self.additional_headers['Pragma'] = 'no-cache'
1579
07a6b8587bc2 removed Pragma: no-cache...
Richard Jones <richard@users.sourceforge.net>
parents: 1562
diff changeset
454
4109
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
455 # pages with messages added expire right now
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
456 # simple views may be cached for a small amount of time
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
457 # TODO? make page expire time configurable
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
458 # <rj> always expire pages, as IE just doesn't seem to do the
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
459 # right thing here :(
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
460 date = time.time() - 1
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
461 #if self.error_message or self.ok_message:
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
462 # date = time.time() - 1
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
463 #else:
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
464 # date = time.time() + 5
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
465 self.additional_headers['Expires'] = rfc822.formatdate(date)
1552
68ef6deefcf1 cgi fixes
Richard Jones <richard@users.sourceforge.net>
parents: 1538
diff changeset
466
4109
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
467 # render the content
3896
fca0365521fc ignore client shutdown exceptions when sending responses
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3867
diff changeset
468 self.write_html(self.renderContext())
4109
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
469 except SendFile, designator:
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
470 # The call to serve_file may result in an Unauthorised
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
471 # exception or a NotModified exception. Those
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
472 # exceptions will be handled by the outermost set of
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
473 # exception handlers.
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
474 self.serve_file(designator)
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
475 except SendStaticFile, file:
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
476 self.serve_static_file(str(file))
3896
fca0365521fc ignore client shutdown exceptions when sending responses
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3867
diff changeset
477 except IOError:
3900
182ba3207899 wrap comment to less than 75 chars
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3898
diff changeset
478 # IOErrors here are due to the client disconnecting before
182ba3207899 wrap comment to less than 75 chars
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3898
diff changeset
479 # recieving the reply.
3896
fca0365521fc ignore client shutdown exceptions when sending responses
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3867
diff changeset
480 pass
2230
ca2664e095be disable forking server when os.fork() not available [SF#938586]
Richard Jones <richard@users.sourceforge.net>
parents: 2183
diff changeset
481
2052
78e6a1e4984e forward-port from maint branch
Richard Jones <richard@users.sourceforge.net>
parents: 2046
diff changeset
482 except SeriousError, message:
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
483 self.write_html(str(message))
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
484 except Redirect, url:
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
485 # let's redirect - if the url isn't None, then we need to do
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
486 # the headers, otherwise the headers have been set before the
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
487 # exception was raised
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
488 if url:
3736
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents: 3687
diff changeset
489 self.additional_headers['Location'] = str(url)
1120
c26471971d18 Exposed the Batch mechanism through the top-level "utils" variable.
Richard Jones <richard@users.sourceforge.net>
parents: 1103
diff changeset
490 self.response_code = 302
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
491 self.write_html('Redirecting to <a href="%s">%s</a>'%(url, url))
4265
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
492 except LoginError, message:
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
493 # The user tried to log in, but did not provide a valid
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
494 # username and password. If we support HTTP
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
495 # authorization, send back a response that will cause the
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
496 # browser to prompt the user again.
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
497 if self.instance.config.WEB_HTTP_AUTH:
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
498 self.response_code = httplib.UNAUTHORIZED
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
499 realm = self.instance.config.TRACKER_NAME
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
500 self.setHeader("WWW-Authenticate",
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
501 "Basic realm=\"%s\"" % realm)
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
502 else:
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
503 self.response_code = httplib.FORBIDDEN
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
504 self.renderFrontPage(message)
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
505 except Unauthorised, message:
1977
f96592a7c357 changes to support the new templating Unauthorised exception.
Richard Jones <richard@users.sourceforge.net>
parents: 1973
diff changeset
506 # users may always see the front page
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
507 self.response_code = 403
4265
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
508 self.renderFrontPage(message)
4109
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
509 except NotModified:
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
510 # send the 304 response
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
511 self.response_code = 304
3f3f44e3534c Address issue2550528.
Stefan Seefeld <stefan@seefeld.name>
parents: 4088
diff changeset
512 self.header()
3898
dd00c917fc40 per-tracker 404 templating
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3896
diff changeset
513 except NotFound, e:
dd00c917fc40 per-tracker 404 templating
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3896
diff changeset
514 self.response_code = 404
dd00c917fc40 per-tracker 404 templating
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3896
diff changeset
515 self.template = '404'
dd00c917fc40 per-tracker 404 templating
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3896
diff changeset
516 try:
dd00c917fc40 per-tracker 404 templating
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3896
diff changeset
517 cl = self.db.getclass(self.classname)
dd00c917fc40 per-tracker 404 templating
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3896
diff changeset
518 self.write_html(self.renderContext())
dd00c917fc40 per-tracker 404 templating
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3896
diff changeset
519 except KeyError:
dd00c917fc40 per-tracker 404 templating
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3896
diff changeset
520 # we can't map the URL to a class we know about
dd00c917fc40 per-tracker 404 templating
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3896
diff changeset
521 # reraise the NotFound and let roundup_server
dd00c917fc40 per-tracker 404 templating
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3896
diff changeset
522 # handle it
dd00c917fc40 per-tracker 404 templating
Justus Pendleton <jpend@users.sourceforge.net>
parents: 3896
diff changeset
523 raise NotFound, e
1818
85fd3d0e7d81 Actually use FormError, so we can move the handling up to inner_main().
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 1807
diff changeset
524 except FormError, e:
2467
76ead526113d client instances may be used as translation engines.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2366
diff changeset
525 self.error_message.append(self._('Form Error: ') + str(e))
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
526 self.write_html(self.renderContext())
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
527 except:
4264
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
528 # Something has gone badly wrong. Therefore, we should
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
529 # make sure that the response code indicates failure.
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
530 if self.response_code == httplib.OK:
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
531 self.response_code = httplib.INTERNAL_SERVER_ERROR
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
532 # Help the administrator work out what went wrong.
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
533 html = ("<h1>Traceback</h1>"
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
534 + cgitb.html(i18n=self.translator)
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
535 + ("<h1>Environment Variables</h1><table>%s</table>"
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
536 % cgitb.niceDict("", self.env)))
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
537 if not self.instance.config.WEB_DEBUG:
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
538 exc_info = sys.exc_info()
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
539 subject = "Error: %s" % exc_info[1]
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
540 self.send_html_to_admin(subject, html)
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
541 self.write_html(self._(error_message))
3548
61d48244e7a8 login may now be for a single session
Richard Jones <richard@users.sourceforge.net>
parents: 3494
diff changeset
542 else:
4264
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
543 self.write_html(html)
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
544
1372
3931614b1cce cleaning old unused sessions only once per hour, not on every cgi request
Andrey Lebedev <kedder@users.sourceforge.net>
parents: 1358
diff changeset
545 def clean_sessions(self):
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
546 """Deprecated
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
547 XXX remove
1937
4c850112895b Some reformatting and fixing docstrings for emacs.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 1936
diff changeset
548 """
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
549 self.clean_up()
1372
3931614b1cce cleaning old unused sessions only once per hour, not on every cgi request
Andrey Lebedev <kedder@users.sourceforge.net>
parents: 1358
diff changeset
550
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
551 def clean_up(self):
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
552 """Remove expired sessions and One Time Keys.
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
553
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
554 Do it only once an hour.
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
555 """
1372
3931614b1cce cleaning old unused sessions only once per hour, not on every cgi request
Andrey Lebedev <kedder@users.sourceforge.net>
parents: 1358
diff changeset
556 hour = 60*60
3931614b1cce cleaning old unused sessions only once per hour, not on every cgi request
Andrey Lebedev <kedder@users.sourceforge.net>
parents: 1358
diff changeset
557 now = time.time()
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
558
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
559 # XXX: hack - use OTK table to store last_clean time information
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
560 # 'last_clean' string is used instead of otk key
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
561 last_clean = self.db.getOTKManager().get('last_clean', 'last_use', 0)
2046
f913b6beac35 document and make easier the actions-returning-content idiom
Richard Jones <richard@users.sourceforge.net>
parents: 2045
diff changeset
562 if now - last_clean < hour:
f913b6beac35 document and make easier the actions-returning-content idiom
Richard Jones <richard@users.sourceforge.net>
parents: 2045
diff changeset
563 return
f913b6beac35 document and make easier the actions-returning-content idiom
Richard Jones <richard@users.sourceforge.net>
parents: 2045
diff changeset
564
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
565 self.session_api.clean_up()
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
566 self.db.getOTKManager().clean()
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
567 self.db.getOTKManager().set('last_clean', last_use=now)
3687
ff9f4ca42454 Postgres backend allows transaction collisions to be ignored when...
Richard Jones <richard@users.sourceforge.net>
parents: 3628
diff changeset
568 self.db.commit(fail_ok=True)
1372
3931614b1cce cleaning old unused sessions only once per hour, not on every cgi request
Andrey Lebedev <kedder@users.sourceforge.net>
parents: 1358
diff changeset
569
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
570 def determine_charset(self):
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
571 """Look for client charset in the form parameters or browser cookie.
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
572
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
573 If no charset requested by client, use storage charset (utf-8).
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
574
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
575 If the charset is found, and differs from the storage charset,
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
576 recode all form fields of type 'text/plain'
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
577 """
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
578 # look for client charset
2946
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
579 charset_parameter = 0
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
580 if self.form.has_key('@charset'):
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
581 charset = self.form['@charset'].value
2946
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
582 if charset.lower() == "none":
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
583 charset = ""
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
584 charset_parameter = 1
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
585 elif self.cookie.has_key('roundup_charset'):
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
586 charset = self.cookie['roundup_charset'].value
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
587 else:
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
588 charset = None
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
589 if charset:
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
590 # make sure the charset is recognized
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
591 try:
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
592 codecs.lookup(charset)
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
593 except LookupError:
2467
76ead526113d client instances may be used as translation engines.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2366
diff changeset
594 self.error_message.append(self._('Unrecognized charset: %r')
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
595 % charset)
2946
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
596 charset_parameter = 0
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
597 else:
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
598 self.charset = charset.lower()
2946
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
599 # If we've got a character set in request parameters,
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
600 # set the browser cookie to keep the preference.
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
601 # This is done after codecs.lookup to make sure
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
602 # that we aren't keeping a wrong value.
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
603 if charset_parameter:
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
604 self.add_cookie('roundup_charset', charset)
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
605
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
606 # if client charset is different from the storage charset,
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
607 # recode form fields
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
608 # XXX this requires FieldStorage from Python library.
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
609 # mod_python FieldStorage is not supported!
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
610 if self.charset != self.STORAGE_CHARSET:
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
611 decoder = codecs.getdecoder(self.charset)
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
612 encoder = codecs.getencoder(self.STORAGE_CHARSET)
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
613 re_charref = re.compile('&#([0-9]+|x[0-9a-f]+);', re.IGNORECASE)
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
614 def _decode_charref(matchobj):
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
615 num = matchobj.group(1)
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
616 if num[0].lower() == 'x':
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
617 uc = int(num[1:], 16)
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
618 else:
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
619 uc = int(num)
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
620 return unichr(uc)
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
621
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
622 for field_name in self.form.keys():
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
623 field = self.form[field_name]
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
624 if (field.type == 'text/plain') and not field.filename:
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
625 try:
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
626 value = decoder(field.value)[0]
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
627 except UnicodeError:
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
628 continue
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
629 value = re_charref.sub(_decode_charref, value)
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
630 field.value = encoder(value)[0]
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
631
3427
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
632 def determine_language(self):
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
633 """Determine the language"""
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
634 # look for language parameter
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
635 # then for language cookie
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
636 # last for the Accept-Language header
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
637 if self.form.has_key("@language"):
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
638 language = self.form["@language"].value
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
639 if language.lower() == "none":
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
640 language = ""
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
641 self.add_cookie("roundup_language", language)
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
642 elif self.cookie.has_key("roundup_language"):
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
643 language = self.cookie["roundup_language"].value
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
644 elif self.instance.config["WEB_USE_BROWSER_LANGUAGE"]:
3557
ea471747d5aa fix failure with browsers not sending "Accept-Language" header [SF#1429646]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3554
diff changeset
645 hal = self.env.get('HTTP_ACCEPT_LANGUAGE')
3427
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
646 language = accept_language.parse(hal)
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
647 else:
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
648 language = ""
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
649
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
650 self.language = language
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
651 if language:
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
652 self.setTranslator(TranslationService.get_translation(
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
653 language,
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
654 tracker_home=self.instance.config["TRACKER_HOME"]))
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
655
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
656 def determine_user(self):
3427
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
657 """Determine who the user is"""
1724
bc4f0aec594e oops, we really do need a database
Richard Jones <richard@users.sourceforge.net>
parents: 1719
diff changeset
658 self.opendb('admin')
bc4f0aec594e oops, we really do need a database
Richard Jones <richard@users.sourceforge.net>
parents: 1719
diff changeset
659
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
660 # get session data from db
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
661 # XXX: rename
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
662 self.session_api = Session(self)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
663
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
664 # take the opportunity to cleanup expired sessions and otks
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
665 self.clean_up()
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
666
3453
8e3c0b88afad prefer http authorization over cookie sessions [SF#1396134]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3427
diff changeset
667 user = None
8e3c0b88afad prefer http authorization over cookie sessions [SF#1396134]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3427
diff changeset
668 # first up, try http authorization if enabled
8e3c0b88afad prefer http authorization over cookie sessions [SF#1396134]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3427
diff changeset
669 if self.instance.config['WEB_HTTP_AUTH']:
3356
2913b42c0810 enabled disabling of REMOTE_USER for when it's not a valid username
Richard Jones <richard@users.sourceforge.net>
parents: 3276
diff changeset
670 if self.env.has_key('REMOTE_USER'):
3453
8e3c0b88afad prefer http authorization over cookie sessions [SF#1396134]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3427
diff changeset
671 # we have external auth (e.g. by Apache)
3356
2913b42c0810 enabled disabling of REMOTE_USER for when it's not a valid username
Richard Jones <richard@users.sourceforge.net>
parents: 3276
diff changeset
672 user = self.env['REMOTE_USER']
2913b42c0810 enabled disabling of REMOTE_USER for when it's not a valid username
Richard Jones <richard@users.sourceforge.net>
parents: 3276
diff changeset
673 elif self.env.get('HTTP_AUTHORIZATION', ''):
3453
8e3c0b88afad prefer http authorization over cookie sessions [SF#1396134]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3427
diff changeset
674 # try handling Basic Auth ourselves
3356
2913b42c0810 enabled disabling of REMOTE_USER for when it's not a valid username
Richard Jones <richard@users.sourceforge.net>
parents: 3276
diff changeset
675 auth = self.env['HTTP_AUTHORIZATION']
2913b42c0810 enabled disabling of REMOTE_USER for when it's not a valid username
Richard Jones <richard@users.sourceforge.net>
parents: 3276
diff changeset
676 scheme, challenge = auth.split(' ', 1)
2913b42c0810 enabled disabling of REMOTE_USER for when it's not a valid username
Richard Jones <richard@users.sourceforge.net>
parents: 3276
diff changeset
677 if scheme.lower() == 'basic':
2913b42c0810 enabled disabling of REMOTE_USER for when it's not a valid username
Richard Jones <richard@users.sourceforge.net>
parents: 3276
diff changeset
678 try:
2913b42c0810 enabled disabling of REMOTE_USER for when it's not a valid username
Richard Jones <richard@users.sourceforge.net>
parents: 3276
diff changeset
679 decoded = base64.decodestring(challenge)
2913b42c0810 enabled disabling of REMOTE_USER for when it's not a valid username
Richard Jones <richard@users.sourceforge.net>
parents: 3276
diff changeset
680 except TypeError:
2913b42c0810 enabled disabling of REMOTE_USER for when it's not a valid username
Richard Jones <richard@users.sourceforge.net>
parents: 3276
diff changeset
681 # invalid challenge
2913b42c0810 enabled disabling of REMOTE_USER for when it's not a valid username
Richard Jones <richard@users.sourceforge.net>
parents: 3276
diff changeset
682 pass
2913b42c0810 enabled disabling of REMOTE_USER for when it's not a valid username
Richard Jones <richard@users.sourceforge.net>
parents: 3276
diff changeset
683 username, password = decoded.split(':')
2913b42c0810 enabled disabling of REMOTE_USER for when it's not a valid username
Richard Jones <richard@users.sourceforge.net>
parents: 3276
diff changeset
684 try:
2913b42c0810 enabled disabling of REMOTE_USER for when it's not a valid username
Richard Jones <richard@users.sourceforge.net>
parents: 3276
diff changeset
685 login = self.get_action_class('login')(self)
2913b42c0810 enabled disabling of REMOTE_USER for when it's not a valid username
Richard Jones <richard@users.sourceforge.net>
parents: 3276
diff changeset
686 login.verifyLogin(username, password)
2913b42c0810 enabled disabling of REMOTE_USER for when it's not a valid username
Richard Jones <richard@users.sourceforge.net>
parents: 3276
diff changeset
687 except LoginError, err:
2913b42c0810 enabled disabling of REMOTE_USER for when it's not a valid username
Richard Jones <richard@users.sourceforge.net>
parents: 3276
diff changeset
688 self.make_user_anonymous()
4265
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
689 raise
3356
2913b42c0810 enabled disabling of REMOTE_USER for when it's not a valid username
Richard Jones <richard@users.sourceforge.net>
parents: 3276
diff changeset
690 user = username
2928
81c99c857b57 applied patch [SF#1067690]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2923
diff changeset
691
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
692 # if user was not set by http authorization, try session lookup
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
693 if not user:
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
694 user = self.session_api.get('user')
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
695 if user:
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
696 # update session lifetime datestamp
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
697 self.session_api.update()
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
698
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
699 # if no user name set by http authorization or session lookup
3453
8e3c0b88afad prefer http authorization over cookie sessions [SF#1396134]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3427
diff changeset
700 # the user is anonymous
8e3c0b88afad prefer http authorization over cookie sessions [SF#1396134]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3427
diff changeset
701 if not user:
8e3c0b88afad prefer http authorization over cookie sessions [SF#1396134]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3427
diff changeset
702 user = 'anonymous'
8e3c0b88afad prefer http authorization over cookie sessions [SF#1396134]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3427
diff changeset
703
8e3c0b88afad prefer http authorization over cookie sessions [SF#1396134]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3427
diff changeset
704 # sanity check on the user still being valid,
8e3c0b88afad prefer http authorization over cookie sessions [SF#1396134]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3427
diff changeset
705 # getting the userid at the same time
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
706 try:
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
707 self.userid = self.db.user.lookup(user)
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
708 except (KeyError, TypeError):
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
709 user = 'anonymous'
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
710
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
711 # make sure the anonymous user is valid if we're using it
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
712 if user == 'anonymous':
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
713 self.make_user_anonymous()
2649
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2638
diff changeset
714 if not self.db.security.hasPermission('Web Access', self.userid):
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2638
diff changeset
715 raise Unauthorised, self._("Anonymous users are not "
1df7d4a41da4 Buncha stuff (sorry about the large checkin):
Richard Jones <richard@users.sourceforge.net>
parents: 2638
diff changeset
716 "allowed to use the web interface")
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
717 else:
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
718 self.user = user
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
719
1003
f89b8d32291b Hack hack hack...
Richard Jones <richard@users.sourceforge.net>
parents: 1002
diff changeset
720 # reopen the database as the correct user
f89b8d32291b Hack hack hack...
Richard Jones <richard@users.sourceforge.net>
parents: 1002
diff changeset
721 self.opendb(self.user)
f89b8d32291b Hack hack hack...
Richard Jones <richard@users.sourceforge.net>
parents: 1002
diff changeset
722
2940
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
723 def opendb(self, username):
3427
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
724 """Open the database and set the current user.
2940
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
725
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
726 Opens a database once. On subsequent calls only the user is set on
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
727 the database object the instance.optimize is set. If we are in
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
728 "Development Mode" (cf. roundup_server) then the database is always
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
729 re-opened.
3427
198fe87b0254 add language detection (patch [SF#1360321])
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3396
diff changeset
730 """
2940
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
731 # don't do anything if the db is open and the user has not changed
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
732 if hasattr(self, 'db') and self.db.isCurrentUser(username):
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
733 return
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
734
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
735 # open the database or only set the user
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
736 if not hasattr(self, 'db'):
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
737 self.db = self.instance.open(username)
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
738 else:
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
739 if self.instance.optimize:
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
740 self.db.setCurrentUser(username)
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
741 else:
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
742 self.db.close()
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
743 self.db = self.instance.open(username)
4212
51a098592b78 Reopen session with database.
Stefan Seefeld <stefan@seefeld.name>
parents: 4145
diff changeset
744 # The old session API refers to the closed database;
51a098592b78 Reopen session with database.
Stefan Seefeld <stefan@seefeld.name>
parents: 4145
diff changeset
745 # we can no longer use it.
51a098592b78 Reopen session with database.
Stefan Seefeld <stefan@seefeld.name>
parents: 4145
diff changeset
746 self.session_api = Session(self)
51a098592b78 Reopen session with database.
Stefan Seefeld <stefan@seefeld.name>
parents: 4145
diff changeset
747
2940
00f609d53a8c tweaks to last patch
Richard Jones <richard@users.sourceforge.net>
parents: 2938
diff changeset
748
2829
aa1cb9df09c3 ignore leading zeroes in the ID part of a node designator
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2808
diff changeset
749 def determine_context(self, dre=re.compile(r'([^\d]+)0*(\d+)')):
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
750 """Determine the context of this page from the URL:
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
751
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
752 The URL path after the instance identifier is examined. The path
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
753 is generally only one entry long.
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
754
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
755 - if there is no path, then we are in the "home" context.
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
756 - if the path is "_file", then the additional path entry
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
757 specifies the filename of a static file we're to serve up
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
758 from the instance "html" directory. Raises a SendStaticFile
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
759 exception.(*)
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
760 - if there is something in the path (eg "issue"), it identifies
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
761 the tracker class we're to display.
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
762 - if the path is an item designator (eg "issue123"), then we're
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
763 to display a specific item.
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
764 - if the path starts with an item designator and is longer than
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
765 one entry, then we're assumed to be handling an item of a
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
766 FileClass, and the extra path information gives the filename
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
767 that the client is going to label the download with (ie
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
768 "file123/image.png" is nicer to download than "file123"). This
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
769 raises a SendFile exception.(*)
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
770
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
771 Both of the "*" types of contexts stop before we bother to
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
772 determine the template we're going to use. That's because they
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
773 don't actually use templates.
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
774
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
775 The template used is specified by the :template CGI variable,
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
776 which defaults to:
1053
b28393def972 more explanatory docsting
Richard Jones <richard@users.sourceforge.net>
parents: 1051
diff changeset
777
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
778 - only classname suplied: "index"
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
779 - full item designator supplied: "item"
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
780
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
781 We set:
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
782
1041
c28603c9f831 Class help and generic class editing done.
Richard Jones <richard@users.sourceforge.net>
parents: 1029
diff changeset
783 self.classname - the class to display, can be None
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
784
1041
c28603c9f831 Class help and generic class editing done.
Richard Jones <richard@users.sourceforge.net>
parents: 1029
diff changeset
785 self.template - the template to render the current context with
2005
fc52d57c6c3e documentation cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
786
1041
c28603c9f831 Class help and generic class editing done.
Richard Jones <richard@users.sourceforge.net>
parents: 1029
diff changeset
787 self.nodeid - the nodeid of the class we're displaying
1937
4c850112895b Some reformatting and fixing docstrings for emacs.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 1936
diff changeset
788 """
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
789 # default the optional variables
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
790 self.classname = None
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
791 self.nodeid = None
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
792
1420
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
793 # see if a template or messages are specified
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
794 template_override = ok_message = error_message = None
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
795 for key in self.form.keys():
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
796 if self.FV_TEMPLATE.match(key):
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
797 template_override = self.form[key].value
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
798 elif self.FV_OK_MESSAGE.match(key):
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
799 ok_message = self.form[key].value
1684
b87c40d1b8fb fix hackish message escaping [SF#757128]
Richard Jones <richard@users.sourceforge.net>
parents: 1656
diff changeset
800 ok_message = clean_message(ok_message)
1420
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
801 elif self.FV_ERROR_MESSAGE.match(key):
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
802 error_message = self.form[key].value
1684
b87c40d1b8fb fix hackish message escaping [SF#757128]
Richard Jones <richard@users.sourceforge.net>
parents: 1656
diff changeset
803 error_message = clean_message(error_message)
1420
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
804
1977
f96592a7c357 changes to support the new templating Unauthorised exception.
Richard Jones <richard@users.sourceforge.net>
parents: 1973
diff changeset
805 # see if we were passed in a message
f96592a7c357 changes to support the new templating Unauthorised exception.
Richard Jones <richard@users.sourceforge.net>
parents: 1973
diff changeset
806 if ok_message:
f96592a7c357 changes to support the new templating Unauthorised exception.
Richard Jones <richard@users.sourceforge.net>
parents: 1973
diff changeset
807 self.ok_message.append(ok_message)
f96592a7c357 changes to support the new templating Unauthorised exception.
Richard Jones <richard@users.sourceforge.net>
parents: 1973
diff changeset
808 if error_message:
f96592a7c357 changes to support the new templating Unauthorised exception.
Richard Jones <richard@users.sourceforge.net>
parents: 1973
diff changeset
809 self.error_message.append(error_message)
f96592a7c357 changes to support the new templating Unauthorised exception.
Richard Jones <richard@users.sourceforge.net>
parents: 1973
diff changeset
810
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
811 # determine the classname and possibly nodeid
1157
26c8cb2162d7 fixed various URL / base URL issues
Richard Jones <richard@users.sourceforge.net>
parents: 1153
diff changeset
812 path = self.path.split('/')
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
813 if not path or path[0] in ('', 'home', 'index'):
1420
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
814 if template_override is not None:
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
815 self.template = template_override
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
816 else:
1041
c28603c9f831 Class help and generic class editing done.
Richard Jones <richard@users.sourceforge.net>
parents: 1029
diff changeset
817 self.template = ''
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
818 return
1911
f5c804379c85 fixed ZRoundup - mostly changes to classic template
Richard Jones <richard@users.sourceforge.net>
parents: 1905
diff changeset
819 elif path[0] in ('_file', '@@file'):
1427
37e712e77a99 trackers' templates directory can contain subdirectories with static files
Andrey Lebedev <kedder@users.sourceforge.net>
parents: 1426
diff changeset
820 raise SendStaticFile, os.path.join(*path[1:])
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
821 else:
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
822 self.classname = path[0]
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
823 if len(path) > 1:
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
824 # send the file identified by the designator in path[0]
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
825 raise SendFile, path[0]
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
826
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
827 # see if we got a designator
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
828 m = dre.match(self.classname)
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
829 if m:
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
830 self.classname = m.group(1)
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
831 self.nodeid = m.group(2)
3494
5a56abcf1b22 catch bad classname in URL (related to [SF#1240541])
Richard Jones <richard@users.sourceforge.net>
parents: 3453
diff changeset
832 try:
5a56abcf1b22 catch bad classname in URL (related to [SF#1240541])
Richard Jones <richard@users.sourceforge.net>
parents: 3453
diff changeset
833 klass = self.db.getclass(self.classname)
5a56abcf1b22 catch bad classname in URL (related to [SF#1240541])
Richard Jones <richard@users.sourceforge.net>
parents: 3453
diff changeset
834 except KeyError:
5a56abcf1b22 catch bad classname in URL (related to [SF#1240541])
Richard Jones <richard@users.sourceforge.net>
parents: 3453
diff changeset
835 raise NotFound, '%s/%s'%(self.classname, self.nodeid)
5a56abcf1b22 catch bad classname in URL (related to [SF#1240541])
Richard Jones <richard@users.sourceforge.net>
parents: 3453
diff changeset
836 if not klass.hasnode(self.nodeid):
1153
0455eccad866 raise not found earlier, where it makes more sense to the user
Richard Jones <richard@users.sourceforge.net>
parents: 1152
diff changeset
837 raise NotFound, '%s/%s'%(self.classname, self.nodeid)
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
838 # with a designator, we default to item view
1041
c28603c9f831 Class help and generic class editing done.
Richard Jones <richard@users.sourceforge.net>
parents: 1029
diff changeset
839 self.template = 'item'
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
840 else:
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
841 # with only a class, we default to index view
1041
c28603c9f831 Class help and generic class editing done.
Richard Jones <richard@users.sourceforge.net>
parents: 1029
diff changeset
842 self.template = 'index'
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
843
1288
ad8de51d7cd5 handle "classname" URL path errors cleaner (generate a 404)
Richard Jones <richard@users.sourceforge.net>
parents: 1277
diff changeset
844 # make sure the classname is valid
ad8de51d7cd5 handle "classname" URL path errors cleaner (generate a 404)
Richard Jones <richard@users.sourceforge.net>
parents: 1277
diff changeset
845 try:
ad8de51d7cd5 handle "classname" URL path errors cleaner (generate a 404)
Richard Jones <richard@users.sourceforge.net>
parents: 1277
diff changeset
846 self.db.getclass(self.classname)
ad8de51d7cd5 handle "classname" URL path errors cleaner (generate a 404)
Richard Jones <richard@users.sourceforge.net>
parents: 1277
diff changeset
847 except KeyError:
ad8de51d7cd5 handle "classname" URL path errors cleaner (generate a 404)
Richard Jones <richard@users.sourceforge.net>
parents: 1277
diff changeset
848 raise NotFound, self.classname
ad8de51d7cd5 handle "classname" URL path errors cleaner (generate a 404)
Richard Jones <richard@users.sourceforge.net>
parents: 1277
diff changeset
849
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
850 # see if we have a template override
1420
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
851 if template_override is not None:
3ac43c62a250 implemented extension to form parsing...
Richard Jones <richard@users.sourceforge.net>
parents: 1417
diff changeset
852 self.template = template_override
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
853
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
854 def serve_file(self, designator, dre=re.compile(r'([^\d]+)(\d+)')):
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
855 """ Serve the file from the content property of the designated item.
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
856 """
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
857 m = dre.match(str(designator))
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
858 if not m:
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
859 raise NotFound, str(designator)
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
860 classname, nodeid = m.group(1), m.group(2)
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
861
4263
bd000a1e9a57 Robustify web interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4224
diff changeset
862 try:
bd000a1e9a57 Robustify web interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4224
diff changeset
863 klass = self.db.getclass(classname)
bd000a1e9a57 Robustify web interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4224
diff changeset
864 except KeyError:
bd000a1e9a57 Robustify web interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4224
diff changeset
865 # The classname was not valid.
bd000a1e9a57 Robustify web interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4224
diff changeset
866 raise NotFound, str(designator)
bd000a1e9a57 Robustify web interface.
Stefan Seefeld <stefan@seefeld.name>
parents: 4224
diff changeset
867
1946
c538a64b94a7 Refactored CGI file serving so that FileClass contents are...
Richard Jones <richard@users.sourceforge.net>
parents: 1937
diff changeset
868
1967
d30cd44321f2 commit old file-serving bugfix, and new pt content-type fix
Richard Jones <richard@users.sourceforge.net>
parents: 1946
diff changeset
869 # make sure we have the appropriate properties
d30cd44321f2 commit old file-serving bugfix, and new pt content-type fix
Richard Jones <richard@users.sourceforge.net>
parents: 1946
diff changeset
870 props = klass.getprops()
1977
f96592a7c357 changes to support the new templating Unauthorised exception.
Richard Jones <richard@users.sourceforge.net>
parents: 1973
diff changeset
871 if not props.has_key('type'):
1967
d30cd44321f2 commit old file-serving bugfix, and new pt content-type fix
Richard Jones <richard@users.sourceforge.net>
parents: 1946
diff changeset
872 raise NotFound, designator
1977
f96592a7c357 changes to support the new templating Unauthorised exception.
Richard Jones <richard@users.sourceforge.net>
parents: 1973
diff changeset
873 if not props.has_key('content'):
1967
d30cd44321f2 commit old file-serving bugfix, and new pt content-type fix
Richard Jones <richard@users.sourceforge.net>
parents: 1946
diff changeset
874 raise NotFound, designator
d30cd44321f2 commit old file-serving bugfix, and new pt content-type fix
Richard Jones <richard@users.sourceforge.net>
parents: 1946
diff changeset
875
2870
795cdba40c05 enforce View Permission when serving file content [SF#1050470]
Richard Jones <richard@users.sourceforge.net>
parents: 2864
diff changeset
876 # make sure we have permission
795cdba40c05 enforce View Permission when serving file content [SF#1050470]
Richard Jones <richard@users.sourceforge.net>
parents: 2864
diff changeset
877 if not self.db.security.hasPermission('View', self.userid,
795cdba40c05 enforce View Permission when serving file content [SF#1050470]
Richard Jones <richard@users.sourceforge.net>
parents: 2864
diff changeset
878 classname, 'content', nodeid):
795cdba40c05 enforce View Permission when serving file content [SF#1050470]
Richard Jones <richard@users.sourceforge.net>
parents: 2864
diff changeset
879 raise Unauthorised, self._("You are not allowed to view "
795cdba40c05 enforce View Permission when serving file content [SF#1050470]
Richard Jones <richard@users.sourceforge.net>
parents: 2864
diff changeset
880 "this file.")
795cdba40c05 enforce View Permission when serving file content [SF#1050470]
Richard Jones <richard@users.sourceforge.net>
parents: 2864
diff changeset
881
1967
d30cd44321f2 commit old file-serving bugfix, and new pt content-type fix
Richard Jones <richard@users.sourceforge.net>
parents: 1946
diff changeset
882 mime_type = klass.get(nodeid, 'type')
4291
b1772fdb09d0 Fix traceback on .../msgN/ url...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4265
diff changeset
883 # Can happen for msg class:
b1772fdb09d0 Fix traceback on .../msgN/ url...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4265
diff changeset
884 if not mime_type:
b1772fdb09d0 Fix traceback on .../msgN/ url...
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 4265
diff changeset
885 mime_type = 'text/plain'
4047
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
886
4088
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
887 # if the mime_type is HTML-ish then make sure we're allowed to serve up
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
888 # HTML-ish content
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
889 if mime_type in ('text/html', 'text/x-html'):
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
890 if not self.instance.config['WEB_ALLOW_HTML_FILE']:
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
891 # do NOT serve the content up as HTML
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
892 mime_type = 'application/octet-stream'
34434785f308 Plug a number of security holes:
Richard Jones <richard@users.sourceforge.net>
parents: 4083
diff changeset
893
4047
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
894 # If this object is a file (i.e., an instance of FileClass),
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
895 # see if we can find it in the filesystem. If so, we may be
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
896 # able to use the more-efficient request.sendfile method of
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
897 # sending the file. If not, just get the "content" property
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
898 # in the usual way, and use that.
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
899 content = None
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
900 filename = None
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
901 if isinstance(klass, hyperdb.FileClass):
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
902 try:
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
903 filename = self.db.filename(classname, nodeid)
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
904 except AttributeError:
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
905 # The database doesn't store files in the filesystem
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
906 # and therefore doesn't provide the "filename" method.
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
907 pass
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
908 except IOError:
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
909 # The file does not exist.
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
910 pass
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
911 if not filename:
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
912 content = klass.get(nodeid, 'content')
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
913
1967
d30cd44321f2 commit old file-serving bugfix, and new pt content-type fix
Richard Jones <richard@users.sourceforge.net>
parents: 1946
diff changeset
914 lmt = klass.get(nodeid, 'activity').timestamp()
1946
c538a64b94a7 Refactored CGI file serving so that FileClass contents are...
Richard Jones <richard@users.sourceforge.net>
parents: 1937
diff changeset
915
4047
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
916 self._serve_file(lmt, mime_type, content, filename)
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
917
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
918 def serve_static_file(self, file):
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
919 """ Serve up the file named from the templates dir
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
920 """
2864
930e780c751f support STATIC_FILES directory in addition to TEMPLATES
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2853
diff changeset
921 # figure the filename - try STATIC_FILES, then TEMPLATES dir
930e780c751f support STATIC_FILES directory in addition to TEMPLATES
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2853
diff changeset
922 for dir_option in ('STATIC_FILES', 'TEMPLATES'):
930e780c751f support STATIC_FILES directory in addition to TEMPLATES
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2853
diff changeset
923 prefix = self.instance.config[dir_option]
930e780c751f support STATIC_FILES directory in addition to TEMPLATES
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2853
diff changeset
924 if not prefix:
930e780c751f support STATIC_FILES directory in addition to TEMPLATES
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2853
diff changeset
925 continue
930e780c751f support STATIC_FILES directory in addition to TEMPLATES
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2853
diff changeset
926 # ensure the load doesn't try to poke outside
930e780c751f support STATIC_FILES directory in addition to TEMPLATES
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2853
diff changeset
927 # of the static files directory
930e780c751f support STATIC_FILES directory in addition to TEMPLATES
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2853
diff changeset
928 prefix = os.path.normpath(prefix)
930e780c751f support STATIC_FILES directory in addition to TEMPLATES
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2853
diff changeset
929 filename = os.path.normpath(os.path.join(prefix, file))
930e780c751f support STATIC_FILES directory in addition to TEMPLATES
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2853
diff changeset
930 if os.path.isfile(filename) and filename.startswith(prefix):
930e780c751f support STATIC_FILES directory in addition to TEMPLATES
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2853
diff changeset
931 break
930e780c751f support STATIC_FILES directory in addition to TEMPLATES
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2853
diff changeset
932 else:
2366
1d46cd2f83f6 fix security hole in serve_static_file
Richard Jones <richard@users.sourceforge.net>
parents: 2279
diff changeset
933 raise NotFound, file
1946
c538a64b94a7 Refactored CGI file serving so that FileClass contents are...
Richard Jones <richard@users.sourceforge.net>
parents: 1937
diff changeset
934
c538a64b94a7 Refactored CGI file serving so that FileClass contents are...
Richard Jones <richard@users.sourceforge.net>
parents: 1937
diff changeset
935 # last-modified time
c538a64b94a7 Refactored CGI file serving so that FileClass contents are...
Richard Jones <richard@users.sourceforge.net>
parents: 1937
diff changeset
936 lmt = os.stat(filename)[stat.ST_MTIME]
c538a64b94a7 Refactored CGI file serving so that FileClass contents are...
Richard Jones <richard@users.sourceforge.net>
parents: 1937
diff changeset
937
c538a64b94a7 Refactored CGI file serving so that FileClass contents are...
Richard Jones <richard@users.sourceforge.net>
parents: 1937
diff changeset
938 # detemine meta-type
c538a64b94a7 Refactored CGI file serving so that FileClass contents are...
Richard Jones <richard@users.sourceforge.net>
parents: 1937
diff changeset
939 file = str(file)
c538a64b94a7 Refactored CGI file serving so that FileClass contents are...
Richard Jones <richard@users.sourceforge.net>
parents: 1937
diff changeset
940 mime_type = mimetypes.guess_type(file)[0]
c538a64b94a7 Refactored CGI file serving so that FileClass contents are...
Richard Jones <richard@users.sourceforge.net>
parents: 1937
diff changeset
941 if not mime_type:
c538a64b94a7 Refactored CGI file serving so that FileClass contents are...
Richard Jones <richard@users.sourceforge.net>
parents: 1937
diff changeset
942 if file.endswith('.css'):
c538a64b94a7 Refactored CGI file serving so that FileClass contents are...
Richard Jones <richard@users.sourceforge.net>
parents: 1937
diff changeset
943 mime_type = 'text/css'
c538a64b94a7 Refactored CGI file serving so that FileClass contents are...
Richard Jones <richard@users.sourceforge.net>
parents: 1937
diff changeset
944 else:
c538a64b94a7 Refactored CGI file serving so that FileClass contents are...
Richard Jones <richard@users.sourceforge.net>
parents: 1937
diff changeset
945 mime_type = 'text/plain'
c538a64b94a7 Refactored CGI file serving so that FileClass contents are...
Richard Jones <richard@users.sourceforge.net>
parents: 1937
diff changeset
946
4047
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
947 self._serve_file(lmt, mime_type, '', filename)
1946
c538a64b94a7 Refactored CGI file serving so that FileClass contents are...
Richard Jones <richard@users.sourceforge.net>
parents: 1937
diff changeset
948
4047
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
949 def _serve_file(self, lmt, mime_type, content=None, filename=None):
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
950 """ guts of serve_file() and serve_static_file()
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
951 """
4047
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
952
3736
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents: 3687
diff changeset
953 # spit out headers
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents: 3687
diff changeset
954 self.additional_headers['Content-Type'] = mime_type
3800
75d3896929bb really fix the last-modified code
Richard Jones <richard@users.sourceforge.net>
parents: 3796
diff changeset
955 self.additional_headers['Last-Modified'] = rfc822.formatdate(lmt)
3736
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents: 3687
diff changeset
956
1498
203f6a154b30 even better if-modified-since handling for cgi-bin
Andrey Lebedev <kedder@users.sourceforge.net>
parents: 1497
diff changeset
957 ims = None
1469
79d8956de3f5 implemented last-modified and if-modified-since support
Richard Jones <richard@users.sourceforge.net>
parents: 1468
diff changeset
958 # see if there's an if-modified-since...
3736
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents: 3687
diff changeset
959 # XXX see which interfaces set this
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents: 3687
diff changeset
960 #if hasattr(self.request, 'headers'):
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents: 3687
diff changeset
961 #ims = self.request.headers.getheader('if-modified-since')
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents: 3687
diff changeset
962 if self.env.has_key('HTTP_IF_MODIFIED_SINCE'):
1497
2704d8438823 better if-modified-since handling for cgi-bin
Richard Jones <richard@users.sourceforge.net>
parents: 1477
diff changeset
963 # cgi will put the header in the env var
1469
79d8956de3f5 implemented last-modified and if-modified-since support
Richard Jones <richard@users.sourceforge.net>
parents: 1468
diff changeset
964 ims = self.env['HTTP_IF_MODIFIED_SINCE']
79d8956de3f5 implemented last-modified and if-modified-since support
Richard Jones <richard@users.sourceforge.net>
parents: 1468
diff changeset
965 if ims:
79d8956de3f5 implemented last-modified and if-modified-since support
Richard Jones <richard@users.sourceforge.net>
parents: 1468
diff changeset
966 ims = rfc822.parsedate(ims)[:6]
3800
75d3896929bb really fix the last-modified code
Richard Jones <richard@users.sourceforge.net>
parents: 3796
diff changeset
967 lmtt = time.gmtime(lmt)[:6]
1469
79d8956de3f5 implemented last-modified and if-modified-since support
Richard Jones <richard@users.sourceforge.net>
parents: 1468
diff changeset
968 if lmtt <= ims:
79d8956de3f5 implemented last-modified and if-modified-since support
Richard Jones <richard@users.sourceforge.net>
parents: 1468
diff changeset
969 raise NotModified
79d8956de3f5 implemented last-modified and if-modified-since support
Richard Jones <richard@users.sourceforge.net>
parents: 1468
diff changeset
970
4047
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
971 if filename:
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
972 self.write_file(filename)
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
973 else:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
974 self.additional_headers['Content-Length'] = str(len(content))
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
975 self.write(content)
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
976
4264
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
977 def send_html_to_admin(self, subject, content):
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
978
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
979 to = [self.mailer.config.ADMIN_EMAIL]
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
980 message = self.mailer.get_standard_message(to, subject)
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
981 # delete existing content-type headers
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
982 del message['Content-type']
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
983 message['Content-type'] = 'text/html; charset=utf-8'
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
984 message.set_payload(content)
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
985 encode_quopri(message)
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
986 self.mailer.smtp_send(to, str(message))
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
987
4265
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
988 def renderFrontPage(self, message):
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
989 """Return the front page of the tracker."""
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
990
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
991 self.classname = self.nodeid = None
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
992 self.template = ''
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
993 self.error_message.append(message)
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
994 self.write_html(self.renderContext())
e24a6ca34448 Improve login failure response.
Stefan Seefeld <stefan@seefeld.name>
parents: 4264
diff changeset
995
1204
b862bbf2067a Replaced the content() callback ickiness with Page Template macro usage
Richard Jones <richard@users.sourceforge.net>
parents: 1196
diff changeset
996 def renderContext(self):
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
997 """ Return a PageTemplate for the named page
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
998 """
1204
b862bbf2067a Replaced the content() callback ickiness with Page Template macro usage
Richard Jones <richard@users.sourceforge.net>
parents: 1196
diff changeset
999 name = self.classname
b862bbf2067a Replaced the content() callback ickiness with Page Template macro usage
Richard Jones <richard@users.sourceforge.net>
parents: 1196
diff changeset
1000 extension = self.template
b862bbf2067a Replaced the content() callback ickiness with Page Template macro usage
Richard Jones <richard@users.sourceforge.net>
parents: 1196
diff changeset
1001
1103
db787cef1385 handled some XXXs
Richard Jones <richard@users.sourceforge.net>
parents: 1096
diff changeset
1002 # catch errors so we can handle PT rendering errors more nicely
1204
b862bbf2067a Replaced the content() callback ickiness with Page Template macro usage
Richard Jones <richard@users.sourceforge.net>
parents: 1196
diff changeset
1003 args = {
b862bbf2067a Replaced the content() callback ickiness with Page Template macro usage
Richard Jones <richard@users.sourceforge.net>
parents: 1196
diff changeset
1004 'ok_message': self.ok_message,
b862bbf2067a Replaced the content() callback ickiness with Page Template macro usage
Richard Jones <richard@users.sourceforge.net>
parents: 1196
diff changeset
1005 'error_message': self.error_message
b862bbf2067a Replaced the content() callback ickiness with Page Template macro usage
Richard Jones <richard@users.sourceforge.net>
parents: 1196
diff changeset
1006 }
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1007 try:
4027
39ad32d47cfb Catch missing page template errors.
Stefan Seefeld <stefan@seefeld.name>
parents: 3989
diff changeset
1008 pt = self.instance.templates.get(name, extension)
1016
d6c13142e7b9 Keep a cache of compiled PageTemplates.
Richard Jones <richard@users.sourceforge.net>
parents: 1008
diff changeset
1009 # let the template render figure stuff out
1967
d30cd44321f2 commit old file-serving bugfix, and new pt content-type fix
Richard Jones <richard@users.sourceforge.net>
parents: 1946
diff changeset
1010 result = pt.render(self, None, None, **args)
d30cd44321f2 commit old file-serving bugfix, and new pt content-type fix
Richard Jones <richard@users.sourceforge.net>
parents: 1946
diff changeset
1011 self.additional_headers['Content-Type'] = pt.content_type
2942
a50e4f7c9276 look for CGI_SHOW_TIMING in self.env instead of os.environ;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2940
diff changeset
1012 if self.env.get('CGI_SHOW_TIMING', ''):
a50e4f7c9276 look for CGI_SHOW_TIMING in self.env instead of os.environ;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2940
diff changeset
1013 if self.env['CGI_SHOW_TIMING'].upper() == 'COMMENT':
a50e4f7c9276 look for CGI_SHOW_TIMING in self.env instead of os.environ;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2940
diff changeset
1014 timings = {'starttag': '<!-- ', 'endtag': ' -->'}
a50e4f7c9276 look for CGI_SHOW_TIMING in self.env instead of os.environ;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2940
diff changeset
1015 else:
a50e4f7c9276 look for CGI_SHOW_TIMING in self.env instead of os.environ;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2940
diff changeset
1016 timings = {'starttag': '<p>', 'endtag': '</p>'}
a50e4f7c9276 look for CGI_SHOW_TIMING in self.env instead of os.environ;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2940
diff changeset
1017 timings['seconds'] = time.time()-self.start
a50e4f7c9276 look for CGI_SHOW_TIMING in self.env instead of os.environ;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2940
diff changeset
1018 s = self._('%(starttag)sTime elapsed: %(seconds)fs%(endtag)s\n'
a50e4f7c9276 look for CGI_SHOW_TIMING in self.env instead of os.environ;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2940
diff changeset
1019 ) % timings
2237
f624fc20f8fe added capturing of stats
Richard Jones <richard@users.sourceforge.net>
parents: 2233
diff changeset
1020 if hasattr(self.db, 'stats'):
2942
a50e4f7c9276 look for CGI_SHOW_TIMING in self.env instead of os.environ;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2940
diff changeset
1021 timings.update(self.db.stats)
a50e4f7c9276 look for CGI_SHOW_TIMING in self.env instead of os.environ;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2940
diff changeset
1022 s += self._("%(starttag)sCache hits: %(cache_hits)d,"
a50e4f7c9276 look for CGI_SHOW_TIMING in self.env instead of os.environ;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2940
diff changeset
1023 " misses %(cache_misses)d."
a50e4f7c9276 look for CGI_SHOW_TIMING in self.env instead of os.environ;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2940
diff changeset
1024 " Loading items: %(get_items)f secs."
a50e4f7c9276 look for CGI_SHOW_TIMING in self.env instead of os.environ;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2940
diff changeset
1025 " Filtering: %(filtering)f secs."
a50e4f7c9276 look for CGI_SHOW_TIMING in self.env instead of os.environ;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2940
diff changeset
1026 "%(endtag)s\n") % timings
2237
f624fc20f8fe added capturing of stats
Richard Jones <richard@users.sourceforge.net>
parents: 2233
diff changeset
1027 s += '</body>'
2230
ca2664e095be disable forking server when os.fork() not available [SF#938586]
Richard Jones <richard@users.sourceforge.net>
parents: 2183
diff changeset
1028 result = result.replace('</body>', s)
1967
d30cd44321f2 commit old file-serving bugfix, and new pt content-type fix
Richard Jones <richard@users.sourceforge.net>
parents: 1946
diff changeset
1029 return result
1977
f96592a7c357 changes to support the new templating Unauthorised exception.
Richard Jones <richard@users.sourceforge.net>
parents: 1973
diff changeset
1030 except templating.NoTemplate, message:
1068
665730c27d29 nicer template absence error
Richard Jones <richard@users.sourceforge.net>
parents: 1065
diff changeset
1031 return '<strong>%s</strong>'%message
1977
f96592a7c357 changes to support the new templating Unauthorised exception.
Richard Jones <richard@users.sourceforge.net>
parents: 1973
diff changeset
1032 except templating.Unauthorised, message:
f96592a7c357 changes to support the new templating Unauthorised exception.
Richard Jones <richard@users.sourceforge.net>
parents: 1973
diff changeset
1033 raise Unauthorised, str(message)
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1034 except:
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1035 # everything else
4045
82213b1971b4 Only feed back traceback to web users if config.WEB_DEBUG is True
Stefan Seefeld <stefan@seefeld.name>
parents: 4027
diff changeset
1036 if self.instance.config.WEB_DEBUG:
82213b1971b4 Only feed back traceback to web users if config.WEB_DEBUG is True
Stefan Seefeld <stefan@seefeld.name>
parents: 4027
diff changeset
1037 return cgitb.pt_html(i18n=self.translator)
82213b1971b4 Only feed back traceback to web users if config.WEB_DEBUG is True
Stefan Seefeld <stefan@seefeld.name>
parents: 4027
diff changeset
1038 exc_info = sys.exc_info()
82213b1971b4 Only feed back traceback to web users if config.WEB_DEBUG is True
Stefan Seefeld <stefan@seefeld.name>
parents: 4027
diff changeset
1039 try:
82213b1971b4 Only feed back traceback to web users if config.WEB_DEBUG is True
Stefan Seefeld <stefan@seefeld.name>
parents: 4027
diff changeset
1040 # If possible, send the HTML page template traceback
82213b1971b4 Only feed back traceback to web users if config.WEB_DEBUG is True
Stefan Seefeld <stefan@seefeld.name>
parents: 4027
diff changeset
1041 # to the administrator.
82213b1971b4 Only feed back traceback to web users if config.WEB_DEBUG is True
Stefan Seefeld <stefan@seefeld.name>
parents: 4027
diff changeset
1042 subject = "Templating Error: %s" % exc_info[1]
4264
b1e614c6759f Improve error reporting.
Stefan Seefeld <stefan@seefeld.name>
parents: 4263
diff changeset
1043 self.send_html_to_admin(subject, cgitb.pt_html())
4045
82213b1971b4 Only feed back traceback to web users if config.WEB_DEBUG is True
Stefan Seefeld <stefan@seefeld.name>
parents: 4027
diff changeset
1044 # Now report the error to the user.
82213b1971b4 Only feed back traceback to web users if config.WEB_DEBUG is True
Stefan Seefeld <stefan@seefeld.name>
parents: 4027
diff changeset
1045 return self._(error_message)
82213b1971b4 Only feed back traceback to web users if config.WEB_DEBUG is True
Stefan Seefeld <stefan@seefeld.name>
parents: 4027
diff changeset
1046 except:
82213b1971b4 Only feed back traceback to web users if config.WEB_DEBUG is True
Stefan Seefeld <stefan@seefeld.name>
parents: 4027
diff changeset
1047 # Reraise the original exception. The user will
82213b1971b4 Only feed back traceback to web users if config.WEB_DEBUG is True
Stefan Seefeld <stefan@seefeld.name>
parents: 4027
diff changeset
1048 # receive an error message, and the adminstrator will
82213b1971b4 Only feed back traceback to web users if config.WEB_DEBUG is True
Stefan Seefeld <stefan@seefeld.name>
parents: 4027
diff changeset
1049 # receive a traceback, albeit with less information
82213b1971b4 Only feed back traceback to web users if config.WEB_DEBUG is True
Stefan Seefeld <stefan@seefeld.name>
parents: 4027
diff changeset
1050 # than the one we tried to generate above.
82213b1971b4 Only feed back traceback to web users if config.WEB_DEBUG is True
Stefan Seefeld <stefan@seefeld.name>
parents: 4027
diff changeset
1051 raise exc_info[0], exc_info[1], exc_info[2]
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1052
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1053 # these are the actions that are available
2904
b1ad7add1a2c back out
Richard Jones <richard@users.sourceforge.net>
parents: 2903
diff changeset
1054 actions = (
b1ad7add1a2c back out
Richard Jones <richard@users.sourceforge.net>
parents: 2903
diff changeset
1055 ('edit', EditItemAction),
b1ad7add1a2c back out
Richard Jones <richard@users.sourceforge.net>
parents: 2903
diff changeset
1056 ('editcsv', EditCSVAction),
b1ad7add1a2c back out
Richard Jones <richard@users.sourceforge.net>
parents: 2903
diff changeset
1057 ('new', NewItemAction),
b1ad7add1a2c back out
Richard Jones <richard@users.sourceforge.net>
parents: 2903
diff changeset
1058 ('register', RegisterAction),
b1ad7add1a2c back out
Richard Jones <richard@users.sourceforge.net>
parents: 2903
diff changeset
1059 ('confrego', ConfRegoAction),
b1ad7add1a2c back out
Richard Jones <richard@users.sourceforge.net>
parents: 2903
diff changeset
1060 ('passrst', PassResetAction),
b1ad7add1a2c back out
Richard Jones <richard@users.sourceforge.net>
parents: 2903
diff changeset
1061 ('login', LoginAction),
b1ad7add1a2c back out
Richard Jones <richard@users.sourceforge.net>
parents: 2903
diff changeset
1062 ('logout', LogoutAction),
b1ad7add1a2c back out
Richard Jones <richard@users.sourceforge.net>
parents: 2903
diff changeset
1063 ('search', SearchAction),
b1ad7add1a2c back out
Richard Jones <richard@users.sourceforge.net>
parents: 2903
diff changeset
1064 ('retire', RetireAction),
b1ad7add1a2c back out
Richard Jones <richard@users.sourceforge.net>
parents: 2903
diff changeset
1065 ('show', ShowAction),
b1ad7add1a2c back out
Richard Jones <richard@users.sourceforge.net>
parents: 2903
diff changeset
1066 ('export_csv', ExportCSVAction),
b1ad7add1a2c back out
Richard Jones <richard@users.sourceforge.net>
parents: 2903
diff changeset
1067 )
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1068 def handle_action(self):
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
1069 """ Determine whether there should be an Action called.
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1070
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1071 The action is defined by the form variable :action which
1477
ed725179953d Added password reset facility for forgotten passwords.
Richard Jones <richard@users.sourceforge.net>
parents: 1472
diff changeset
1072 identifies the method on this object to call. The actions
2904
b1ad7add1a2c back out
Richard Jones <richard@users.sourceforge.net>
parents: 2903
diff changeset
1073 are defined in the "actions" sequence on this class.
2045
d124af927369 Forward-porting of fixes from the maintenance branch.
Richard Jones <richard@users.sourceforge.net>
parents: 2032
diff changeset
1074
d124af927369 Forward-porting of fixes from the maintenance branch.
Richard Jones <richard@users.sourceforge.net>
parents: 2032
diff changeset
1075 Actions may return a page (by default HTML) to return to the
d124af927369 Forward-porting of fixes from the maintenance branch.
Richard Jones <richard@users.sourceforge.net>
parents: 2032
diff changeset
1076 user, bypassing the usual template rendering.
3388
0c66acaea802 present Reject exception messages to web users [SF#1237685]
Richard Jones <richard@users.sourceforge.net>
parents: 3356
diff changeset
1077
0c66acaea802 present Reject exception messages to web users [SF#1237685]
Richard Jones <richard@users.sourceforge.net>
parents: 3356
diff changeset
1078 We explicitly catch Reject and ValueError exceptions and
0c66acaea802 present Reject exception messages to web users [SF#1237685]
Richard Jones <richard@users.sourceforge.net>
parents: 3356
diff changeset
1079 present their messages to the user.
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
1080 """
1467
378081f066cc registration is now a two-step process with confirmation from the
Richard Jones <richard@users.sourceforge.net>
parents: 1456
diff changeset
1081 if self.form.has_key(':action'):
378081f066cc registration is now a two-step process with confirmation from the
Richard Jones <richard@users.sourceforge.net>
parents: 1456
diff changeset
1082 action = self.form[':action'].value.lower()
378081f066cc registration is now a two-step process with confirmation from the
Richard Jones <richard@users.sourceforge.net>
parents: 1456
diff changeset
1083 elif self.form.has_key('@action'):
378081f066cc registration is now a two-step process with confirmation from the
Richard Jones <richard@users.sourceforge.net>
parents: 1456
diff changeset
1084 action = self.form['@action'].value.lower()
378081f066cc registration is now a two-step process with confirmation from the
Richard Jones <richard@users.sourceforge.net>
parents: 1456
diff changeset
1085 else:
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1086 return None
2638
18e86941c950 Load up extensions in the tracker "extensions" directory.
Richard Jones <richard@users.sourceforge.net>
parents: 2592
diff changeset
1087
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1088 try:
2948
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
1089 action_klass = self.get_action_class(action)
2019
8fab5d394f22 Call actions in a different way so we won't hide any bad TypeErrors.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2018
diff changeset
1090
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1091 # call the mapped action
2019
8fab5d394f22 Call actions in a different way so we won't hide any bad TypeErrors.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2018
diff changeset
1092 if isinstance(action_klass, type('')):
8fab5d394f22 Call actions in a different way so we won't hide any bad TypeErrors.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2018
diff changeset
1093 # old way of specifying actions
2045
d124af927369 Forward-porting of fixes from the maintenance branch.
Richard Jones <richard@users.sourceforge.net>
parents: 2032
diff changeset
1094 return getattr(self, action_klass)()
2019
8fab5d394f22 Call actions in a different way so we won't hide any bad TypeErrors.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 2018
diff changeset
1095 else:
2045
d124af927369 Forward-porting of fixes from the maintenance branch.
Richard Jones <richard@users.sourceforge.net>
parents: 2032
diff changeset
1096 return action_klass(self).execute()
2032
5a7ec0c63095 fixes to some unit tests, and a cleanup
Richard Jones <richard@users.sourceforge.net>
parents: 2019
diff changeset
1097
3388
0c66acaea802 present Reject exception messages to web users [SF#1237685]
Richard Jones <richard@users.sourceforge.net>
parents: 3356
diff changeset
1098 except (ValueError, Reject), err:
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 1987
diff changeset
1099 self.error_message.append(str(err))
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1100
2948
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
1101 def get_action_class(self, action_name):
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
1102 if (hasattr(self.instance, 'cgi_actions') and
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
1103 self.instance.cgi_actions.has_key(action_name)):
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
1104 # tracker-defined action
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
1105 action_klass = self.instance.cgi_actions[action_name]
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
1106 else:
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
1107 # go with a default
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
1108 for name, action_klass in self.actions:
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
1109 if name == action_name:
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
1110 break
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
1111 else:
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
1112 raise ValueError, 'No such action "%s"'%action_name
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
1113 return action_klass
deda13909085 factor out get_action_class so it may be called from other places
Richard Jones <richard@users.sourceforge.net>
parents: 2947
diff changeset
1114
3760
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
1115 def _socket_op(self, call, *args, **kwargs):
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
1116 """Execute socket-related operation, catch common network errors
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
1117
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
1118 Parameters:
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
1119 call: a callable to execute
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
1120 args, kwargs: call arguments
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
1121
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
1122 """
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
1123 try:
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
1124 call(*args, **kwargs)
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
1125 except socket.error, err:
3807
c27aafab067d Band-aid over handling of netework errors.
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3800
diff changeset
1126 err_errno = getattr (err, 'errno', None)
3808
36eb9e8faf30 Real handling of network errors.
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3807
diff changeset
1127 if err_errno is None:
36eb9e8faf30 Real handling of network errors.
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3807
diff changeset
1128 try:
36eb9e8faf30 Real handling of network errors.
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3807
diff changeset
1129 err_errno = err[0]
36eb9e8faf30 Real handling of network errors.
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3807
diff changeset
1130 except TypeError:
36eb9e8faf30 Real handling of network errors.
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3807
diff changeset
1131 pass
3807
c27aafab067d Band-aid over handling of netework errors.
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3800
diff changeset
1132 if err_errno not in self.IGNORE_NET_ERRORS:
3760
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
1133 raise
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1134 except IOError:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1135 # Apache's mod_python will raise IOError -- without an
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1136 # accompanying errno -- when a write to the client fails.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1137 # A common case is that the client has closed the
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1138 # connection. There's no way to be certain that this is
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1139 # the situation that has occurred here, but that is the
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1140 # most likely case.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1141 pass
3760
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
1142
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1143 def write(self, content):
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1144 if not self.headers_done:
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1145 self.header()
2592
5a8d9465827e implement the HTTP HEAD command [SF#992544]
Richard Jones <richard@users.sourceforge.net>
parents: 2565
diff changeset
1146 if self.env['REQUEST_METHOD'] != 'HEAD':
3760
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
1147 self._socket_op(self.request.wfile.write, content)
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1148
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1149 def write_html(self, content):
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1150 if not self.headers_done:
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1151 # at this point, we are sure about Content-Type
3867
2563ddf71cd7 Enabled over-riding of content-type in web interface (thanks John Mitchell)
Richard Jones <richard@users.sourceforge.net>
parents: 3808
diff changeset
1152 if not self.additional_headers.has_key('Content-Type'):
2563ddf71cd7 Enabled over-riding of content-type in web interface (thanks John Mitchell)
Richard Jones <richard@users.sourceforge.net>
parents: 3808
diff changeset
1153 self.additional_headers['Content-Type'] = \
2563ddf71cd7 Enabled over-riding of content-type in web interface (thanks John Mitchell)
Richard Jones <richard@users.sourceforge.net>
parents: 3808
diff changeset
1154 'text/html; charset=%s' % self.charset
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1155 self.header()
2592
5a8d9465827e implement the HTTP HEAD command [SF#992544]
Richard Jones <richard@users.sourceforge.net>
parents: 2565
diff changeset
1156
5a8d9465827e implement the HTTP HEAD command [SF#992544]
Richard Jones <richard@users.sourceforge.net>
parents: 2565
diff changeset
1157 if self.env['REQUEST_METHOD'] == 'HEAD':
5a8d9465827e implement the HTTP HEAD command [SF#992544]
Richard Jones <richard@users.sourceforge.net>
parents: 2565
diff changeset
1158 # client doesn't care about content
5a8d9465827e implement the HTTP HEAD command [SF#992544]
Richard Jones <richard@users.sourceforge.net>
parents: 2565
diff changeset
1159 return
5a8d9465827e implement the HTTP HEAD command [SF#992544]
Richard Jones <richard@users.sourceforge.net>
parents: 2565
diff changeset
1160
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1161 if self.charset != self.STORAGE_CHARSET:
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1162 # recode output
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1163 content = content.decode(self.STORAGE_CHARSET, 'replace')
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1164 content = content.encode(self.charset, 'xmlcharrefreplace')
2592
5a8d9465827e implement the HTTP HEAD command [SF#992544]
Richard Jones <richard@users.sourceforge.net>
parents: 2565
diff changeset
1165
5a8d9465827e implement the HTTP HEAD command [SF#992544]
Richard Jones <richard@users.sourceforge.net>
parents: 2565
diff changeset
1166 # and write
3760
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
1167 self._socket_op(self.request.wfile.write, content)
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1168
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1169 def http_strip(self, content):
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1170 """Remove HTTP Linear White Space from 'content'.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1171
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1172 'content' -- A string.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1173
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1174 returns -- 'content', with all leading and trailing LWS
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1175 removed."""
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1176
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1177 # RFC 2616 2.2: Basic Rules
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1178 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1179 # LWS = [CRLF] 1*( SP | HT )
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1180 return content.strip(" \r\n\t")
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1181
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1182 def http_split(self, content):
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1183 """Split an HTTP list.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1184
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1185 'content' -- A string, giving a list of items.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1186
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1187 returns -- A sequence of strings, containing the elements of
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1188 the list."""
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1189
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1190 # RFC 2616 2.1: Augmented BNF
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1191 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1192 # Grammar productions of the form "#rule" indicate a
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1193 # comma-separated list of elements matching "rule". LWS
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1194 # is then removed from each element, and empty elements
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1195 # removed.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1196
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1197 # Split at commas.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1198 elements = content.split(",")
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1199 # Remove linear whitespace at either end of the string.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1200 elements = [self.http_strip(e) for e in elements]
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1201 # Remove any now-empty elements.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1202 return [e for e in elements if e]
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1203
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1204 def handle_range_header(self, length, etag):
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1205 """Handle the 'Range' and 'If-Range' headers.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1206
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1207 'length' -- the length of the content available for the
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1208 resource.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1209
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1210 'etag' -- the entity tag for this resources.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1211
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1212 returns -- If the request headers (including 'Range' and
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1213 'If-Range') indicate that only a portion of the entity should
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1214 be returned, then the return value is a pair '(offfset,
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1215 length)' indicating the first byte and number of bytes of the
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1216 content that should be returned to the client. In addition,
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1217 this method will set 'self.response_code' to indicate Partial
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1218 Content. In all other cases, the return value is 'None'. If
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1219 appropriate, 'self.response_code' will be
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1220 set to indicate 'REQUESTED_RANGE_NOT_SATISFIABLE'. In that
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1221 case, the caller should not send any data to the client."""
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1222
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1223 # RFC 2616 14.35: Range
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1224 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1225 # See if the Range header is present.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1226 ranges_specifier = self.env.get("HTTP_RANGE")
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1227 if ranges_specifier is None:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1228 return None
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1229 # RFC 2616 14.27: If-Range
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1230 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1231 # Check to see if there is an If-Range header.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1232 # Because the specification says:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1233 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1234 # The If-Range header ... MUST be ignored if the request
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1235 # does not include a Range header, we check for If-Range
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1236 # after checking for Range.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1237 if_range = self.env.get("HTTP_IF_RANGE")
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1238 if if_range:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1239 # The grammar for the If-Range header is:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1240 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1241 # If-Range = "If-Range" ":" ( entity-tag | HTTP-date )
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1242 # entity-tag = [ weak ] opaque-tag
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1243 # weak = "W/"
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1244 # opaque-tag = quoted-string
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1245 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1246 # We only support strong entity tags.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1247 if_range = self.http_strip(if_range)
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1248 if (not if_range.startswith('"')
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1249 or not if_range.endswith('"')):
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1250 return None
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1251 # If the condition doesn't match the entity tag, then we
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1252 # must send the client the entire file.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1253 if if_range != etag:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1254 return
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1255 # The grammar for the Range header value is:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1256 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1257 # ranges-specifier = byte-ranges-specifier
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1258 # byte-ranges-specifier = bytes-unit "=" byte-range-set
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1259 # byte-range-set = 1#( byte-range-spec | suffix-byte-range-spec )
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1260 # byte-range-spec = first-byte-pos "-" [last-byte-pos]
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1261 # first-byte-pos = 1*DIGIT
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1262 # last-byte-pos = 1*DIGIT
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1263 # suffix-byte-range-spec = "-" suffix-length
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1264 # suffix-length = 1*DIGIT
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1265 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1266 # Look for the "=" separating the units from the range set.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1267 specs = ranges_specifier.split("=", 1)
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1268 if len(specs) != 2:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1269 return None
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1270 # Check that the bytes-unit is in fact "bytes". If it is not,
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1271 # we do not know how to process this range.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1272 bytes_unit = self.http_strip(specs[0])
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1273 if bytes_unit != "bytes":
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1274 return None
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1275 # Seperate the range-set into range-specs.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1276 byte_range_set = self.http_strip(specs[1])
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1277 byte_range_specs = self.http_split(byte_range_set)
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1278 # We only handle exactly one range at this time.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1279 if len(byte_range_specs) != 1:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1280 return None
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1281 # Parse the spec.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1282 byte_range_spec = byte_range_specs[0]
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1283 pos = byte_range_spec.split("-", 1)
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1284 if len(pos) != 2:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1285 return None
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1286 # Get the first and last bytes.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1287 first = self.http_strip(pos[0])
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1288 last = self.http_strip(pos[1])
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1289 # We do not handle suffix ranges.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1290 if not first:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1291 return None
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1292 # Convert the first and last positions to integers.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1293 try:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1294 first = int(first)
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1295 if last:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1296 last = int(last)
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1297 else:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1298 last = length - 1
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1299 except:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1300 # The positions could not be parsed as integers.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1301 return None
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1302 # Check that the range makes sense.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1303 if (first < 0 or last < 0 or last < first):
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1304 return None
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1305 if last >= length:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1306 # RFC 2616 10.4.17: 416 Requested Range Not Satisfiable
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1307 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1308 # If there is an If-Range header, RFC 2616 says that we
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1309 # should just ignore the invalid Range header.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1310 if if_range:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1311 return None
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1312 # Return code 416 with a Content-Range header giving the
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1313 # allowable range.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1314 self.response_code = httplib.REQUESTED_RANGE_NOT_SATISFIABLE
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1315 self.setHeader("Content-Range", "bytes */%d" % length)
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1316 return None
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1317 # RFC 2616 10.2.7: 206 Partial Content
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1318 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1319 # Tell the client that we are honoring the Range request by
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1320 # indicating that we are providing partial content.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1321 self.response_code = httplib.PARTIAL_CONTENT
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1322 # RFC 2616 14.16: Content-Range
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1323 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1324 # Tell the client what data we are providing.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1325 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1326 # content-range-spec = byte-content-range-spec
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1327 # byte-content-range-spec = bytes-unit SP
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1328 # byte-range-resp-spec "/"
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1329 # ( instance-length | "*" )
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1330 # byte-range-resp-spec = (first-byte-pos "-" last-byte-pos)
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1331 # | "*"
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1332 # instance-length = 1 * DIGIT
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1333 self.setHeader("Content-Range",
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1334 "bytes %d-%d/%d" % (first, last, length))
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1335 return (first, last - first + 1)
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1336
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1337 def write_file(self, filename):
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
1338 """Send the contents of 'filename' to the user."""
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1339
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1340 # Determine the length of the file.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1341 stat_info = os.stat(filename)
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1342 length = stat_info[stat.ST_SIZE]
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1343 # Assume we will return the entire file.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1344 offset = 0
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1345 # If the headers have not already been finalized,
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1346 if not self.headers_done:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1347 # RFC 2616 14.19: ETag
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1348 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1349 # Compute the entity tag, in a format similar to that
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1350 # used by Apache.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1351 etag = '"%x-%x-%x"' % (stat_info[stat.ST_INO],
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1352 length,
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1353 stat_info[stat.ST_MTIME])
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1354 self.setHeader("ETag", etag)
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1355 # RFC 2616 14.5: Accept-Ranges
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1356 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1357 # Let the client know that we will accept range requests.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1358 self.setHeader("Accept-Ranges", "bytes")
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1359 # RFC 2616 14.35: Range
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1360 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1361 # If there is a Range header, we may be able to avoid
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1362 # sending the entire file.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1363 content_range = self.handle_range_header(length, etag)
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1364 if content_range:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1365 offset, length = content_range
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1366 # RFC 2616 14.13: Content-Length
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1367 #
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1368 # Tell the client how much data we are providing.
4145
c15fcee3d8a1 Fix issue2550552.
Stefan Seefeld <stefan@seefeld.name>
parents: 4114
diff changeset
1369 self.setHeader("Content-Length", str(length))
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1370 # Send the HTTP header.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1371 self.header()
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1372 # If the client doesn't actually want the body, or if we are
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1373 # indicating an invalid range.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1374 if (self.env['REQUEST_METHOD'] == 'HEAD'
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1375 or self.response_code == httplib.REQUESTED_RANGE_NOT_SATISFIABLE):
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1376 return
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1377 # Use the optimized "sendfile" operation, if possible.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1378 if hasattr(self.request, "sendfile"):
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1379 self._socket_op(self.request.sendfile, filename, offset, length)
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1380 return
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1381 # Fallback to the "write" operation.
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1382 f = open(filename, 'rb')
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1383 try:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1384 if offset:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1385 f.seek(offset)
4077
7d19ed05baa6 Fix issue2550517
Stefan Seefeld <stefan@seefeld.name>
parents: 4065
diff changeset
1386 content = f.read(length)
4064
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1387 finally:
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1388 f.close()
662cd78df973 Add support for resuming (file) downloads.
Stefan Seefeld <stefan@seefeld.name>
parents: 4047
diff changeset
1389 self.write(content)
4047
e70643990e9c Support the use of sendfile() for file transfer, if available.
Stefan Seefeld <stefan@seefeld.name>
parents: 4046
diff changeset
1390
2046
f913b6beac35 document and make easier the actions-returning-content idiom
Richard Jones <richard@users.sourceforge.net>
parents: 2045
diff changeset
1391 def setHeader(self, header, value):
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
1392 """Override a header to be returned to the user's browser.
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
1393 """
2046
f913b6beac35 document and make easier the actions-returning-content idiom
Richard Jones <richard@users.sourceforge.net>
parents: 2045
diff changeset
1394 self.additional_headers[header] = value
f913b6beac35 document and make easier the actions-returning-content idiom
Richard Jones <richard@users.sourceforge.net>
parents: 2045
diff changeset
1395
1120
c26471971d18 Exposed the Batch mechanism through the top-level "utils" variable.
Richard Jones <richard@users.sourceforge.net>
parents: 1103
diff changeset
1396 def header(self, headers=None, response=None):
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
1397 """Put up the appropriate header.
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
1398 """
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1399 if headers is None:
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1400 headers = {'Content-Type':'text/html; charset=utf-8'}
1120
c26471971d18 Exposed the Batch mechanism through the top-level "utils" variable.
Richard Jones <richard@users.sourceforge.net>
parents: 1103
diff changeset
1401 if response is None:
c26471971d18 Exposed the Batch mechanism through the top-level "utils" variable.
Richard Jones <richard@users.sourceforge.net>
parents: 1103
diff changeset
1402 response = self.response_code
1130
89bd02ffe4af tell clients/caches not to cache our dynamic bits
Richard Jones <richard@users.sourceforge.net>
parents: 1129
diff changeset
1403
89bd02ffe4af tell clients/caches not to cache our dynamic bits
Richard Jones <richard@users.sourceforge.net>
parents: 1129
diff changeset
1404 # update with additional info
1120
c26471971d18 Exposed the Batch mechanism through the top-level "utils" variable.
Richard Jones <richard@users.sourceforge.net>
parents: 1103
diff changeset
1405 headers.update(self.additional_headers)
1130
89bd02ffe4af tell clients/caches not to cache our dynamic bits
Richard Jones <richard@users.sourceforge.net>
parents: 1129
diff changeset
1406
2279
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1407 if headers.get('Content-Type', 'text/html') == 'text/html':
297e46e22e04 implemented HTTP charset negotiation.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2248
diff changeset
1408 headers['Content-Type'] = 'text/html; charset=utf-8'
3736
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents: 3687
diff changeset
1409
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents: 3687
diff changeset
1410 headers = headers.items()
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents: 3687
diff changeset
1411
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1412 for ((path, name), (value, expire)) in self._cookies.items():
3548
61d48244e7a8 login may now be for a single session
Richard Jones <richard@users.sourceforge.net>
parents: 3494
diff changeset
1413 cookie = "%s=%s; Path=%s;"%(name, value, path)
61d48244e7a8 login may now be for a single session
Richard Jones <richard@users.sourceforge.net>
parents: 3494
diff changeset
1414 if expire is not None:
61d48244e7a8 login may now be for a single session
Richard Jones <richard@users.sourceforge.net>
parents: 3494
diff changeset
1415 cookie += " expires=%s;"%Cookie._getdate(expire)
3736
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents: 3687
diff changeset
1416 headers.append(('Set-Cookie', cookie))
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents: 3687
diff changeset
1417
3760
b8f52d030f1a ignore common network errors, like "Connection reset by peer"
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3736
diff changeset
1418 self._socket_op(self.request.start_response, headers, response)
3736
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents: 3687
diff changeset
1419
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1420 self.headers_done = 1
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1421 if self.debug:
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1422 self.headers_sent = headers
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1423
2946
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1424 def add_cookie(self, name, value, expire=86400*365, path=None):
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1425 """Set a cookie value to be sent in HTTP headers
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1426
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1427 Parameters:
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1428 name:
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1429 cookie name
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1430 value:
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1431 cookie value
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1432 expire:
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1433 cookie expiration time (seconds).
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1434 If value is empty (meaning "delete cookie"),
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1435 expiration time is forced in the past
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1436 and this argument is ignored.
3548
61d48244e7a8 login may now be for a single session
Richard Jones <richard@users.sourceforge.net>
parents: 3494
diff changeset
1437 If None, the cookie will expire at end-of-session.
2946
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1438 If omitted, the cookie will be kept for a year.
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1439 path:
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1440 cookie path (optional)
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1441
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1442 """
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1443 if path is None:
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1444 path = self.cookie_path
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1445 if not value:
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1446 expire = -1
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1447 self._cookies[(path, name)] = (value, expire)
2946
661028d24cd2 support for multiple cookie headers in single http response;
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2942
diff changeset
1448
3548
61d48244e7a8 login may now be for a single session
Richard Jones <richard@users.sourceforge.net>
parents: 3494
diff changeset
1449 def set_cookie(self, user, expire=None):
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1450 """Deprecated. Use session_api calls directly
2233
3d9bb1a052d1 fix random seeding for forking server
Richard Jones <richard@users.sourceforge.net>
parents: 2230
diff changeset
1451
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1452 XXX remove
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1453 """
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1454
3989
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1455 # insert the session in the session db
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1456 self.session_api.set(user=user)
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1457 # refresh session cookie
0112e9e1d068 improvements to session management
Richard Jones <richard@users.sourceforge.net>
parents: 3916
diff changeset
1458 self.session_api.update(set_cookie=True, expire=expire)
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1459
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1460 def make_user_anonymous(self):
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
1461 """ Make us anonymous
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1462
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1463 This method used to handle non-existence of the 'anonymous'
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1464 user, but that user is mandatory now.
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
1465 """
985
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1466 self.userid = self.db.user.lookup('anonymous')
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1467 self.user = 'anonymous'
55ab0c5b49f9 New CGI interface support
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1468
1801
9f9d35f3d8f7 Change the message asking for confirmation of registration...
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 1799
diff changeset
1469 def standard_message(self, to, subject, body, author=None):
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
1470 """Send a standard email message from Roundup.
2248
cd7e6d6288c6 fixed rego from email address [SF#947414]
Richard Jones <richard@users.sourceforge.net>
parents: 2246
diff changeset
1471
cd7e6d6288c6 fixed rego from email address [SF#947414]
Richard Jones <richard@users.sourceforge.net>
parents: 2246
diff changeset
1472 "to" - recipients list
cd7e6d6288c6 fixed rego from email address [SF#947414]
Richard Jones <richard@users.sourceforge.net>
parents: 2246
diff changeset
1473 "subject" - Subject
cd7e6d6288c6 fixed rego from email address [SF#947414]
Richard Jones <richard@users.sourceforge.net>
parents: 2246
diff changeset
1474 "body" - Message
cd7e6d6288c6 fixed rego from email address [SF#947414]
Richard Jones <richard@users.sourceforge.net>
parents: 2246
diff changeset
1475 "author" - (name, address) tuple or None for admin email
cd7e6d6288c6 fixed rego from email address [SF#947414]
Richard Jones <richard@users.sourceforge.net>
parents: 2246
diff changeset
1476
cd7e6d6288c6 fixed rego from email address [SF#947414]
Richard Jones <richard@users.sourceforge.net>
parents: 2246
diff changeset
1477 Arguments are passed to the Mailer.standard_message code.
4065
1e28d58c6d1c Uniformly use """...""" instead of '''...''' for comments.
Stefan Seefeld <stefan@seefeld.name>
parents: 4064
diff changeset
1478 """
1799
071ea6fc803f Extracted duplicated mail-sending code...
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 1798
diff changeset
1479 try:
1801
9f9d35f3d8f7 Change the message asking for confirmation of registration...
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 1799
diff changeset
1480 self.mailer.standard_message(to, subject, body, author)
1802
fe9d122f1bb1 Fix misnamed exception clause.
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 1801
diff changeset
1481 except MessageSendError, e:
1799
071ea6fc803f Extracted duplicated mail-sending code...
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents: 1798
diff changeset
1482 self.error_message.append(str(e))
2248
cd7e6d6288c6 fixed rego from email address [SF#947414]
Richard Jones <richard@users.sourceforge.net>
parents: 2246
diff changeset
1483 return 0
cd7e6d6288c6 fixed rego from email address [SF#947414]
Richard Jones <richard@users.sourceforge.net>
parents: 2246
diff changeset
1484 return 1
1467
378081f066cc registration is now a two-step process with confirmation from the
Richard Jones <richard@users.sourceforge.net>
parents: 1456
diff changeset
1485
2107
b7404a96b58a minor pre-release / test fixes
Richard Jones <richard@users.sourceforge.net>
parents: 2082
diff changeset
1486 def parsePropsFromForm(self, create=0):
2010
1b11ffd8015e forward-porting of fixed edit action / parsePropsFromForm...
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
1487 return FormParser(self).parse(create=create)
1b11ffd8015e forward-porting of fixed edit action / parsePropsFromForm...
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
1488
2799
9605965569b0 disallow caching of pages with error and/or ok messages.
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2724
diff changeset
1489 # vim: set et sts=4 sw=4 :

Roundup Issue Tracker: http://roundup-tracker.org/