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,8 +200,10 @@ impl<R: URLHint + 'static, F: Fetch> Endpoint for ContentFetcher<F, R> {
|
|||||||
Some(URLHintResult::Dapp(_)) if self.only_content => {
|
Some(URLHintResult::Dapp(_)) if self.only_content => {
|
||||||
(None, Self::dapps_disabled(self.embeddable_on.clone()))
|
(None, Self::dapps_disabled(self.embeddable_on.clone()))
|
||||||
},
|
},
|
||||||
Some(URLHintResult::Dapp(dapp)) => {
|
Some(content) => {
|
||||||
let handler = ContentFetcherHandler::new(
|
let handler = match content {
|
||||||
|
URLHintResult::Dapp(dapp) => {
|
||||||
|
ContentFetcherHandler::new(
|
||||||
req.method(),
|
req.method(),
|
||||||
&dapp.url(),
|
&dapp.url(),
|
||||||
path,
|
path,
|
||||||
@ -214,12 +216,26 @@ impl<R: URLHint + 'static, F: Fetch> Endpoint for ContentFetcher<F, R> {
|
|||||||
),
|
),
|
||||||
self.embeddable_on.clone(),
|
self.embeddable_on.clone(),
|
||||||
self.fetch.clone(),
|
self.fetch.clone(),
|
||||||
);
|
)
|
||||||
|
|
||||||
(Some(ContentStatus::Fetching(handler.fetch_control())), Box::new(handler) as endpoint::Response)
|
|
||||||
},
|
},
|
||||||
Some(URLHintResult::Content(content)) => {
|
URLHintResult::GithubDapp(content) => {
|
||||||
let handler = ContentFetcherHandler::new(
|
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(),
|
req.method(),
|
||||||
&content.url,
|
&content.url,
|
||||||
path,
|
path,
|
||||||
@ -232,7 +248,9 @@ impl<R: URLHint + 'static, F: Fetch> Endpoint for ContentFetcher<F, R> {
|
|||||||
),
|
),
|
||||||
self.embeddable_on.clone(),
|
self.embeddable_on.clone(),
|
||||||
self.fetch.clone(),
|
self.fetch.clone(),
|
||||||
);
|
)
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
(Some(ContentStatus::Fetching(handler.fetch_control())), Box::new(handler) as endpoint::Response)
|
(Some(ContentStatus::Fetching(handler.fetch_control())), Box::new(handler) as endpoint::Response)
|
||||||
},
|
},
|
||||||
|
@ -17,8 +17,9 @@
|
|||||||
use std::io;
|
use std::io;
|
||||||
use std::time::{Duration, SystemTime};
|
use std::time::{Duration, SystemTime};
|
||||||
use hyper::{self, header, StatusCode};
|
use hyper::{self, header, StatusCode};
|
||||||
use hyper::mime::Mime;
|
use hyper::mime::{self, Mime};
|
||||||
|
|
||||||
|
use apps;
|
||||||
use handlers::{Reader, ContentHandler, add_security_headers};
|
use handlers::{Reader, ContentHandler, add_security_headers};
|
||||||
use {Embeddable};
|
use {Embeddable};
|
||||||
|
|
||||||
@ -95,7 +96,18 @@ impl<T: DappFile> PageHandler<T> {
|
|||||||
add_security_headers(&mut headers, self.safe_to_embed_on);
|
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);
|
res.set_body(body);
|
||||||
(Some(reader), res)
|
(Some(reader), res)
|
||||||
}
|
}
|
||||||
|
@ -166,14 +166,15 @@ fn should_return_fetched_dapp_content() {
|
|||||||
|
|
||||||
response1.assert_status("HTTP/1.1 200 OK");
|
response1.assert_status("HTTP/1.1 200 OK");
|
||||||
assert_security_headers_for_embed(&response1.headers);
|
assert_security_headers_for_embed(&response1.headers);
|
||||||
assert_eq!(
|
assert!(
|
||||||
response1.body,
|
response1.body.contains(r#"18
|
||||||
r#"18
|
|
||||||
<h1>Hello Gavcoin!</h1>
|
<h1>Hello Gavcoin!</h1>
|
||||||
|
|
||||||
0
|
0
|
||||||
|
|
||||||
"#
|
"#),
|
||||||
|
"Expected Gavcoin body: {}",
|
||||||
|
response1.body
|
||||||
);
|
);
|
||||||
|
|
||||||
response2.assert_status("HTTP/1.1 200 OK");
|
response2.assert_status("HTTP/1.1 200 OK");
|
||||||
|
@ -60,3 +60,32 @@ fn should_serve_home() {
|
|||||||
response.assert_header("Content-Type", "text/html");
|
response.assert_header("Content-Type", "text/html");
|
||||||
assert_security_headers(&response.headers);
|
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) => {
|
URLHintResult::Dapp(dapp) => {
|
||||||
dapp.url()
|
dapp.url()
|
||||||
},
|
},
|
||||||
|
URLHintResult::GithubDapp(content) => {
|
||||||
|
content.url
|
||||||
|
},
|
||||||
URLHintResult::Content(content) => {
|
URLHintResult::Content(content) => {
|
||||||
content.url
|
content.url
|
||||||
},
|
},
|
||||||
|
@ -32,6 +32,10 @@ use bytes::Bytes;
|
|||||||
pub type BoxFuture<A, B> = Box<Future<Item = A, Error = B> + Send>;
|
pub type BoxFuture<A, B> = Box<Future<Item = A, Error = B> + Send>;
|
||||||
|
|
||||||
const COMMIT_LEN: usize = 20;
|
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.
|
/// RAW Contract interface.
|
||||||
/// Should execute transaction using current blockchain state.
|
/// Should execute transaction using current blockchain state.
|
||||||
@ -93,6 +97,8 @@ pub struct Content {
|
|||||||
pub enum URLHintResult {
|
pub enum URLHintResult {
|
||||||
/// Dapp
|
/// Dapp
|
||||||
Dapp(GithubApp),
|
Dapp(GithubApp),
|
||||||
|
/// GithubDapp
|
||||||
|
GithubDapp(Content),
|
||||||
/// Content
|
/// Content
|
||||||
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> {
|
fn decode_urlhint_output(output: (String, ::bigint::hash::H160, Address)) -> Option<URLHintResult> {
|
||||||
let (account_slash_repo, commit, owner) = output;
|
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);
|
let commit = GithubApp::commit(&commit);
|
||||||
|
|
||||||
if commit == Some(Default::default()) {
|
if commit == Some(Default::default()) {
|
||||||
let mime = guess_mime_type(&account_slash_repo).unwrap_or(mime::APPLICATION_JSON);
|
let content = get_urlhint_content(account_slash_repo, owner);
|
||||||
return Some(URLHintResult::Content(Content {
|
return Some(URLHintResult::Content(content));
|
||||||
url: account_slash_repo,
|
}
|
||||||
mime: mime,
|
|
||||||
owner: owner,
|
if commit == Some(*GITHUB_DAPP_COMMIT) {
|
||||||
}));
|
let content = get_urlhint_content(account_slash_repo, owner);
|
||||||
|
return Some(URLHintResult::GithubDapp(content));
|
||||||
}
|
}
|
||||||
|
|
||||||
let (account, repo) = {
|
let (account, repo) = {
|
||||||
|
Loading…
Reference in New Issue
Block a user