server-side fixes for double-escaped base_url

This commit is contained in:
Min RK 2015-09-21 13:19:14 +02:00
parent 164c3b6c1a
commit 8de725a8de
8 changed files with 41 additions and 37 deletions

View File

@ -564,7 +564,7 @@ class FilesRedirectHandler(IPythonHandler):
cm = self.contents_manager
if cm.dir_exists(path):
# it's a *directory*, redirect to /tree
url = url_path_join(self.base_url, 'tree', path)
url = url_path_join(self.base_url, 'tree', url_escape(path))
else:
orig_path = path
# otherwise, redirect to /files
@ -580,8 +580,7 @@ class FilesRedirectHandler(IPythonHandler):
if not cm.file_exists(path=path):
raise web.HTTPError(404)
url = url_path_join(self.base_url, 'files', path)
url = url_escape(url)
url = url_path_join(self.base_url, 'files', url_escape(path))
self.log.debug("Redirecting %s to %s", self.request.path, url)
self.redirect(url)

View File

@ -87,9 +87,9 @@ class ContentsHandler(APIHandler):
path : unicode
The API path of the file, such as "foo/bar.txt".
"""
return url_escape(url_path_join(
self.base_url, 'api', 'contents', path
))
return url_path_join(
self.base_url, 'api', 'contents', url_escape(path)
)
def _finish_model(self, model, location=True):
"""Finish a JSON request with a model, setting relevant headers, etc."""
@ -280,8 +280,8 @@ class CheckpointsHandler(APIHandler):
checkpoint = yield gen.maybe_future(cm.create_checkpoint(path))
data = json.dumps(checkpoint, default=date_default)
location = url_path_join(self.base_url, 'api/contents',
path, 'checkpoints', checkpoint['id'])
self.set_header('Location', url_escape(location))
url_escape(path), 'checkpoints', url_escape(checkpoint['id']))
self.set_header('Location', location)
self.set_status(201)
self.finish(data)

View File

@ -338,7 +338,7 @@ class APITest(NotebookTestBase):
def _check_created(self, resp, path, type='notebook'):
self.assertEqual(resp.status_code, 201)
location_header = py3compat.str_to_unicode(resp.headers['Location'])
self.assertEqual(location_header, url_escape(url_path_join(u'/api/contents', path)))
self.assertEqual(location_header, url_path_join(self.url_prefix, u'api/contents', url_escape(path)))
rjson = resp.json()
self.assertEqual(rjson['name'], path.rsplit('/', 1)[-1])
self.assertEqual(rjson['path'], path)

View File

@ -43,8 +43,8 @@ class MainKernelHandler(APIHandler):
kernel_id = km.start_kernel(kernel_name=model['name'])
model = km.kernel_model(kernel_id)
location = url_path_join(self.base_url, 'api', 'kernels', kernel_id)
self.set_header('Location', url_escape(location))
location = url_path_join(self.base_url, 'api', 'kernels', url_escape(kernel_id))
self.set_header('Location', location)
self.set_status(201)
self.finish(json.dumps(model))

View File

@ -63,29 +63,33 @@ class KernelAPITest(NotebookTestBase):
# POST request
r = self.kern_api._req('POST', '')
kern1 = r.json()
self.assertEqual(r.headers['location'], '/api/kernels/' + kern1['id'])
self.assertEqual(r.headers['location'], url_path_join(self.url_prefix, 'api/kernels', kern1['id']))
self.assertEqual(r.status_code, 201)
self.assertIsInstance(kern1, dict)
self.assertEqual(r.headers['Content-Security-Policy'], (
"frame-ancestors 'self'; "
"report-uri /api/security/csp-report; "
"default-src 'none'"
))
report_uri = url_path_join(self.url_prefix, 'api/security/csp-report')
expected_csp = '; '.join([
"frame-ancestors 'self'",
'report-uri ' + report_uri,
"default-src 'none'"
])
self.assertEqual(r.headers['Content-Security-Policy'], expected_csp)
def test_main_kernel_handler(self):
# POST request
r = self.kern_api.start()
kern1 = r.json()
self.assertEqual(r.headers['location'], '/api/kernels/' + kern1['id'])
self.assertEqual(r.headers['location'], url_path_join(self.url_prefix, 'api/kernels', kern1['id']))
self.assertEqual(r.status_code, 201)
self.assertIsInstance(kern1, dict)
self.assertEqual(r.headers['Content-Security-Policy'], (
"frame-ancestors 'self'; "
"report-uri /api/security/csp-report; "
"default-src 'none'"
))
report_uri = url_path_join(self.url_prefix, 'api/security/csp-report')
expected_csp = '; '.join([
"frame-ancestors 'self'",
'report-uri ' + report_uri,
"default-src 'none'"
])
self.assertEqual(r.headers['Content-Security-Policy'], expected_csp)
# GET request
r = self.kern_api.list()
@ -110,7 +114,7 @@ class KernelAPITest(NotebookTestBase):
# Restart a kernel
r = self.kern_api.restart(kern2['id'])
self.assertEqual(r.headers['Location'], '/api/kernels/'+kern2['id'])
self.assertEqual(r.headers['Location'], url_path_join(self.url_prefix, 'api/kernels', kern2['id']))
rekern = r.json()
self.assertEqual(rekern['id'], kern2['id'])
self.assertEqual(rekern['name'], kern2['name'])

View File

@ -12,7 +12,7 @@ from tornado import web
from ...base.handlers import APIHandler, json_errors
from jupyter_client.jsonutil import date_default
from notebook.utils import url_path_join, url_escape
from notebook.utils import url_path_join
from jupyter_client.kernelspec import NoSuchKernel
@ -64,7 +64,7 @@ class SessionRootHandler(APIHandler):
return
location = url_path_join(self.base_url, 'api', 'sessions', model['id'])
self.set_header('Location', url_escape(location))
self.set_header('Location', location)
self.set_status(201)
self.finish(json.dumps(model, default=date_default))

View File

@ -92,7 +92,7 @@ class SessionAPITest(NotebookTestBase):
newsession = resp.json()
self.assertIn('id', newsession)
self.assertEqual(newsession['notebook']['path'], 'foo/nb1.ipynb')
self.assertEqual(resp.headers['Location'], '/api/sessions/{0}'.format(newsession['id']))
self.assertEqual(resp.headers['Location'], self.url_prefix + 'api/sessions/{0}'.format(newsession['id']))
sessions = self.sess_api.list().json()
self.assertEqual(sessions, [newsession])

View File

@ -12,13 +12,14 @@ class TreeHandler(IPythonHandler):
"""Render the tree view, listing notebooks, etc."""
def generate_breadcrumbs(self, path):
breadcrumbs = [(url_escape(url_path_join(self.base_url, 'tree')), '')]
comps = path.split('/')
ncomps = len(comps)
for i in range(ncomps):
if comps[i]:
link = url_escape(url_path_join(self.base_url, 'tree', *comps[0:i+1]))
breadcrumbs.append((link, comps[i]))
breadcrumbs = [(url_path_join(self.base_url, 'tree'), '')]
parts = path.split('/')
for i in range(len(parts)):
if parts[i]:
link = url_path_join(self.base_url, 'tree',
url_escape(url_path_join(*parts[:i+1])),
)
breadcrumbs.append((link, parts[i]))
return breadcrumbs
def generate_page_title(self, path):
@ -53,9 +54,9 @@ class TreeHandler(IPythonHandler):
model = cm.get(path, content=False)
# redirect to /api/notebooks if it's a notebook, otherwise /api/files
service = 'notebooks' if model['type'] == 'notebook' else 'files'
url = url_escape(url_path_join(
self.base_url, service, path,
))
url = url_path_join(
self.base_url, service, url_escape(path),
)
self.log.debug("Redirecting %s to %s", self.request.path, url)
self.redirect(url)
else: