--- a/thirdparty/google_appengine/google/appengine/tools/dev_appserver.py Sat Dec 06 14:50:45 2008 +0000
+++ b/thirdparty/google_appengine/google/appengine/tools/dev_appserver.py Sat Dec 06 16:52:21 2008 +0000
@@ -46,6 +46,7 @@
import imp
import inspect
import itertools
+import locale
import logging
import mimetools
import mimetypes
@@ -111,6 +112,10 @@
('.wbmp', 'image/vnd.wap.wbmp')):
mimetypes.add_type(mime_type, ext)
+MAX_RUNTIME_RESPONSE_SIZE = 1 << 20
+
+MAX_REQUEST_SIZE = 10 * 1024 * 1024
+
class Error(Exception):
"""Base-class for exceptions in this module."""
@@ -570,6 +575,13 @@
return ('Linux', '', '', '', '')
+def FakeSetLocale(category, value=None, original_setlocale=locale.setlocale):
+ """Fake version of locale.setlocale that only supports the default."""
+ if value not in (None, '', 'C', 'POSIX'):
+ raise locale.Error, 'locale emulation only supports "C" locale'
+ return original_setlocale(category, 'C')
+
+
def IsPathInSubdirectories(filename,
subdirectories,
normcase=os.path.normcase):
@@ -681,7 +693,8 @@
if os.path.isfile(filename))
ALLOWED_DIRS = set([
- os.path.normcase(os.path.realpath(os.path.dirname(os.__file__)))
+ os.path.normcase(os.path.realpath(os.path.dirname(os.__file__))),
+ os.path.normcase(os.path.abspath(os.path.dirname(os.__file__))),
])
NOT_ALLOWED_DIRS = set([
@@ -713,8 +726,10 @@
Args:
root_path: Path to the root of the application.
"""
- FakeFile._application_paths = set(os.path.abspath(path)
- for path in application_paths)
+ FakeFile._application_paths = (set(os.path.realpath(path)
+ for path in application_paths) |
+ set(os.path.abspath(path)
+ for path in application_paths))
@staticmethod
def IsFileAccessible(filename, normcase=os.path.normcase):
@@ -756,7 +771,7 @@
return False
- def __init__(self, filename, mode='r', **kwargs):
+ def __init__(self, filename, mode='r', bufsize=-1, **kwargs):
"""Initializer. See file built-in documentation."""
if mode not in FakeFile.ALLOWED_MODES:
raise IOError('invalid mode: %s' % mode)
@@ -764,7 +779,7 @@
if not FakeFile.IsFileAccessible(filename):
raise IOError(errno.EACCES, 'file not accessible')
- super(FakeFile, self).__init__(filename, mode, **kwargs)
+ super(FakeFile, self).__init__(filename, mode, bufsize, **kwargs)
class RestrictedPathFunction(object):
@@ -1024,9 +1039,14 @@
]
_MODULE_OVERRIDES = {
+ 'locale': {
+ 'setlocale': FakeSetLocale,
+ },
+
'os': {
'listdir': RestrictedPathFunction(os.listdir),
- 'lstat': RestrictedPathFunction(os.lstat),
+
+ 'lstat': RestrictedPathFunction(os.stat),
'stat': RestrictedPathFunction(os.stat),
'uname': FakeUname,
'urandom': FakeURandom,
@@ -1535,7 +1555,8 @@
depth_count += 1
for index in xrange(depth_count):
- current_init_file = os.path.join(module_base, '__init__.py')
+ current_init_file = os.path.abspath(
+ os.path.join(module_base, '__init__.py'))
if not isfile(current_init_file):
missing_init_files.append(current_init_file)
@@ -2403,6 +2424,15 @@
infile = cStringIO.StringIO(self.rfile.read(
int(self.headers.get('content-length', 0))))
+
+ request_size = len(infile.getvalue())
+ if request_size > MAX_REQUEST_SIZE:
+ msg = ('HTTP request was too large: %d. The limit is: %d.'
+ % (request_size, MAX_REQUEST_SIZE))
+ logging.error(msg)
+ self.send_response(httplib.REQUEST_ENTITY_TOO_LARGE, msg)
+ return
+
outfile = cStringIO.StringIO()
try:
dispatcher.Dispatch(self.path,
@@ -2416,8 +2446,21 @@
outfile.flush()
outfile.seek(0)
+
status_code, status_message, header_data, body = RewriteResponse(outfile)
+ runtime_response_size = len(outfile.getvalue())
+ if runtime_response_size > MAX_RUNTIME_RESPONSE_SIZE:
+ status_code = 403
+ status_message = 'Forbidden'
+ new_headers = []
+ for header in header_data.split('\n'):
+ if not header.lower().startswith('content-length'):
+ new_headers.append(header)
+ header_data = '\n'.join(new_headers)
+ body = ('HTTP response was too large: %d. The limit is: %d.'
+ % (runtime_response_size, MAX_RUNTIME_RESPONSE_SIZE))
+
except yaml_errors.EventListenerError, e:
title = 'Fatal error when loading application configuration'
msg = '%s:\n%s' % (title, str(e))