Merge pull request #5399 from paritytech/dapps-content-bug
Fixing disappearing content.
This commit is contained in:
commit
d0e057cabd
@ -14,6 +14,8 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use unicase::UniCase;
|
use unicase::UniCase;
|
||||||
use hyper::{server, net, Decoder, Encoder, Next, Control};
|
use hyper::{server, net, Decoder, Encoder, Next, Control};
|
||||||
use hyper::header;
|
use hyper::header;
|
||||||
@ -28,16 +30,16 @@ use endpoint::{Endpoint, Endpoints, Handler, EndpointPath};
|
|||||||
use jsonrpc_http_server::{self, AccessControlAllowOrigin};
|
use jsonrpc_http_server::{self, AccessControlAllowOrigin};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct RestApi<F> {
|
pub struct RestApi {
|
||||||
// TODO [ToDr] cors_domains should be handled by the server to avoid duplicated logic.
|
// TODO [ToDr] cors_domains should be handled by the server to avoid duplicated logic.
|
||||||
// RequestMiddleware should be able to tell that cors headers should be included.
|
// RequestMiddleware should be able to tell that cors headers should be included.
|
||||||
cors_domains: Option<Vec<AccessControlAllowOrigin>>,
|
cors_domains: Option<Vec<AccessControlAllowOrigin>>,
|
||||||
apps: Vec<App>,
|
apps: Vec<App>,
|
||||||
fetcher: F,
|
fetcher: Arc<Fetcher>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Fetcher + Clone> RestApi<F> {
|
impl RestApi {
|
||||||
pub fn new(cors_domains: Vec<AccessControlAllowOrigin>, endpoints: &Endpoints, fetcher: F) -> Box<Endpoint> {
|
pub fn new(cors_domains: Vec<AccessControlAllowOrigin>, endpoints: &Endpoints, fetcher: Arc<Fetcher>) -> Box<Endpoint> {
|
||||||
Box::new(RestApi {
|
Box::new(RestApi {
|
||||||
cors_domains: Some(cors_domains),
|
cors_domains: Some(cors_domains),
|
||||||
apps: Self::list_apps(endpoints),
|
apps: Self::list_apps(endpoints),
|
||||||
@ -52,22 +54,22 @@ impl<F: Fetcher + Clone> RestApi<F> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Fetcher + Clone> Endpoint for RestApi<F> {
|
impl Endpoint for RestApi {
|
||||||
fn to_async_handler(&self, path: EndpointPath, control: Control) -> Box<Handler> {
|
fn to_async_handler(&self, path: EndpointPath, control: Control) -> Box<Handler> {
|
||||||
Box::new(RestApiRouter::new((*self).clone(), path, control))
|
Box::new(RestApiRouter::new((*self).clone(), path, control))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RestApiRouter<F> {
|
struct RestApiRouter {
|
||||||
api: RestApi<F>,
|
api: RestApi,
|
||||||
cors_header: Option<header::AccessControlAllowOrigin>,
|
cors_header: Option<header::AccessControlAllowOrigin>,
|
||||||
path: Option<EndpointPath>,
|
path: Option<EndpointPath>,
|
||||||
control: Option<Control>,
|
control: Option<Control>,
|
||||||
handler: Box<Handler>,
|
handler: Box<Handler>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Fetcher> RestApiRouter<F> {
|
impl RestApiRouter {
|
||||||
fn new(api: RestApi<F>, path: EndpointPath, control: Control) -> Self {
|
fn new(api: RestApi, path: EndpointPath, control: Control) -> Self {
|
||||||
RestApiRouter {
|
RestApiRouter {
|
||||||
path: Some(path),
|
path: Some(path),
|
||||||
cors_header: None,
|
cors_header: None,
|
||||||
@ -82,6 +84,7 @@ impl<F: Fetcher> RestApiRouter<F> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_content(&self, hash: Option<&str>, path: EndpointPath, control: Control) -> Option<Box<Handler>> {
|
fn resolve_content(&self, hash: Option<&str>, path: EndpointPath, control: Control) -> Option<Box<Handler>> {
|
||||||
|
trace!(target: "dapps", "Resolving content: {:?} from path: {:?}", hash, path);
|
||||||
match hash {
|
match hash {
|
||||||
Some(hash) if self.api.fetcher.contains(hash) => {
|
Some(hash) if self.api.fetcher.contains(hash) => {
|
||||||
Some(self.api.fetcher.to_async_handler(path, control))
|
Some(self.api.fetcher.to_async_handler(path, control))
|
||||||
@ -114,8 +117,7 @@ impl<F: Fetcher> RestApiRouter<F> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Fetcher> server::Handler<net::HttpStream> for RestApiRouter<F> {
|
impl server::Handler<net::HttpStream> for RestApiRouter {
|
||||||
|
|
||||||
fn on_request(&mut self, request: server::Request<net::HttpStream>) -> Next {
|
fn on_request(&mut self, request: server::Request<net::HttpStream>) -> Next {
|
||||||
self.cors_header = jsonrpc_http_server::cors_header(&request, &self.api.cors_domains).into();
|
self.cors_header = jsonrpc_http_server::cors_header(&request, &self.api.cors_domains).into();
|
||||||
|
|
||||||
@ -168,5 +170,4 @@ impl<F: Fetcher> server::Handler<net::HttpStream> for RestApiRouter<F> {
|
|||||||
fn on_response_writable(&mut self, encoder: &mut Encoder<net::HttpStream>) -> Next {
|
fn on_response_writable(&mut self, encoder: &mut Encoder<net::HttpStream>) -> Next {
|
||||||
self.handler.on_response_writable(encoder)
|
self.handler.on_response_writable(encoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -47,8 +47,7 @@ pub trait Fetcher: Send + Sync + 'static {
|
|||||||
fn to_async_handler(&self, path: EndpointPath, control: hyper::Control) -> Box<Handler>;
|
fn to_async_handler(&self, path: EndpointPath, control: hyper::Control) -> Box<Handler>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
pub struct ContentFetcher<F: Fetch = FetchClient, R: URLHint + 'static = URLHintContract> {
|
||||||
pub struct ContentFetcher<F: Fetch + Clone = FetchClient, R: URLHint + Clone + 'static = URLHintContract> {
|
|
||||||
dapps_path: PathBuf,
|
dapps_path: PathBuf,
|
||||||
resolver: R,
|
resolver: R,
|
||||||
cache: Arc<Mutex<ContentCache>>,
|
cache: Arc<Mutex<ContentCache>>,
|
||||||
@ -58,14 +57,14 @@ pub struct ContentFetcher<F: Fetch + Clone = FetchClient, R: URLHint + Clone + '
|
|||||||
fetch: F,
|
fetch: F,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: URLHint + Clone + 'static, F: Fetch + Clone> Drop for ContentFetcher<F, R> {
|
impl<R: URLHint + 'static, F: Fetch> Drop for ContentFetcher<F, R> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
// Clear cache path
|
// Clear cache path
|
||||||
let _ = fs::remove_dir_all(&self.dapps_path);
|
let _ = fs::remove_dir_all(&self.dapps_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: URLHint + Clone + 'static, F: Fetch + Clone> ContentFetcher<F, R> {
|
impl<R: URLHint + 'static, F: Fetch> ContentFetcher<F, R> {
|
||||||
|
|
||||||
pub fn new(resolver: R, sync_status: Arc<SyncStatus>, embeddable_on: Option<(String, u16)>, remote: Remote, fetch: F) -> Self {
|
pub fn new(resolver: R, sync_status: Arc<SyncStatus>, embeddable_on: Option<(String, u16)>, remote: Remote, fetch: F) -> Self {
|
||||||
let mut dapps_path = env::temp_dir();
|
let mut dapps_path = env::temp_dir();
|
||||||
@ -98,7 +97,7 @@ impl<R: URLHint + Clone + 'static, F: Fetch + Clone> ContentFetcher<F, R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: URLHint + Clone + 'static, F: Fetch + Clone> Fetcher for ContentFetcher<F, R> {
|
impl<R: URLHint + 'static, F: Fetch> Fetcher for ContentFetcher<F, R> {
|
||||||
fn contains(&self, content_id: &str) -> bool {
|
fn contains(&self, content_id: &str) -> bool {
|
||||||
{
|
{
|
||||||
let mut cache = self.cache.lock();
|
let mut cache = self.cache.lock();
|
||||||
|
@ -98,13 +98,13 @@ impl<F> WebProxyTokens for F where F: Fn(String) -> bool + Send + Sync {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Dapps server as `jsonrpc-http-server` request middleware.
|
/// Dapps server as `jsonrpc-http-server` request middleware.
|
||||||
pub struct Middleware<F: Fetch + Clone> {
|
pub struct Middleware {
|
||||||
router: router::Router<apps::fetcher::ContentFetcher<F>>,
|
router: router::Router,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Fetch + Clone> Middleware<F> {
|
impl Middleware {
|
||||||
/// Creates new Dapps server middleware.
|
/// Creates new Dapps server middleware.
|
||||||
pub fn new(
|
pub fn new<F: Fetch + Clone>(
|
||||||
remote: Remote,
|
remote: Remote,
|
||||||
signer_address: Option<(String, u16)>,
|
signer_address: Option<(String, u16)>,
|
||||||
dapps_path: PathBuf,
|
dapps_path: PathBuf,
|
||||||
@ -114,13 +114,13 @@ impl<F: Fetch + Clone> Middleware<F> {
|
|||||||
web_proxy_tokens: Arc<WebProxyTokens>,
|
web_proxy_tokens: Arc<WebProxyTokens>,
|
||||||
fetch: F,
|
fetch: F,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let content_fetcher = apps::fetcher::ContentFetcher::new(
|
let content_fetcher = Arc::new(apps::fetcher::ContentFetcher::new(
|
||||||
hash_fetch::urlhint::URLHintContract::new(registrar),
|
hash_fetch::urlhint::URLHintContract::new(registrar),
|
||||||
sync_status,
|
sync_status,
|
||||||
signer_address.clone(),
|
signer_address.clone(),
|
||||||
remote.clone(),
|
remote.clone(),
|
||||||
fetch.clone(),
|
fetch.clone(),
|
||||||
);
|
));
|
||||||
let endpoints = apps::all_endpoints(
|
let endpoints = apps::all_endpoints(
|
||||||
dapps_path,
|
dapps_path,
|
||||||
extra_dapps,
|
extra_dapps,
|
||||||
@ -138,7 +138,11 @@ impl<F: Fetch + Clone> Middleware<F> {
|
|||||||
special.insert(router::SpecialEndpoint::Utils, Some(apps::utils()));
|
special.insert(router::SpecialEndpoint::Utils, Some(apps::utils()));
|
||||||
special.insert(
|
special.insert(
|
||||||
router::SpecialEndpoint::Api,
|
router::SpecialEndpoint::Api,
|
||||||
Some(api::RestApi::new(cors_domains.clone(), &endpoints, content_fetcher.clone())),
|
Some(api::RestApi::new(
|
||||||
|
cors_domains.clone(),
|
||||||
|
&endpoints,
|
||||||
|
content_fetcher.clone()
|
||||||
|
)),
|
||||||
);
|
);
|
||||||
special
|
special
|
||||||
};
|
};
|
||||||
@ -156,7 +160,7 @@ impl<F: Fetch + Clone> Middleware<F> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Fetch + Clone> http::RequestMiddleware for Middleware<F> {
|
impl http::RequestMiddleware for Middleware {
|
||||||
fn on_request(&self, req: &hyper::server::Request<hyper::net::HttpStream>, control: &hyper::Control) -> http::RequestMiddlewareAction {
|
fn on_request(&self, req: &hyper::server::Request<hyper::net::HttpStream>, control: &hyper::Control) -> http::RequestMiddlewareAction {
|
||||||
self.router.on_request(req, control)
|
self.router.on_request(req, control)
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
use address;
|
use address;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
|
use std::sync::Arc;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use url::{Url, Host};
|
use url::{Url, Host};
|
||||||
@ -40,14 +41,14 @@ pub enum SpecialEndpoint {
|
|||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Router<F> {
|
pub struct Router {
|
||||||
signer_address: Option<(String, u16)>,
|
signer_address: Option<(String, u16)>,
|
||||||
endpoints: Endpoints,
|
endpoints: Endpoints,
|
||||||
fetch: F,
|
fetch: Arc<Fetcher>,
|
||||||
special: HashMap<SpecialEndpoint, Option<Box<Endpoint>>>,
|
special: HashMap<SpecialEndpoint, Option<Box<Endpoint>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Fetcher + 'static> http::RequestMiddleware for Router<F> {
|
impl http::RequestMiddleware for Router {
|
||||||
fn on_request(&self, req: &server::Request<HttpStream>, control: &Control) -> http::RequestMiddlewareAction {
|
fn on_request(&self, req: &server::Request<HttpStream>, control: &Control) -> http::RequestMiddlewareAction {
|
||||||
// Choose proper handler depending on path / domain
|
// Choose proper handler depending on path / domain
|
||||||
let url = handlers::extract_url(req);
|
let url = handlers::extract_url(req);
|
||||||
@ -146,10 +147,10 @@ impl<F: Fetcher + 'static> http::RequestMiddleware for Router<F> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F> Router<F> {
|
impl Router {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
signer_address: Option<(String, u16)>,
|
signer_address: Option<(String, u16)>,
|
||||||
content_fetcher: F,
|
content_fetcher: Arc<Fetcher>,
|
||||||
endpoints: Endpoints,
|
endpoints: Endpoints,
|
||||||
special: HashMap<SpecialEndpoint, Option<Box<Endpoint>>>,
|
special: HashMap<SpecialEndpoint, Option<Box<Endpoint>>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -137,11 +137,10 @@ mod server {
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use hash_fetch::fetch::Client as FetchClient;
|
|
||||||
use parity_dapps;
|
use parity_dapps;
|
||||||
use parity_reactor;
|
use parity_reactor;
|
||||||
|
|
||||||
pub type Middleware = parity_dapps::Middleware<FetchClient>;
|
pub use parity_dapps::Middleware;
|
||||||
pub use parity_dapps::SyncStatus;
|
pub use parity_dapps::SyncStatus;
|
||||||
|
|
||||||
pub fn dapps_middleware(
|
pub fn dapps_middleware(
|
||||||
|
Loading…
Reference in New Issue
Block a user