[CalendarServer-changes] [8101] CalendarServer/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Wed Sep 14 13:08:59 PDT 2011
Revision: 8101
http://trac.macosforge.org/projects/calendarserver/changeset/8101
Author: cdaboo at apple.com
Date: 2011-09-14 13:08:58 -0700 (Wed, 14 Sep 2011)
Log Message:
-----------
Handle the case where an SSL decoder in front of the server hands us a non-SSL request but we need to
ensure absolute URIs have scheme/host/port set for SSL.
Modified Paths:
--------------
CalendarServer/trunk/calendarserver/tap/caldav.py
CalendarServer/trunk/twext/web2/server.py
CalendarServer/trunk/twext/web2/test/test_server.py
Modified: CalendarServer/trunk/calendarserver/tap/caldav.py
===================================================================
--- CalendarServer/trunk/calendarserver/tap/caldav.py 2011-09-14 18:01:07 UTC (rev 8100)
+++ CalendarServer/trunk/calendarserver/tap/caldav.py 2011-09-14 20:08:58 UTC (rev 8101)
@@ -1,6 +1,6 @@
# -*- test-case-name: calendarserver.tap.test.test_caldav -*-
##
-# Copyright (c) 2005-2010 Apple Inc. All rights reserved.
+# Copyright (c) 2005-2011 Apple Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -162,7 +162,7 @@
class ErrorLoggingMultiService(MultiService):
- """ Registers a rotating file logger for error logging, iff
+ """ Registers a rotating file logger for error logging, if
config.ErrorLogEnabled is True. """
def setServiceParent(self, app):
@@ -261,7 +261,7 @@
def opt_option(self, option):
"""
Set an option to override a value in the config file. True, False, int,
- and float options are supported, as well as comma seperated lists. Only
+ and float options are supported, as well as comma separated lists. Only
one option may be given for each --option flag, however multiple
--option flags may be specified.
"""
@@ -592,7 +592,7 @@
import signal
def sighup_handler(num, frame):
- self.log_info("SIGHUP recieved at %s" % (location(frame),))
+ self.log_info("SIGHUP received at %s" % (location(frame),))
# Reload the config file
try:
@@ -725,6 +725,13 @@
rootResource = getRootResource(config, store, additional)
underlyingSite = Site(rootResource)
+
+ # Need to cache SSL port info here so we can access it in a Request to deal with the
+ # possibility of being behind an SSL decoder
+ underlyingSite.EnableSSL = config.EnableSSL
+ underlyingSite.SSLPort = config.SSLPort
+ underlyingSite.BindSSLPorts = config.BindSSLPorts
+
requestFactory = underlyingSite
if config.RedirectHTTPToHTTPS:
@@ -891,7 +898,7 @@
main service.
This has the effect of delaying any child process spawning or
- standalone port-binding until the backing for the selected data store
+ stand alone port-binding until the backing for the selected data store
implementation is ready to process requests.
@param createMainService: This is the service that will be doing the main
@@ -1439,7 +1446,7 @@
def startService(self):
- # Now we're ready to build the command lines and actualy add the
+ # Now we're ready to build the command lines and actually add the
# processes to procmon.
super(DelayedStartupProcessMonitor, self).startService()
for name in self.processes:
@@ -1513,7 +1520,7 @@
del self.protocols[name]
if self._reactor.seconds() - self.timeStarted[name] < self.threshold:
- # The process died too fast - backoff
+ # The process died too fast - back off
nextDelay = self.delay[name]
self.delay[name] = min(self.delay[name] * 2, self.maxRestartDelay)
Modified: CalendarServer/trunk/twext/web2/server.py
===================================================================
--- CalendarServer/trunk/twext/web2/server.py 2011-09-14 18:01:07 UTC (rev 8100)
+++ CalendarServer/trunk/twext/web2/server.py 2011-09-14 20:08:58 UTC (rev 8101)
@@ -1,7 +1,7 @@
# -*- test-case-name: twext.web2.test.test_server -*-
##
# Copyright (c) 2001-2008 Twisted Matrix Laboratories.
-# Copyright (c) 2010 Apple Computer, Inc. All rights reserved.
+# Copyright (c) 2010-2011 Apple Computer, Inc. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -296,6 +296,31 @@
self.postpath = path
#print "_parseURL", self.uri, (self.uri, self.scheme, self.host, self.path, self.params, self.querystring)
+ def _schemeFromPort(self, port):
+ """
+ Try to determine the scheme matching the supplied server port. This is needed in case
+ where a device in front of the server is changing the scheme (e.g. decoding SSL) but not
+ rewriting the scheme in URIs returned in responses (e.g. in Location headers). This could trick
+ clients into using an inappropriate scheme for subsequent requests. What we should do is
+ take the port number from the Host header or request-URI and map that to the scheme that
+ matches the service we configured to listen on that port.
+
+ @param port: the port number to test
+ @type port: C{int}
+
+ @return: C{True} if scheme is https (secure), C{False} otherwise
+ @rtype: C{bool}
+ """
+
+ #from twistedcaldav.config import config
+ if hasattr(self.site, "EnableSSL") and self.site.EnableSSL:
+ if port == self.site.SSLPort:
+ return True
+ elif port in self.site.BindSSLPorts:
+ return True
+
+ return False
+
def _fixupURLParts(self):
hostaddr, secure = self.chanRequest.getHostInfo()
if not self.scheme:
@@ -303,11 +328,13 @@
if self.host:
self.host, self.port = http.splitHostPort(self.scheme, self.host)
+ self.scheme = ('http', 'https')[self._schemeFromPort(self.port)]
else:
# If GET line wasn't an absolute URL
host = self.headers.getHeader('host')
if host:
self.host, self.port = http.splitHostPort(self.scheme, host)
+ self.scheme = ('http', 'https')[self._schemeFromPort(self.port)]
else:
# When no hostname specified anywhere, either raise an
# error, or use the interface hostname, depending on
@@ -465,7 +492,7 @@
nor whether the same URL is returned in subsequent calls.
@param resource: the resource to find a URI for. This resource must
- have been obtained from the request (ie. via its C{uri} attribute, or
+ have been obtained from the request (i.e. via its C{uri} attribute, or
through its C{locateResource} or C{locateChildResource} methods).
@return: a valid URL for C{resource} in this request.
@raise NoURLForResourceError: if C{resource} has no URL in this request
@@ -544,7 +571,7 @@
resource. This is similar to locateResource(), but doesn't have to
start the lookup from the root resource, so it is potentially faster.
@param parent: the parent of the resource being looked up. This resource
- must have been obtained from the request (ie. via its C{uri} attribute,
+ must have been obtained from the request (i.e. via its C{uri} attribute,
or through its C{locateResource} or C{locateChildResource} methods).
@param childName: the name of the child of C{parent} to looked up.
to C{parent}.
@@ -599,7 +626,7 @@
log.err(origReason)
body = ("<html><head><title>Internal Server Error</title></head>"
- "<body><h1>Internal Server Error</h1>An error occurred rendering the requested page. Additionally, an error occured rendering the error page.</body></html>")
+ "<body><h1>Internal Server Error</h1>An error occurred rendering the requested page. Additionally, an error occurred rendering the error page.</body></html>")
response = http.Response(
responsecode.INTERNAL_SERVER_ERROR,
Modified: CalendarServer/trunk/twext/web2/test/test_server.py
===================================================================
--- CalendarServer/trunk/twext/web2/test/test_server.py 2011-09-14 18:01:07 UTC (rev 8100)
+++ CalendarServer/trunk/twext/web2/test/test_server.py 2011-09-14 20:08:58 UTC (rev 8101)
@@ -116,7 +116,7 @@
class SimpleRequest(server.Request):
"""I can be used in cases where a Request object is necessary
- but it is benificial to bypass the chanRequest
+ but it is beneficial to bypass the chanRequest
"""
clientproto = (1,1)
@@ -362,7 +362,58 @@
(redirectResource, 'http://localhost/'),
(301, {'location': 'https://localhost/foo?bar=baz'}, None))
+ def test_redirectResourceWithSchemeRemapping(self):
+ def chanrequest2(root, uri, length, headers, method, version, prepath, content):
+ site = server.Site(root)
+ site.EnableSSL = True
+ site.SSLPort = 8443
+ site.BindSSLPorts = []
+ return TestChanRequest(site, method, prepath, uri, length, headers, version, content)
+
+ self.patch(self, "chanrequest", chanrequest2)
+
+ redirectResource = resource.RedirectResource(path='/foo')
+
+ return self.assertResponse(
+ (redirectResource, 'http://localhost:8443/'),
+ (301, {'location': 'https://localhost:8443/foo'}, None))
+
+ def test_redirectResourceWithoutSchemeRemapping(self):
+
+ def chanrequest2(root, uri, length, headers, method, version, prepath, content):
+ site = server.Site(root)
+ site.EnableSSL = True
+ site.SSLPort = 8443
+ site.BindSSLPorts = []
+ return TestChanRequest(site, method, prepath, uri, length, headers, version, content)
+
+ self.patch(self, "chanrequest", chanrequest2)
+
+ redirectResource = resource.RedirectResource(path='/foo')
+
+ return self.assertResponse(
+ (redirectResource, 'http://localhost:8008/'),
+ (301, {'location': 'http://localhost:8008/foo'}, None))
+
+ def test_redirectResourceWithoutSSLSchemeRemapping(self):
+
+ def chanrequest2(root, uri, length, headers, method, version, prepath, content):
+ site = server.Site(root)
+ site.EnableSSL = False
+ site.SSLPort = 8443
+ site.BindSSLPorts = []
+ return TestChanRequest(site, method, prepath, uri, length, headers, version, content)
+
+ self.patch(self, "chanrequest", chanrequest2)
+
+ redirectResource = resource.RedirectResource(path='/foo')
+
+ return self.assertResponse(
+ (redirectResource, 'http://localhost:8443/'),
+ (301, {'location': 'http://localhost:8443/foo'}, None))
+
+
class URLParsingTest(BaseCase):
class TestResource(resource.LeafResource):
def render(self, req):
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110914/3f0e713c/attachment-0001.html>
More information about the calendarserver-changes
mailing list