[web] make it possible to run static viewer in subdirectories

This commit is contained in:
Maximilian Hils 2017-08-21 23:35:04 +02:00
parent 194883fc6a
commit bf243244ce
16 changed files with 28 additions and 24 deletions

View File

@ -478,7 +478,7 @@ class Application(tornado.web.Application):
(r"/flows/(?P<flow_id>[0-9a-f\-]+)/duplicate", DuplicateFlow),
(r"/flows/(?P<flow_id>[0-9a-f\-]+)/replay", ReplayFlow),
(r"/flows/(?P<flow_id>[0-9a-f\-]+)/revert", RevertFlow),
(r"/flows/(?P<flow_id>[0-9a-f\-]+)/(?P<message>request|response)/_content", FlowContent),
(r"/flows/(?P<flow_id>[0-9a-f\-]+)/(?P<message>request|response)/content.data", FlowContent),
(
r"/flows/(?P<flow_id>[0-9a-f\-]+)/(?P<message>request|response)/content/(?P<content_view>[0-9a-zA-Z\-\_]+)(?:\.json)?",
FlowContentView),

View File

@ -48,7 +48,7 @@ def save_flows_content(path: pathlib.Path, flows: typing.Iterable[flow.Flow]) ->
message_path = path / "flows" / f.id / m
os.makedirs(str(message_path / "content"), exist_ok=True)
with open(str(message_path / '_content'), 'wb') as content_file:
with open(str(message_path / 'content.data'), 'wb') as content_file:
# don't use raw_content here as this is served with a default content type
if message:
content_file.write(message.content)

View File

@ -186,7 +186,7 @@ class TestApp(tornado.testing.AsyncHTTPTestCase):
f.response.headers["Content-Encoding"] = "ran\x00dom"
f.response.headers["Content-Disposition"] = 'inline; filename="filename.jpg"'
r = self.fetch("/flows/42/response/_content")
r = self.fetch("/flows/42/response/content.data")
assert r.body == b"message"
assert r.headers["Content-Encoding"] == "random"
assert r.headers["Content-Disposition"] == 'attachment; filename="filename.jpg"'
@ -194,17 +194,17 @@ class TestApp(tornado.testing.AsyncHTTPTestCase):
del f.response.headers["Content-Disposition"]
f.request.path = "/foo/bar.jpg"
assert self.fetch(
"/flows/42/response/_content"
"/flows/42/response/content.data"
).headers["Content-Disposition"] == 'attachment; filename=bar.jpg'
f.response.content = b""
assert self.fetch("/flows/42/response/_content").code == 400
assert self.fetch("/flows/42/response/content.data").code == 400
f.revert()
def test_update_flow_content(self):
assert self.fetch(
"/flows/42/request/_content",
"/flows/42/request/content.data",
method="POST",
body="new"
).code == 200
@ -222,7 +222,7 @@ class TestApp(tornado.testing.AsyncHTTPTestCase):
b'--somefancyboundary--\r\n'
)
assert self.fetch(
"/flows/42/request/_content",
"/flows/42/request/content.data",
method="POST",
headers={"Content-Type": 'multipart/form-data; boundary="somefancyboundary"'},
body=body

View File

@ -43,9 +43,9 @@ def test_save_flows_content(ctx, tmpdir):
for p in flows_path.listdir():
assert p.join('request').check(dir=1)
assert p.join('response').check(dir=1)
assert p.join('request/_content').check(file=1)
assert p.join('request/content.data').check(file=1)
assert p.join('request/content').check(dir=1)
assert p.join('response/_content').check(file=1)
assert p.join('response/content.data').check(file=1)
assert p.join('response/content').check(dir=1)
assert p.join('request/content/Auto.json').check(file=1)
assert p.join('response/content/Auto.json').check(file=1)

View File

@ -13,7 +13,7 @@ exports[`ContentViewOptions Component should render correctly 1`] = `
 
<a
className="btn btn-default btn-xs"
href="/flows/d91165be-ca1f-4612-88a9-c0f8696f3e29/response/_content"
href="./flows/d91165be-ca1f-4612-88a9-c0f8696f3e29/response/content.data"
title="Download the content of the flow."
>
<i

View File

@ -17,7 +17,7 @@ exports[`ViewImage Component should render correctly 1`] = `
<img
alt="preview"
className="img-thumbnail"
src="/flows/d91165be-ca1f-4612-88a9-c0f8696f3e29/response/_content"
src="./flows/d91165be-ca1f-4612-88a9-c0f8696f3e29/response/content.data"
/>
</div>
`;

View File

@ -3,7 +3,7 @@
exports[`DownloadContentButton Component should render correctly 1`] = `
<a
className="btn btn-default btn-xs"
href="/flows/d91165be-ca1f-4612-88a9-c0f8696f3e29/response/_content"
href="./flows/d91165be-ca1f-4612-88a9-c0f8696f3e29/response/content.data"
title="Download the content of the flow."
>
<i

View File

@ -54,7 +54,7 @@ exports[`ContentTooLarge Components should render correctly 1`] = `
 
<a
className="btn btn-default btn-xs"
href="/flows/d91165be-ca1f-4612-88a9-c0f8696f3e29/response/_content"
href="./flows/d91165be-ca1f-4612-88a9-c0f8696f3e29/response/content.data"
title="Download the content of the flow."
>
<i

View File

@ -265,7 +265,7 @@ exports[`Request Component should render correctly 1`] = `
 
<a
className="btn btn-default btn-xs"
href="/flows/d91165be-ca1f-4612-88a9-c0f8696f3e29/request/_content"
href="./flows/d91165be-ca1f-4612-88a9-c0f8696f3e29/request/content.data"
title="Download the content of the flow."
>
<i
@ -528,7 +528,7 @@ exports[`Response Component should render correctly 1`] = `
 
<a
className="btn btn-default btn-xs"
href="/flows/d91165be-ca1f-4612-88a9-c0f8696f3e29/response/_content"
href="./flows/d91165be-ca1f-4612-88a9-c0f8696f3e29/response/content.data"
title="Download the content of the flow."
>
<i

View File

@ -49,7 +49,7 @@ exports[`ContentView Component should render correctly with content too large 1`
 
<a
className="btn btn-default btn-xs"
href="/flows/d91165be-ca1f-4612-88a9-c0f8696f3e29/response/_content"
href="./flows/d91165be-ca1f-4612-88a9-c0f8696f3e29/response/content.data"
title="Download the content of the flow."
>
<i

View File

@ -25,15 +25,15 @@ describe('MessageUtils', () => {
let msg = "foo", view = "bar",
flow = { request: msg, id: 1}
expect(utils.MessageUtils.getContentURL(flow, msg, view)).toEqual(
"/flows/1/request/content/bar.json"
"./flows/1/request/content/bar.json"
)
expect(utils.MessageUtils.getContentURL(flow, msg, '')).toEqual(
"/flows/1/request/_content"
"./flows/1/request/content.data"
)
// response
flow = {response: msg, id: 2}
expect(utils.MessageUtils.getContentURL(flow, msg, view)).toEqual(
"/flows/2/response/content/bar.json"
"./flows/2/response/content/bar.json"
)
})
})

View File

@ -16,7 +16,7 @@ export default class StaticBackend {
}
fetchData(resource) {
fetchApi(`/${resource}`)
fetchApi(`./${resource}`)
.then(res => res.json())
.then(json => {
this.receive(resource, json)

View File

@ -34,7 +34,7 @@ export default class WebsocketBackend {
fetchData(resource) {
let queue = []
this.activeFetches[resource] = queue
fetchApi(`/${resource}`)
fetchApi(`./${resource}`)
.then(res => res.json())
.then(json => {
// Make sure that we are not superseded yet by the server sending a RESET.

View File

@ -5,7 +5,7 @@ import * as modalActions from "./modal"
export function onKeyDown(e) {
console.debug("onKeyDown", e)
//console.debug("onKeyDown", e)
if (e.ctrlKey) {
return () => {
}

View File

@ -49,7 +49,7 @@ export var MessageUtils = {
} else if (message === flow.response) {
message = "response";
}
return `/flows/${flow.id}/${message}/` + (view ? `content/${view}.json` : '_content');
return `./flows/${flow.id}/${message}/` + (view ? `content/${view}.json` : 'content.data');
}
};

View File

@ -72,8 +72,12 @@ export function updateUrlFromStore(store) {
if (queryStr) {
url += "?" + queryStr
}
let pathname = window.location.pathname
if(pathname === "blank") {
pathname = "/" // this happens in tests...
}
if (window.location.hash.substr(1) !== url) {
history.replaceState(undefined, "", `/#${url}`)
history.replaceState(undefined, "", `${pathname}#${url}`)
}
}