Inject parity script to all dapps // Expand dapps to any ZIP file (#7260)
* Inject Parity script to all HTML dapps pages * Small glitch * Add injection test * Add Special GHH commit value for serving ZIP files as DAPPS * Refactor GithubDapp fetcher * PR Grumbles
This commit is contained in:
parent
f3297dd44a
commit
82d7fc54b3
@ -200,39 +200,57 @@ impl<R: URLHint + 'static, F: Fetch> Endpoint for ContentFetcher<F, R> {
|
||||
Some(URLHintResult::Dapp(_)) if self.only_content => {
|
||||
(None, Self::dapps_disabled(self.embeddable_on.clone()))
|
||||
},
|
||||
Some(URLHintResult::Dapp(dapp)) => {
|
||||
let handler = ContentFetcherHandler::new(
|
||||
req.method(),
|
||||
&dapp.url(),
|
||||
path,
|
||||
installers::Dapp::new(
|
||||
content_id.clone(),
|
||||
self.cache_path.clone(),
|
||||
Box::new(on_done),
|
||||
self.embeddable_on.clone(),
|
||||
self.pool.clone(),
|
||||
),
|
||||
self.embeddable_on.clone(),
|
||||
self.fetch.clone(),
|
||||
);
|
||||
|
||||
(Some(ContentStatus::Fetching(handler.fetch_control())), Box::new(handler) as endpoint::Response)
|
||||
},
|
||||
Some(URLHintResult::Content(content)) => {
|
||||
let handler = ContentFetcherHandler::new(
|
||||
req.method(),
|
||||
&content.url,
|
||||
path,
|
||||
installers::Content::new(
|
||||
content_id.clone(),
|
||||
content.mime,
|
||||
self.cache_path.clone(),
|
||||
Box::new(on_done),
|
||||
self.pool.clone(),
|
||||
),
|
||||
self.embeddable_on.clone(),
|
||||
self.fetch.clone(),
|
||||
);
|
||||
Some(content) => {
|
||||
let handler = match content {
|
||||
URLHintResult::Dapp(dapp) => {
|
||||
ContentFetcherHandler::new(
|
||||
req.method(),
|
||||
&dapp.url(),
|
||||
path,
|
||||
installers::Dapp::new(
|
||||
content_id.clone(),
|
||||
self.cache_path.clone(),
|
||||
Box::new(on_done),
|
||||
self.embeddable_on.clone(),
|
||||
self.pool.clone(),
|
||||
),
|
||||
self.embeddable_on.clone(),
|
||||
self.fetch.clone(),
|
||||
)
|
||||
},
|
||||
URLHintResult::GithubDapp(content) => {
|
||||
ContentFetcherHandler::new(
|
||||
req.method(),
|
||||
&content.url,
|
||||
path,
|
||||
installers::Dapp::new(
|
||||
content_id.clone(),
|
||||
self.cache_path.clone(),
|
||||
Box::new(on_done),
|
||||
self.embeddable_on.clone(),
|
||||
self.pool.clone(),
|
||||
),
|
||||
self.embeddable_on.clone(),
|
||||
self.fetch.clone(),
|
||||
)
|
||||
},
|
||||
URLHintResult::Content(content) => {
|
||||
ContentFetcherHandler::new(
|
||||
req.method(),
|
||||
&content.url,
|
||||
path,
|
||||
installers::Content::new(
|
||||
content_id.clone(),
|
||||
content.mime,
|
||||
self.cache_path.clone(),
|
||||
Box::new(on_done),
|
||||
self.pool.clone(),
|
||||
),
|
||||
self.embeddable_on.clone(),
|
||||
self.fetch.clone(),
|
||||
)
|
||||
},
|
||||
};
|
||||
|
||||
(Some(ContentStatus::Fetching(handler.fetch_control())), Box::new(handler) as endpoint::Response)
|
||||
},
|
||||
|
@ -17,8 +17,9 @@
|
||||
use std::io;
|
||||
use std::time::{Duration, SystemTime};
|
||||
use hyper::{self, header, StatusCode};
|
||||
use hyper::mime::Mime;
|
||||
use hyper::mime::{self, Mime};
|
||||
|
||||
use apps;
|
||||
use handlers::{Reader, ContentHandler, add_security_headers};
|
||||
use {Embeddable};
|
||||
|
||||
@ -95,7 +96,18 @@ impl<T: DappFile> PageHandler<T> {
|
||||
add_security_headers(&mut headers, self.safe_to_embed_on);
|
||||
}
|
||||
|
||||
let (reader, body) = Reader::pair(file.into_reader(), Vec::new());
|
||||
let initial_content = if file.content_type().to_owned() == mime::TEXT_HTML {
|
||||
let content = &format!(
|
||||
r#"<script src="/{}/inject.js"></script>"#,
|
||||
apps::UTILS_PATH,
|
||||
);
|
||||
|
||||
content.as_bytes().to_vec()
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
|
||||
let (reader, body) = Reader::pair(file.into_reader(), initial_content);
|
||||
res.set_body(body);
|
||||
(Some(reader), res)
|
||||
}
|
||||
|
@ -166,14 +166,15 @@ fn should_return_fetched_dapp_content() {
|
||||
|
||||
response1.assert_status("HTTP/1.1 200 OK");
|
||||
assert_security_headers_for_embed(&response1.headers);
|
||||
assert_eq!(
|
||||
response1.body,
|
||||
r#"18
|
||||
assert!(
|
||||
response1.body.contains(r#"18
|
||||
<h1>Hello Gavcoin!</h1>
|
||||
|
||||
0
|
||||
|
||||
"#
|
||||
"#),
|
||||
"Expected Gavcoin body: {}",
|
||||
response1.body
|
||||
);
|
||||
|
||||
response2.assert_status("HTTP/1.1 200 OK");
|
||||
|
@ -60,3 +60,32 @@ fn should_serve_home() {
|
||||
response.assert_header("Content-Type", "text/html");
|
||||
assert_security_headers(&response.headers);
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn should_inject_js() {
|
||||
// given
|
||||
let server = serve_ui();
|
||||
|
||||
// when
|
||||
let response = request(server,
|
||||
"\
|
||||
GET / HTTP/1.1\r\n\
|
||||
Host: 127.0.0.1:8080\r\n\
|
||||
Connection: close\r\n\
|
||||
\r\n\
|
||||
{}
|
||||
"
|
||||
);
|
||||
|
||||
// then
|
||||
response.assert_status("HTTP/1.1 200 OK");
|
||||
response.assert_header("Content-Type", "text/html");
|
||||
assert_eq!(
|
||||
response.body.contains(r#"/inject.js"></script>"#),
|
||||
true,
|
||||
"Expected inject script tag in: {}",
|
||||
response.body
|
||||
);
|
||||
assert_security_headers(&response.headers);
|
||||
}
|
||||
|
@ -150,6 +150,9 @@ impl<F: Fetch + 'static> HashFetch for Client<F> {
|
||||
URLHintResult::Dapp(dapp) => {
|
||||
dapp.url()
|
||||
},
|
||||
URLHintResult::GithubDapp(content) => {
|
||||
content.url
|
||||
},
|
||||
URLHintResult::Content(content) => {
|
||||
content.url
|
||||
},
|
||||
|
@ -32,6 +32,10 @@ use bytes::Bytes;
|
||||
pub type BoxFuture<A, B> = Box<Future<Item = A, Error = B> + Send>;
|
||||
|
||||
const COMMIT_LEN: usize = 20;
|
||||
/// GithubHint entries with commit set as `0x0..01` should be treated
|
||||
/// as Github Dapp, downloadable zip files, than can be extracted, containing
|
||||
/// the manifest.json file along with the dapp
|
||||
static GITHUB_DAPP_COMMIT: &[u8; COMMIT_LEN] = &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
|
||||
|
||||
/// RAW Contract interface.
|
||||
/// Should execute transaction using current blockchain state.
|
||||
@ -93,6 +97,8 @@ pub struct Content {
|
||||
pub enum URLHintResult {
|
||||
/// Dapp
|
||||
Dapp(GithubApp),
|
||||
/// GithubDapp
|
||||
GithubDapp(Content),
|
||||
/// Content
|
||||
Content(Content),
|
||||
}
|
||||
@ -122,6 +128,15 @@ impl URLHintContract {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_urlhint_content(account_slash_repo: String, owner: Address) -> Content {
|
||||
let mime = guess_mime_type(&account_slash_repo).unwrap_or(mime::APPLICATION_JSON);
|
||||
Content {
|
||||
url: account_slash_repo,
|
||||
mime,
|
||||
owner,
|
||||
}
|
||||
}
|
||||
|
||||
fn decode_urlhint_output(output: (String, ::bigint::hash::H160, Address)) -> Option<URLHintResult> {
|
||||
let (account_slash_repo, commit, owner) = output;
|
||||
|
||||
@ -130,13 +145,15 @@ fn decode_urlhint_output(output: (String, ::bigint::hash::H160, Address)) -> Opt
|
||||
}
|
||||
|
||||
let commit = GithubApp::commit(&commit);
|
||||
|
||||
if commit == Some(Default::default()) {
|
||||
let mime = guess_mime_type(&account_slash_repo).unwrap_or(mime::APPLICATION_JSON);
|
||||
return Some(URLHintResult::Content(Content {
|
||||
url: account_slash_repo,
|
||||
mime: mime,
|
||||
owner: owner,
|
||||
}));
|
||||
let content = get_urlhint_content(account_slash_repo, owner);
|
||||
return Some(URLHintResult::Content(content));
|
||||
}
|
||||
|
||||
if commit == Some(*GITHUB_DAPP_COMMIT) {
|
||||
let content = get_urlhint_content(account_slash_repo, owner);
|
||||
return Some(URLHintResult::GithubDapp(content));
|
||||
}
|
||||
|
||||
let (account, repo) = {
|
||||
|
Loading…
Reference in New Issue
Block a user