mirror of
https://github.com/jupyter/notebook.git
synced 2024-12-21 04:10:17 +08:00
server-side fixes for double-escaped base_url
This commit is contained in:
parent
164c3b6c1a
commit
8de725a8de
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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))
|
||||
|
||||
|
@ -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'])
|
||||
|
@ -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))
|
||||
|
||||
|
@ -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])
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user