from zope.publisher.http import HTTPRequest from zope.publisher.browser import BrowserRequest from zope.publisher.xmlrpc import XMLRPCRequest from zope.interface import directlyProvides from zope.app import zapi from zope.app.publication.httpfactory import HTTPPublicationRequestFactory _browser_methods = 'GET', 'POST', 'HEAD' # TODO make this configurable through a ZConfig file _dav_user_agents = ['cadaver/0.22.2 neon/0.24.7', 'cadaver/0.20.5 neon/0.23.9', 'neon/0.23.9 cadaver/0.20.5'] class DAVUserAgentFactory31(HTTPPublicationRequestFactory): def __call__(self, input_stream, output_steam, env): """See `zope.app.publication.interfaces.IPublicationRequestFactory`""" method = env.get('REQUEST_METHOD', 'GET').upper() # only make a distinction if we're dealing with browser # methods at all if method not in _browser_methods: request = HTTPRequest(input_stream, output_steam, env) request.setPublication(self._http) return request content_type = env.get('CONTENT_TYPE', '') is_xml = content_type.startswith('text/xml') if (method == 'POST' and is_xml): # soap if (env.get('HTTP_SOAPACTION', None) and self._soapreq is not None): request = self._soapreq(input_stream, output_steam, env) request.setPublication(self._soappub) return request request = XMLRPCRequest(input_stream, output_steam, env) request.setPublication(self._xmlrpc) return request # check if we have a distinguished DAV client user_agent = env.get('HTTP_USER_AGENT', '') # TODO saner detection logic if user_agent in _dav_user_agents: request = HTTPRequest(input_stream, output_steam, env) request.setPublication(self._http) return request # fallback to a regular browser request: request = BrowserRequest(input_stream, output_steam, env) request.setPublication(self._brower) # Set the default skin adapters = zapi.getSiteManager().adapters skin = adapters.lookup((providedBy(request),), IDefaultSkin, '') if skin is not None: directlyProvides(request, directlyProvidedBy(request)+skin) else: directlyProvides(request, IDefaultBrowserLayer)