def get_resource(self, url, orig_req, log): """ Gets the resource at the given url, using the original request `orig_req` as the basis for constructing the subrequest. Returns a `webob.Response` object. """ assert url is not None if url.lower().startswith('file:'): if not display_local_files(orig_req): ## FIXME: not sure if this applies generally; some ## calls to get_resource might be because of a more ## valid subrequest than displaying a file return exc.HTTPForbidden( "You cannot access file: URLs (like %r)" % url) filename = url_to_filename(url) if not os.path.exists(filename): return exc.HTTPNotFound( "The file %r was not found" % filename) if os.path.isdir(filename): return exc.HTTPForbidden( "You cannot display a directory (%r)" % filename) subresp = Response() type, dummy = mimetypes.guess_type(filename) if not type: type = 'application/octet-stream' subresp.content_type = type ## FIXME: reading the whole thing obviously ain't great: f = open(filename, 'rb') subresp.body = f.read() f.close() return subresp elif url.startswith(orig_req.application_url + '/'): subreq = orig_req.copy_get() subreq.environ['deliverance.subrequest_original_environ'] = orig_req.environ #jhb subreq.environ['deliverance.subrequest_original_request'] = orig_req new_path_info = url[len(orig_req.application_url):] query_string = '' if '?' in new_path_info: new_path_info, query_string = new_path_info.split('?') new_path_info = urllib.unquote(new_path_info) assert new_path_info.startswith('/') subreq.path_info = new_path_info subreq.query_string = query_string subresp = subreq.get_response(self.app) ## FIXME: error if not HTML? ## FIXME: handle redirects? ## FIXME: handle non-200? log.debug(self, 'Internal request for %s: %s content-type: %s', url, subresp.status, subresp.content_type) return subresp else: ## FIXME: pluggable subrequest handler? subreq = Request.blank(url) subresp = subreq.get_response(proxy_exact_request) log.debug(self, 'External request for %s: %s content-type: %s', url, subresp.status, subresp.content_type) return subresp
def get_resource(self, url, orig_req, log, retry_inner_if_not_200=False): """ Gets the resource at the given url, using the original request `orig_req` as the basis for constructing the subrequest. Returns a `webob.Response` object. If `url.startswith(orig_req.application_url + '/')`, then Deliverance will try to fetch the resource by making a subrequest to the app that is being wrapped by Deliverance, instead of an external subrequest. This can cause problems in some setups -- see #16. To work around this, if `retry_inner_if_not_200` is True, then, in the situation described above, non-200 responses from the inner app will be tossed out, and the request will be retried as an external http request. Currently this is used only by RuleSet.get_theme """ assert url is not None force_external = 'deliv_force_external' in urlparse.urlsplit(url).query if url.lower().startswith('file:'): if not display_local_files(orig_req): ## FIXME: not sure if this applies generally; some ## calls to get_resource might be because of a more ## valid subrequest than displaying a file return exc.HTTPForbidden( "You cannot access file: URLs (like %r)" % url) filename = url_to_filename(url) if not os.path.exists(filename): return exc.HTTPNotFound("The file %r was not found" % filename) if os.path.isdir(filename): return exc.HTTPForbidden( "You cannot display a directory (%r)" % filename) subresp = Response() type, dummy = mimetypes.guess_type(filename) if not type: type = 'application/octet-stream' subresp.content_type = type ## FIXME: reading the whole thing obviously ain't great: f = open(filename, 'rb') subresp.body = f.read() f.close() return subresp elif not force_external and\ url.startswith(orig_req.application_url + '/'): subreq = orig_req.copy_get() subreq.environ[ 'deliverance.subrequest_original_environ'] = orig_req.environ new_path_info = url[len(orig_req.application_url):] query_string = '' if '?' in new_path_info: new_path_info, query_string = new_path_info.split('?', 1) new_path_info = urllib.unquote(new_path_info) assert new_path_info.startswith('/') subreq.path_info = new_path_info subreq.query_string = query_string subresp = subreq.get_response(self.app) ## FIXME: error if not HTML? ## FIXME: handle redirects? ## FIXME: handle non-200? log.debug(self, 'Internal request for %s: %s content-type: %s', url, subresp.status, subresp.content_type) if not retry_inner_if_not_200: return subresp if subresp.status_int == 200: return subresp elif 'x-deliverance-theme-subrequest' in orig_req.headers: log.debug( self, 'Internal request for %s was not 200 OK; ' 'returning it anyway.' % url) return subresp else: log.debug( self, 'Internal request for %s was not 200 OK; retrying as external request.' % url) ## FIXME: ZCA aptaperized subrequest handler subreq = self.build_external_subrequest(url, orig_req, log) subresp = subreq.get_response(proxy_exact_request) log.debug(self, 'External request for %s: %s content-type: %s', url, subresp.status, subresp.content_type) return subresp
def get_resource(self, url, orig_req, log, retry_inner_if_not_200=False): """ Gets the resource at the given url, using the original request `orig_req` as the basis for constructing the subrequest. Returns a `webob.Response` object. If `url.startswith(orig_req.application_url + '/')`, then Deliverance will try to fetch the resource by making a subrequest to the app that is being wrapped by Deliverance, instead of an external subrequest. This can cause problems in some setups -- see #16. To work around this, if `retry_inner_if_not_200` is True, then, in the situation described above, non-200 responses from the inner app will be tossed out, and the request will be retried as an external http request. Currently this is used only by RuleSet.get_theme """ assert url is not None if url.lower().startswith('file:'): if not display_local_files(orig_req): ## FIXME: not sure if this applies generally; some ## calls to get_resource might be because of a more ## valid subrequest than displaying a file return exc.HTTPForbidden( "You cannot access file: URLs (like %r)" % url) filename = url_to_filename(url) if not os.path.exists(filename): return exc.HTTPNotFound( "The file %r was not found" % filename) if os.path.isdir(filename): return exc.HTTPForbidden( "You cannot display a directory (%r)" % filename) subresp = Response() type, dummy = mimetypes.guess_type(filename) if not type: type = 'application/octet-stream' subresp.content_type = type ## FIXME: reading the whole thing obviously ain't great: f = open(filename, 'rb') subresp.body = f.read() f.close() return subresp elif self.use_internal_subrequest(url, orig_req, log): subreq = orig_req.copy_get() subreq.environ['deliverance.subrequest_original_environ'] = orig_req.environ new_path_info = url[len(orig_req.application_url):] query_string = '' if '?' in new_path_info: new_path_info, query_string = new_path_info.split('?', 1) new_path_info = urllib.unquote(new_path_info) assert new_path_info.startswith('/') subreq.path_info = new_path_info subreq.query_string = query_string subresp = subreq.get_response(self.app) ## FIXME: error if not HTML? ## FIXME: handle redirects? ## FIXME: handle non-200? log.debug(self, 'Internal request for %s: %s content-type: %s', url, subresp.status, subresp.content_type) if not retry_inner_if_not_200: return subresp if subresp.status_int == 200: return subresp elif 'x-deliverance-theme-subrequest' in orig_req.headers: log.debug(self, 'Internal request for %s was not 200 OK; ' 'returning it anyway.' % url) return subresp else: log.debug(self, 'Internal request for %s was not 200 OK; retrying as external request.' % url) ## FIXME: pluggable subrequest handler? subreq = self.build_external_subrequest(url, orig_req, log) subresp = subreq.get_response(proxy_exact_request) log.debug(self, 'External request for %s: %s content-type: %s', url, subresp.status, subresp.content_type) return subresp