core: Introduce `Request`
Which holds both a URL and what was `RequestOptions` formerly.
This commit is contained in:
parent
115f15806e
commit
f643048c1c
|
@ -7,7 +7,7 @@ use crate::avm1::scope::Scope;
|
|||
use crate::avm1::{
|
||||
fscommand, globals, scope, skip_actions, start_drag, ArrayObject, ScriptObject, Value,
|
||||
};
|
||||
use crate::backend::navigator::{NavigationMethod, RequestOptions};
|
||||
use crate::backend::navigator::{NavigationMethod, Request};
|
||||
use crate::context::UpdateContext;
|
||||
use crate::display_object::{DisplayObject, MovieClip, TDisplayObject, TDisplayObjectContainer};
|
||||
use crate::ecma_conversions::f64_to_wrapping_u32;
|
||||
|
@ -1154,8 +1154,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
|||
let future = self.context.load_manager.load_movie_into_clip(
|
||||
self.context.player.clone(),
|
||||
level,
|
||||
&url,
|
||||
RequestOptions::get(),
|
||||
Request::get(url),
|
||||
None,
|
||||
None,
|
||||
);
|
||||
|
@ -1246,15 +1245,14 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
|||
.unwrap()
|
||||
.object()
|
||||
.coerce_to_object(self);
|
||||
let (url, opts) = self.locals_into_request_options(
|
||||
&url,
|
||||
let request = self.locals_into_request(
|
||||
url,
|
||||
NavigationMethod::from_send_vars_method(action.send_vars_method()),
|
||||
);
|
||||
let future = self.context.load_manager.load_form_into_object(
|
||||
self.context.player.clone(),
|
||||
target_obj,
|
||||
&url,
|
||||
opts,
|
||||
request,
|
||||
);
|
||||
self.context.navigator.spawn_future(future);
|
||||
}
|
||||
|
@ -1263,22 +1261,20 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
|||
} else if action.is_target_sprite() {
|
||||
// `loadMovie`, `unloadMovie` or `unloadMovieNum` call.
|
||||
if let Some(clip_target) = clip_target {
|
||||
let (url, opts) = self.locals_into_request_options(
|
||||
&url,
|
||||
NavigationMethod::from_send_vars_method(action.send_vars_method()),
|
||||
);
|
||||
|
||||
if url.is_empty() {
|
||||
// Blank URL on movie loads = unload!
|
||||
if let Some(mut mc) = clip_target.as_movie_clip() {
|
||||
mc.replace_with_movie(self.context.gc_context, None)
|
||||
}
|
||||
} else {
|
||||
let request = self.locals_into_request(
|
||||
url,
|
||||
NavigationMethod::from_send_vars_method(action.send_vars_method()),
|
||||
);
|
||||
let future = self.context.load_manager.load_movie_into_clip(
|
||||
self.context.player.clone(),
|
||||
clip_target,
|
||||
&url,
|
||||
opts,
|
||||
request,
|
||||
None,
|
||||
None,
|
||||
);
|
||||
|
@ -1292,8 +1288,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
|||
let future = self.context.load_manager.load_movie_into_clip(
|
||||
self.context.player.clone(),
|
||||
clip_target,
|
||||
&url.to_utf8_lossy(),
|
||||
RequestOptions::get(),
|
||||
Request::get(url.to_utf8_lossy().into_owned()),
|
||||
None,
|
||||
None,
|
||||
);
|
||||
|
@ -2295,14 +2290,14 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
|||
form_values
|
||||
}
|
||||
|
||||
/// Construct request options for a fetch operation that may sends object properties as
|
||||
/// form data in the request body or URL.
|
||||
pub fn object_into_request_options<'c>(
|
||||
/// Construct a request for a fetch operation that may send object properties as form data in
|
||||
/// the request body or URL.
|
||||
pub fn object_into_request(
|
||||
&mut self,
|
||||
object: Object<'gc>,
|
||||
url: &'c WStr,
|
||||
url: AvmString<'gc>,
|
||||
method: Option<NavigationMethod>,
|
||||
) -> (Cow<'c, str>, RequestOptions) {
|
||||
) -> Request {
|
||||
match method {
|
||||
Some(method) => {
|
||||
let vars = self.object_into_form_values(object);
|
||||
|
@ -2311,24 +2306,20 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
|||
.finish();
|
||||
|
||||
match method {
|
||||
NavigationMethod::Get if url.find(b'?').is_none() => (
|
||||
Cow::Owned(format!("{}?{}", url, qstring)),
|
||||
RequestOptions::get(),
|
||||
),
|
||||
NavigationMethod::Get => (
|
||||
Cow::Owned(format!("{}&{}", url, qstring)),
|
||||
RequestOptions::get(),
|
||||
),
|
||||
NavigationMethod::Post => (
|
||||
url.to_utf8_lossy(),
|
||||
RequestOptions::post(Some((
|
||||
NavigationMethod::Get if !url.contains(b'?') => {
|
||||
Request::get(format!("{}?{}", url, qstring))
|
||||
}
|
||||
NavigationMethod::Get => Request::get(format!("{}&{}", url, qstring)),
|
||||
NavigationMethod::Post => Request::post(
|
||||
url.to_utf8_lossy().into_owned(),
|
||||
Some((
|
||||
qstring.as_bytes().to_owned(),
|
||||
"application/x-www-form-urlencoded".to_string(),
|
||||
))),
|
||||
)),
|
||||
),
|
||||
}
|
||||
}
|
||||
None => (url.to_utf8_lossy(), RequestOptions::get()),
|
||||
None => Request::get(url.to_utf8_lossy().into_owned()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2344,16 +2335,16 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
|||
self.object_into_form_values(locals)
|
||||
}
|
||||
|
||||
/// Construct request options for a fetch operation that may send locals as
|
||||
/// form data in the request body or URL.
|
||||
pub fn locals_into_request_options<'c>(
|
||||
/// Construct a request for a fetch operation that may send locals as form data in the request
|
||||
/// body or URL.
|
||||
pub fn locals_into_request(
|
||||
&mut self,
|
||||
url: &'c WStr,
|
||||
url: AvmString<'gc>,
|
||||
method: Option<NavigationMethod>,
|
||||
) -> (Cow<'c, str>, RequestOptions) {
|
||||
) -> Request {
|
||||
let scope = self.scope_cell();
|
||||
let locals = scope.read().locals_cell();
|
||||
self.object_into_request_options(locals, url, method)
|
||||
self.object_into_request(locals, url, method)
|
||||
}
|
||||
|
||||
/// Resolves a target value to a display object, relative to a starting display object.
|
||||
|
|
|
@ -8,7 +8,7 @@ use crate::avm1::property::Attribute;
|
|||
use crate::avm1::property_decl::{define_properties_on, Declaration};
|
||||
use crate::avm1::{Object, ScriptObject, TObject, Value};
|
||||
use crate::avm_warn;
|
||||
use crate::backend::navigator::{NavigationMethod, RequestOptions};
|
||||
use crate::backend::navigator::{NavigationMethod, Request};
|
||||
use crate::string::AvmString;
|
||||
use gc_arena::MutationContext;
|
||||
|
||||
|
@ -102,7 +102,7 @@ fn load<'gc>(
|
|||
None => return Ok(false.into()),
|
||||
};
|
||||
|
||||
spawn_load_var_fetch(activation, this, &url, None)?;
|
||||
spawn_load_var_fetch(activation, this, url, None)?;
|
||||
|
||||
Ok(true.into())
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ fn send_and_load<'gc>(
|
|||
.coerce_to_string(activation)?;
|
||||
let method = NavigationMethod::from_method_str(&method_name).unwrap_or(NavigationMethod::Post);
|
||||
|
||||
spawn_load_var_fetch(activation, target, &url, Some((this, method)))?;
|
||||
spawn_load_var_fetch(activation, target, url, Some((this, method)))?;
|
||||
|
||||
Ok(true.into())
|
||||
}
|
||||
|
@ -254,22 +254,21 @@ fn to_string<'gc>(
|
|||
fn spawn_load_var_fetch<'gc>(
|
||||
activation: &mut Activation<'_, 'gc, '_>,
|
||||
loader_object: Object<'gc>,
|
||||
url: &AvmString,
|
||||
url: AvmString<'gc>,
|
||||
send_object: Option<(Object<'gc>, NavigationMethod)>,
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
let (url, request_options) = if let Some((send_object, method)) = send_object {
|
||||
let request = if let Some((send_object, method)) = send_object {
|
||||
// Send properties from `send_object`.
|
||||
activation.object_into_request_options(send_object, url, Some(method))
|
||||
activation.object_into_request(send_object, url, Some(method))
|
||||
} else {
|
||||
// Not sending any parameters.
|
||||
(url.to_utf8_lossy(), RequestOptions::get())
|
||||
Request::get(url.to_utf8_lossy().into_owned())
|
||||
};
|
||||
|
||||
let future = activation.context.load_manager.load_form_into_load_vars(
|
||||
activation.context.player.clone(),
|
||||
loader_object,
|
||||
&url,
|
||||
request_options,
|
||||
request,
|
||||
);
|
||||
activation.context.navigator.spawn_future(future);
|
||||
|
||||
|
|
|
@ -1320,12 +1320,11 @@ fn load_movie<'gc>(
|
|||
let url = url_val.coerce_to_string(activation)?;
|
||||
let method = args.get(1).cloned().unwrap_or(Value::Undefined);
|
||||
let method = NavigationMethod::from_method_str(&method.coerce_to_string(activation)?);
|
||||
let (url, opts) = activation.locals_into_request_options(&url, method);
|
||||
let request = activation.locals_into_request(url, method);
|
||||
let future = activation.context.load_manager.load_movie_into_clip(
|
||||
activation.context.player.clone(),
|
||||
DisplayObject::MovieClip(target),
|
||||
&url,
|
||||
opts,
|
||||
request,
|
||||
None,
|
||||
None,
|
||||
);
|
||||
|
@ -1343,13 +1342,12 @@ fn load_variables<'gc>(
|
|||
let url = url_val.coerce_to_string(activation)?;
|
||||
let method = args.get(1).cloned().unwrap_or(Value::Undefined);
|
||||
let method = NavigationMethod::from_method_str(&method.coerce_to_string(activation)?);
|
||||
let (url, opts) = activation.locals_into_request_options(&url, method);
|
||||
let request = activation.locals_into_request(url, method);
|
||||
let target = target.object().coerce_to_object(activation);
|
||||
let future = activation.context.load_manager.load_form_into_object(
|
||||
activation.context.player.clone(),
|
||||
target,
|
||||
&url,
|
||||
opts,
|
||||
request,
|
||||
);
|
||||
activation.context.navigator.spawn_future(future);
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ use crate::avm1::object::TObject;
|
|||
use crate::avm1::property::Attribute;
|
||||
use crate::avm1::property_decl::{define_properties_on, Declaration};
|
||||
use crate::avm1::{ArrayObject, Object, Value};
|
||||
use crate::backend::navigator::RequestOptions;
|
||||
use crate::backend::navigator::Request;
|
||||
use crate::display_object::{TDisplayObject, TDisplayObjectContainer};
|
||||
use gc_arena::MutationContext;
|
||||
|
||||
|
@ -61,8 +61,7 @@ fn load_clip<'gc>(
|
|||
let future = activation.context.load_manager.load_movie_into_clip(
|
||||
activation.context.player.clone(),
|
||||
target,
|
||||
&url.to_utf8_lossy(),
|
||||
RequestOptions::get(),
|
||||
Request::get(url.to_utf8_lossy().into_owned()),
|
||||
None,
|
||||
Some(this),
|
||||
);
|
||||
|
|
|
@ -7,8 +7,8 @@ use crate::avm1::object::xml_object::XmlObject;
|
|||
use crate::avm1::property_decl::{define_properties_on, Declaration};
|
||||
use crate::avm1::{Object, TObject, Value};
|
||||
use crate::avm_warn;
|
||||
use crate::backend::navigator::RequestOptions;
|
||||
use crate::string::WStr;
|
||||
use crate::backend::navigator::Request;
|
||||
use crate::string::AvmString;
|
||||
use crate::xml::{XmlNode, ELEMENT_NODE, TEXT_NODE};
|
||||
use gc_arena::MutationContext;
|
||||
|
||||
|
@ -134,7 +134,7 @@ fn send_and_load<'gc>(
|
|||
|
||||
if let Some(document) = this.as_xml() {
|
||||
let url = url_val.coerce_to_string(activation)?;
|
||||
spawn_xml_fetch(activation, this, target, &url, Some(document.as_node()))?;
|
||||
spawn_xml_fetch(activation, this, target, url, Some(document.as_node()))?;
|
||||
}
|
||||
Ok(Value::Undefined)
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ fn load<'gc>(
|
|||
|
||||
if let Some(_document) = this.as_xml() {
|
||||
let url = url_val.coerce_to_string(activation)?;
|
||||
spawn_xml_fetch(activation, this, this, &url, None)?;
|
||||
spawn_xml_fetch(activation, this, this, url, None)?;
|
||||
|
||||
Ok(true.into())
|
||||
} else {
|
||||
|
@ -252,19 +252,24 @@ fn spawn_xml_fetch<'gc>(
|
|||
activation: &mut Activation<'_, 'gc, '_>,
|
||||
this: Object<'gc>,
|
||||
loader_object: Object<'gc>,
|
||||
url: &WStr,
|
||||
url: AvmString<'gc>,
|
||||
send_object: Option<XmlNode<'gc>>,
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
let request_options = if let Some(node) = send_object {
|
||||
let url = url.to_utf8_lossy().into_owned();
|
||||
|
||||
let request = if let Some(node) = send_object {
|
||||
// Send `node` as string.
|
||||
let string = node.into_string(activation)?;
|
||||
RequestOptions::post(Some((
|
||||
string.to_utf8_lossy().into_owned().into_bytes(),
|
||||
"application/x-www-form-urlencoded".to_string(),
|
||||
)))
|
||||
Request::post(
|
||||
url,
|
||||
Some((
|
||||
string.to_utf8_lossy().into_owned().into_bytes(),
|
||||
"application/x-www-form-urlencoded".to_string(),
|
||||
)),
|
||||
)
|
||||
} else {
|
||||
// Not sending any parameters.
|
||||
RequestOptions::get()
|
||||
Request::get(url)
|
||||
};
|
||||
|
||||
this.set("loaded", false.into(), activation)?;
|
||||
|
@ -272,8 +277,7 @@ fn spawn_xml_fetch<'gc>(
|
|||
let future = activation.context.load_manager.load_form_into_load_vars(
|
||||
activation.context.player.clone(),
|
||||
loader_object,
|
||||
&url.to_utf8_lossy(),
|
||||
request_options,
|
||||
request,
|
||||
);
|
||||
activation.context.navigator.spawn_future(future);
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ use crate::avm2::names::{Multiname, Namespace, QName};
|
|||
use crate::avm2::object::TObject;
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::{Error, Object};
|
||||
use crate::backend::navigator::RequestOptions;
|
||||
use crate::backend::navigator::Request;
|
||||
use crate::loader::DataFormat;
|
||||
use gc_arena::{GcCell, MutationContext};
|
||||
|
||||
|
@ -130,14 +130,11 @@ fn spawn_fetch<'gc>(
|
|||
.get_property(&QName::dynamic_name("url").into(), activation)?
|
||||
.coerce_to_string(activation)?;
|
||||
|
||||
let url = url.to_utf8_lossy();
|
||||
|
||||
let future = activation.context.load_manager.load_data_into_url_loader(
|
||||
activation.context.player.clone(),
|
||||
loader_object,
|
||||
&url,
|
||||
// FIXME - get these from the `URLRequest`
|
||||
RequestOptions::get(),
|
||||
Request::get(url.to_utf8_lossy().into_owned()),
|
||||
data_format,
|
||||
);
|
||||
activation.context.navigator.spawn_future(future);
|
||||
|
|
|
@ -54,8 +54,11 @@ impl NavigationMethod {
|
|||
}
|
||||
}
|
||||
|
||||
/// Represents request options to be sent as part of a fetch.
|
||||
pub struct RequestOptions {
|
||||
/// A fetch request.
|
||||
pub struct Request {
|
||||
/// The URL of the request.
|
||||
url: String,
|
||||
|
||||
/// The HTTP method to be used to make the request.
|
||||
method: NavigationMethod,
|
||||
|
||||
|
@ -66,23 +69,30 @@ pub struct RequestOptions {
|
|||
body: Option<(Vec<u8>, String)>,
|
||||
}
|
||||
|
||||
impl RequestOptions {
|
||||
/// Construct request options for a GET request.
|
||||
pub fn get() -> Self {
|
||||
impl Request {
|
||||
/// Construct a GET request.
|
||||
pub fn get(url: String) -> Self {
|
||||
Self {
|
||||
url,
|
||||
method: NavigationMethod::Get,
|
||||
body: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Construct request options for a POST request.
|
||||
pub fn post(body: Option<(Vec<u8>, String)>) -> Self {
|
||||
/// Construct a POST request.
|
||||
pub fn post(url: String, body: Option<(Vec<u8>, String)>) -> Self {
|
||||
Self {
|
||||
url,
|
||||
method: NavigationMethod::Post,
|
||||
body,
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieve the URL of this request.
|
||||
pub fn url(&self) -> &str {
|
||||
&self.url
|
||||
}
|
||||
|
||||
/// Retrieve the navigation method for this request.
|
||||
pub fn method(&self) -> NavigationMethod {
|
||||
self.method
|
||||
|
@ -138,8 +148,8 @@ pub trait NavigatorBackend {
|
|||
vars_method: Option<(NavigationMethod, IndexMap<String, String>)>,
|
||||
);
|
||||
|
||||
/// Fetch data at a given URL and return it some time in the future.
|
||||
fn fetch(&self, url: &str, request_options: RequestOptions) -> OwnedFuture<Response, Error>;
|
||||
/// Fetch data and return it some time in the future.
|
||||
fn fetch(&self, request: Request) -> OwnedFuture<Response, Error>;
|
||||
|
||||
/// Arrange for a future to be run at some point in the... well, future.
|
||||
///
|
||||
|
@ -280,9 +290,9 @@ impl NavigatorBackend for NullNavigatorBackend {
|
|||
) {
|
||||
}
|
||||
|
||||
fn fetch(&self, url: &str, _opts: RequestOptions) -> OwnedFuture<Response, Error> {
|
||||
fn fetch(&self, request: Request) -> OwnedFuture<Response, Error> {
|
||||
let mut path = self.relative_base_path.clone();
|
||||
path.push(url);
|
||||
path.push(request.url);
|
||||
|
||||
Box::pin(async move {
|
||||
let url = Self::url_from_file_path(&path)
|
||||
|
|
|
@ -11,7 +11,7 @@ use crate::avm2::{
|
|||
Activation as Avm2Activation, Avm2, Domain as Avm2Domain, Event as Avm2Event,
|
||||
EventData as Avm2EventData, Object as Avm2Object, QName, Value as Avm2Value,
|
||||
};
|
||||
use crate::backend::navigator::{OwnedFuture, RequestOptions};
|
||||
use crate::backend::navigator::{OwnedFuture, Request};
|
||||
use crate::backend::render::{determine_jpeg_tag_format, JpegTagFormat};
|
||||
use crate::context::{ActionQueue, ActionType, UpdateContext};
|
||||
use crate::display_object::{
|
||||
|
@ -189,15 +189,14 @@ impl<'gc> LoadManager<'gc> {
|
|||
pub fn load_root_movie(
|
||||
&mut self,
|
||||
player: Weak<Mutex<Player>>,
|
||||
url: &str,
|
||||
options: RequestOptions,
|
||||
request: Request,
|
||||
parameters: Vec<(String, String)>,
|
||||
on_metadata: Box<dyn FnOnce(&swf::HeaderExt)>,
|
||||
) -> OwnedFuture<(), Error> {
|
||||
let loader = Loader::RootMovie { self_handle: None };
|
||||
let handle = self.add_loader(loader);
|
||||
let loader = self.get_loader_mut(handle).unwrap();
|
||||
loader.root_movie_loader(player, url.to_owned(), options, parameters, on_metadata)
|
||||
loader.root_movie_loader(player, request, parameters, on_metadata)
|
||||
}
|
||||
|
||||
/// Kick off a movie clip load.
|
||||
|
@ -207,8 +206,7 @@ impl<'gc> LoadManager<'gc> {
|
|||
&mut self,
|
||||
player: Weak<Mutex<Player>>,
|
||||
target_clip: DisplayObject<'gc>,
|
||||
url: &str,
|
||||
options: RequestOptions,
|
||||
request: Request,
|
||||
loader_url: Option<String>,
|
||||
target_broadcaster: Option<Object<'gc>>,
|
||||
) -> OwnedFuture<(), Error> {
|
||||
|
@ -220,7 +218,7 @@ impl<'gc> LoadManager<'gc> {
|
|||
};
|
||||
let handle = self.add_loader(loader);
|
||||
let loader = self.get_loader_mut(handle).unwrap();
|
||||
loader.movie_loader(player, url.to_owned(), options, loader_url)
|
||||
loader.movie_loader(player, request, loader_url)
|
||||
}
|
||||
|
||||
/// Indicates that a movie clip has initialized (ran its first frame).
|
||||
|
@ -247,8 +245,7 @@ impl<'gc> LoadManager<'gc> {
|
|||
&mut self,
|
||||
player: Weak<Mutex<Player>>,
|
||||
target_object: Object<'gc>,
|
||||
url: &str,
|
||||
options: RequestOptions,
|
||||
request: Request,
|
||||
) -> OwnedFuture<(), Error> {
|
||||
let loader = Loader::Form {
|
||||
self_handle: None,
|
||||
|
@ -256,7 +253,7 @@ impl<'gc> LoadManager<'gc> {
|
|||
};
|
||||
let handle = self.add_loader(loader);
|
||||
let loader = self.get_loader_mut(handle).unwrap();
|
||||
loader.form_loader(player, url.to_owned(), options)
|
||||
loader.form_loader(player, request)
|
||||
}
|
||||
|
||||
/// Kick off a form data load into an AVM1 object.
|
||||
|
@ -266,8 +263,7 @@ impl<'gc> LoadManager<'gc> {
|
|||
&mut self,
|
||||
player: Weak<Mutex<Player>>,
|
||||
target_object: Object<'gc>,
|
||||
url: &str,
|
||||
options: RequestOptions,
|
||||
request: Request,
|
||||
) -> OwnedFuture<(), Error> {
|
||||
let loader = Loader::LoadVars {
|
||||
self_handle: None,
|
||||
|
@ -275,7 +271,7 @@ impl<'gc> LoadManager<'gc> {
|
|||
};
|
||||
let handle = self.add_loader(loader);
|
||||
let loader = self.get_loader_mut(handle).unwrap();
|
||||
loader.load_vars_loader(player, url.to_owned(), options)
|
||||
loader.load_vars_loader(player, request)
|
||||
}
|
||||
|
||||
/// Kick off a data load into a `URLLoader`, updating
|
||||
|
@ -286,8 +282,7 @@ impl<'gc> LoadManager<'gc> {
|
|||
&mut self,
|
||||
player: Weak<Mutex<Player>>,
|
||||
target_object: Avm2Object<'gc>,
|
||||
url: &str,
|
||||
options: RequestOptions,
|
||||
request: Request,
|
||||
data_format: DataFormat,
|
||||
) -> OwnedFuture<(), Error> {
|
||||
let loader = Loader::LoadURLLoader {
|
||||
|
@ -296,7 +291,7 @@ impl<'gc> LoadManager<'gc> {
|
|||
};
|
||||
let handle = self.add_loader(loader);
|
||||
let loader = self.get_loader_mut(handle).unwrap();
|
||||
loader.load_url_loader(player, url.to_owned(), options, data_format)
|
||||
loader.load_url_loader(player, request, data_format)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -390,8 +385,7 @@ impl<'gc> Loader<'gc> {
|
|||
fn root_movie_loader(
|
||||
&mut self,
|
||||
player: Weak<Mutex<Player>>,
|
||||
url: String,
|
||||
options: RequestOptions,
|
||||
request: Request,
|
||||
parameters: Vec<(String, String)>,
|
||||
on_metadata: Box<dyn FnOnce(&swf::HeaderExt)>,
|
||||
) -> OwnedFuture<(), Error> {
|
||||
|
@ -407,7 +401,7 @@ impl<'gc> Loader<'gc> {
|
|||
.expect("Could not upgrade weak reference to player");
|
||||
|
||||
Box::pin(async move {
|
||||
let fetch = player.lock().unwrap().navigator().fetch(&url, options);
|
||||
let fetch = player.lock().unwrap().navigator().fetch(request);
|
||||
|
||||
let response = fetch.await.map_err(|error| {
|
||||
player
|
||||
|
@ -436,8 +430,7 @@ impl<'gc> Loader<'gc> {
|
|||
fn movie_loader(
|
||||
&mut self,
|
||||
player: Weak<Mutex<Player>>,
|
||||
url: String,
|
||||
options: RequestOptions,
|
||||
request: Request,
|
||||
loader_url: Option<String>,
|
||||
) -> OwnedFuture<(), Error> {
|
||||
let handle = match self {
|
||||
|
@ -450,7 +443,7 @@ impl<'gc> Loader<'gc> {
|
|||
.expect("Could not upgrade weak reference to player");
|
||||
|
||||
Box::pin(async move {
|
||||
let fetch = player.lock().unwrap().navigator().fetch(&url, options);
|
||||
let fetch = player.lock().unwrap().navigator().fetch(request);
|
||||
|
||||
let mut replacing_root_movie = false;
|
||||
player.lock().unwrap().update(|uc| -> Result<(), Error> {
|
||||
|
@ -545,8 +538,7 @@ impl<'gc> Loader<'gc> {
|
|||
fn form_loader(
|
||||
&mut self,
|
||||
player: Weak<Mutex<Player>>,
|
||||
url: String,
|
||||
options: RequestOptions,
|
||||
request: Request,
|
||||
) -> OwnedFuture<(), Error> {
|
||||
let handle = match self {
|
||||
Loader::Form { self_handle, .. } => self_handle.expect("Loader not self-introduced"),
|
||||
|
@ -558,7 +550,7 @@ impl<'gc> Loader<'gc> {
|
|||
.expect("Could not upgrade weak reference to player");
|
||||
|
||||
Box::pin(async move {
|
||||
let fetch = player.lock().unwrap().navigator().fetch(&url, options);
|
||||
let fetch = player.lock().unwrap().navigator().fetch(request);
|
||||
|
||||
let response = fetch.await?;
|
||||
|
||||
|
@ -607,8 +599,7 @@ impl<'gc> Loader<'gc> {
|
|||
fn load_vars_loader(
|
||||
&mut self,
|
||||
player: Weak<Mutex<Player>>,
|
||||
url: String,
|
||||
options: RequestOptions,
|
||||
request: Request,
|
||||
) -> OwnedFuture<(), Error> {
|
||||
let handle = match self {
|
||||
Loader::LoadVars { self_handle, .. } => {
|
||||
|
@ -622,7 +613,7 @@ impl<'gc> Loader<'gc> {
|
|||
.expect("Could not upgrade weak reference to player");
|
||||
|
||||
Box::pin(async move {
|
||||
let fetch = player.lock().unwrap().navigator().fetch(&url, options);
|
||||
let fetch = player.lock().unwrap().navigator().fetch(request);
|
||||
|
||||
let data = fetch.await;
|
||||
|
||||
|
@ -689,8 +680,7 @@ impl<'gc> Loader<'gc> {
|
|||
fn load_url_loader(
|
||||
&mut self,
|
||||
player: Weak<Mutex<Player>>,
|
||||
url: String,
|
||||
options: RequestOptions,
|
||||
request: Request,
|
||||
data_format: DataFormat,
|
||||
) -> OwnedFuture<(), Error> {
|
||||
let handle = match self {
|
||||
|
@ -705,7 +695,7 @@ impl<'gc> Loader<'gc> {
|
|||
.expect("Could not upgrade weak reference to player");
|
||||
|
||||
Box::pin(async move {
|
||||
let fetch = player.lock().unwrap().navigator().fetch(&url, options);
|
||||
let fetch = player.lock().unwrap().navigator().fetch(request);
|
||||
let response = fetch.await;
|
||||
|
||||
player.lock().unwrap().update(|uc| {
|
||||
|
|
|
@ -8,7 +8,7 @@ use crate::avm2::{Activation as Avm2Activation, Avm2, Domain as Avm2Domain};
|
|||
use crate::backend::{
|
||||
audio::{AudioBackend, AudioManager},
|
||||
log::LogBackend,
|
||||
navigator::{NavigatorBackend, RequestOptions},
|
||||
navigator::{NavigatorBackend, Request},
|
||||
render::RenderBackend,
|
||||
storage::StorageBackend,
|
||||
ui::{InputManager, MouseCursor, UiBackend},
|
||||
|
@ -242,15 +242,14 @@ impl Player {
|
|||
/// off.
|
||||
pub fn fetch_root_movie(
|
||||
&mut self,
|
||||
movie_url: &str,
|
||||
movie_url: String,
|
||||
parameters: Vec<(String, String)>,
|
||||
on_metadata: Box<dyn FnOnce(&swf::HeaderExt)>,
|
||||
) {
|
||||
self.mutate_with_update_context(|context| {
|
||||
let future = context.load_manager.load_root_movie(
|
||||
context.player.clone(),
|
||||
movie_url,
|
||||
RequestOptions::get(),
|
||||
Request::get(movie_url),
|
||||
parameters,
|
||||
on_metadata,
|
||||
);
|
||||
|
|
|
@ -249,14 +249,14 @@ impl App {
|
|||
|
||||
let player = builder.build();
|
||||
|
||||
if let Some(movie_url) = &movie_url {
|
||||
if let Some(movie_url) = movie_url {
|
||||
let event_loop_proxy = event_loop.create_proxy();
|
||||
let on_metadata = move |swf_header: &ruffle_core::swf::HeaderExt| {
|
||||
let _ = event_loop_proxy.send_event(RuffleEvent::OnMetadata(swf_header.clone()));
|
||||
};
|
||||
|
||||
player.lock().unwrap().fetch_root_movie(
|
||||
movie_url.as_str(),
|
||||
movie_url.as_str().to_owned(),
|
||||
parse_parameters(&opt).collect(),
|
||||
Box::new(on_metadata),
|
||||
);
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
//! Navigator backend for web
|
||||
|
||||
use crate::custom_event::RuffleEvent;
|
||||
use isahc::{config::RedirectPolicy, prelude::*, AsyncReadResponseExt, HttpClient, Request};
|
||||
use isahc::{
|
||||
config::RedirectPolicy, prelude::*, AsyncReadResponseExt, HttpClient, Request as IsahcRequest,
|
||||
};
|
||||
use ruffle_core::backend::navigator::{
|
||||
NavigationMethod, NavigatorBackend, OwnedFuture, RequestOptions, Response,
|
||||
NavigationMethod, NavigatorBackend, OwnedFuture, Request, Response,
|
||||
};
|
||||
use ruffle_core::indexmap::IndexMap;
|
||||
use ruffle_core::loader::Error;
|
||||
|
@ -103,12 +105,12 @@ impl NavigatorBackend for ExternalNavigatorBackend {
|
|||
};
|
||||
}
|
||||
|
||||
fn fetch(&self, url: &str, options: RequestOptions) -> OwnedFuture<Response, Error> {
|
||||
fn fetch(&self, request: Request) -> OwnedFuture<Response, Error> {
|
||||
// TODO: honor sandbox type (local-with-filesystem, local-with-network, remote, ...)
|
||||
let full_url = match self.movie_url.join(url) {
|
||||
let full_url = match self.movie_url.join(request.url()) {
|
||||
Ok(url) => url,
|
||||
Err(e) => {
|
||||
let msg = format!("Invalid URL {}: {}", url, e);
|
||||
let msg = format!("Invalid URL {}: {}", request.url(), e);
|
||||
return Box::pin(async move { Err(Error::FetchError(msg)) });
|
||||
}
|
||||
};
|
||||
|
@ -152,13 +154,13 @@ impl NavigatorBackend for ExternalNavigatorBackend {
|
|||
let client =
|
||||
client.ok_or_else(|| Error::FetchError("Network unavailable".to_string()))?;
|
||||
|
||||
let request = match options.method() {
|
||||
NavigationMethod::Get => Request::get(processed_url.to_string()),
|
||||
NavigationMethod::Post => Request::post(processed_url.to_string()),
|
||||
let isahc_request = match request.method() {
|
||||
NavigationMethod::Get => IsahcRequest::get(processed_url.to_string()),
|
||||
NavigationMethod::Post => IsahcRequest::post(processed_url.to_string()),
|
||||
};
|
||||
|
||||
let (body_data, _) = options.body().clone().unwrap_or_default();
|
||||
let body = request
|
||||
let (body_data, _) = request.body().clone().unwrap_or_default();
|
||||
let body = isahc_request
|
||||
.body(body_data)
|
||||
.map_err(|e| Error::FetchError(e.to_string()))?;
|
||||
|
||||
|
|
|
@ -219,7 +219,7 @@ impl Ruffle {
|
|||
/// Stream an arbitrary movie file from (presumably) the Internet.
|
||||
///
|
||||
/// This method should only be called once per player.
|
||||
pub fn stream_from(&mut self, movie_url: &str, parameters: &JsValue) -> Result<(), JsValue> {
|
||||
pub fn stream_from(&mut self, movie_url: String, parameters: &JsValue) -> Result<(), JsValue> {
|
||||
let _ = self.with_core_mut(|core| {
|
||||
let parameters_to_load = parse_movie_parameters(parameters);
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
//! Navigator backend for web
|
||||
use js_sys::{Array, ArrayBuffer, Uint8Array};
|
||||
use ruffle_core::backend::navigator::{
|
||||
url_from_relative_url, NavigationMethod, NavigatorBackend, OwnedFuture, RequestOptions,
|
||||
Response,
|
||||
url_from_relative_url, NavigationMethod, NavigatorBackend, OwnedFuture, Request, Response,
|
||||
};
|
||||
use ruffle_core::indexmap::IndexMap;
|
||||
use ruffle_core::loader::Error;
|
||||
|
@ -11,7 +10,8 @@ use url::Url;
|
|||
use wasm_bindgen::JsCast;
|
||||
use wasm_bindgen_futures::{spawn_local, JsFuture};
|
||||
use web_sys::{
|
||||
window, Blob, BlobPropertyBag, Document, Request, RequestInit, Response as WebResponse,
|
||||
window, Blob, BlobPropertyBag, Document, Request as WebRequest, RequestInit,
|
||||
Response as WebResponse,
|
||||
};
|
||||
|
||||
pub struct WebNavigatorBackend {
|
||||
|
@ -173,22 +173,22 @@ impl NavigatorBackend for WebNavigatorBackend {
|
|||
}
|
||||
}
|
||||
|
||||
fn fetch(&self, url: &str, options: RequestOptions) -> OwnedFuture<Response, Error> {
|
||||
let url = if let Ok(parsed_url) = Url::parse(url) {
|
||||
fn fetch(&self, request: Request) -> OwnedFuture<Response, Error> {
|
||||
let url = if let Ok(parsed_url) = Url::parse(request.url()) {
|
||||
self.pre_process_url(parsed_url).to_string()
|
||||
} else {
|
||||
self.resolve_relative_url(url).to_string()
|
||||
self.resolve_relative_url(request.url()).to_string()
|
||||
};
|
||||
|
||||
Box::pin(async move {
|
||||
let mut init = RequestInit::new();
|
||||
|
||||
init.method(match options.method() {
|
||||
init.method(match request.method() {
|
||||
NavigationMethod::Get => "GET",
|
||||
NavigationMethod::Post => "POST",
|
||||
});
|
||||
|
||||
if let Some((data, mime)) = options.body() {
|
||||
if let Some((data, mime)) = request.body() {
|
||||
let arraydata = ArrayBuffer::new(data.len() as u32);
|
||||
let u8data = Uint8Array::new(&arraydata);
|
||||
|
||||
|
@ -211,7 +211,7 @@ impl NavigatorBackend for WebNavigatorBackend {
|
|||
init.body(Some(&datablob));
|
||||
}
|
||||
|
||||
let request = Request::new_with_str_and_init(&url, &init)
|
||||
let request = WebRequest::new_with_str_and_init(&url, &init)
|
||||
.map_err(|_| Error::FetchError(format!("Unable to create request for {}", url)))?;
|
||||
|
||||
let window = web_sys::window().unwrap();
|
||||
|
|
Loading…
Reference in New Issue