desktop: Add HTTP Referer and Cookie (#16424)
This commit is contained in:
parent
3aa7c07e95
commit
e1f014ea85
|
@ -5,6 +5,8 @@ movie-parameters = Movie Parameters
|
|||
custom-base-url = Custom Base URL
|
||||
|
||||
spoof-swf-url = Spoof SWF URL
|
||||
referer-url = Referer URL
|
||||
cookie = Cookie
|
||||
|
||||
proxy = Proxy
|
||||
|
||||
|
|
|
@ -149,6 +149,15 @@ pub struct Opt {
|
|||
#[clap(long, value_parser)]
|
||||
pub spoof_url: Option<Url>,
|
||||
|
||||
/// Spoofs the HTTP referer header.
|
||||
#[clap(long, value_parser)]
|
||||
pub referer: Option<Url>,
|
||||
|
||||
/// Spoofs the HTTP cookie header.
|
||||
/// This is a string of the form "name1=value1; name2=value2".
|
||||
#[clap(long)]
|
||||
pub cookie: Option<String>,
|
||||
|
||||
/// The version of the player to emulate
|
||||
#[clap(long)]
|
||||
pub player_version: Option<u8>,
|
||||
|
|
|
@ -23,6 +23,8 @@ pub struct OpenDialog {
|
|||
// These are outside of PlayerOptions as it can be an invalid value (ie URL) during typing,
|
||||
// and we don't want to clear the value if the user, ie, toggles the checkbox.
|
||||
spoof_url: OptionalField<UrlField>,
|
||||
referer: OptionalField<UrlField>,
|
||||
cookie: OptionalField<CookieField>,
|
||||
base_url: OptionalField<UrlField>,
|
||||
proxy_url: OptionalField<UrlField>,
|
||||
path: PathOrUrlField,
|
||||
|
@ -53,6 +55,14 @@ impl OpenDialog {
|
|||
defaults.player.spoof_url.as_ref().map(Url::to_string),
|
||||
UrlField::new("https://example.org/game.swf"),
|
||||
);
|
||||
let referer = OptionalField::new(
|
||||
defaults.player.referer.as_ref().map(Url::to_string),
|
||||
UrlField::new("https://example.org"),
|
||||
);
|
||||
let cookie = OptionalField::new(
|
||||
defaults.player.cookie.clone(),
|
||||
CookieField::new("value1=cookie1; value2=cookie2"),
|
||||
);
|
||||
let base_url = OptionalField::new(
|
||||
defaults.player.base.as_ref().map(Url::to_string),
|
||||
UrlField::new("https://example.org"),
|
||||
|
@ -242,6 +252,8 @@ impl OpenDialog {
|
|||
options: defaults,
|
||||
event_loop,
|
||||
spoof_url,
|
||||
referer,
|
||||
cookie,
|
||||
base_url,
|
||||
proxy_url,
|
||||
path,
|
||||
|
@ -354,6 +366,20 @@ impl OpenDialog {
|
|||
.is_valid();
|
||||
ui.end_row();
|
||||
|
||||
ui.label(text(locale, "referer-url"));
|
||||
is_valid &= self
|
||||
.referer
|
||||
.ui(ui, &mut self.options.player.referer, locale)
|
||||
.is_valid();
|
||||
ui.end_row();
|
||||
|
||||
ui.label(text(locale, "cookie"));
|
||||
is_valid &= self
|
||||
.cookie
|
||||
.ui(ui, &mut self.options.player.cookie, locale)
|
||||
.is_valid();
|
||||
ui.end_row();
|
||||
|
||||
ui.label(text(locale, "proxy"));
|
||||
is_valid &= self
|
||||
.proxy_url
|
||||
|
@ -594,6 +620,40 @@ impl InnerField for UrlField {
|
|||
}
|
||||
}
|
||||
|
||||
struct CookieField {
|
||||
hint: &'static str,
|
||||
}
|
||||
|
||||
impl CookieField {
|
||||
pub fn new(hint: &'static str) -> Self {
|
||||
Self { hint }
|
||||
}
|
||||
}
|
||||
|
||||
impl InnerField for CookieField {
|
||||
type Value = String;
|
||||
type Result = String;
|
||||
|
||||
fn value_if_missing(&self) -> Self::Value {
|
||||
String::new()
|
||||
}
|
||||
|
||||
fn ui(&self, ui: &mut Ui, value: &mut Self::Value, error: bool, _locale: &LanguageIdentifier) {
|
||||
TextEdit::singleline(value)
|
||||
.hint_text(self.hint)
|
||||
.text_color_opt(if error {
|
||||
Some(ui.style().visuals.error_fg_color)
|
||||
} else {
|
||||
None
|
||||
})
|
||||
.ui(ui);
|
||||
}
|
||||
|
||||
fn value_to_result(&self, value: &Self::Value) -> Result<Self::Result, ()> {
|
||||
Ok(value.clone())
|
||||
}
|
||||
}
|
||||
|
||||
struct DurationField {
|
||||
range: RangeInclusive<f64>,
|
||||
default_seconds: f64,
|
||||
|
|
|
@ -75,6 +75,8 @@ impl From<&GlobalPreferences> for LaunchOptions {
|
|||
load_behavior: value.cli.load_behavior,
|
||||
letterbox: value.cli.letterbox,
|
||||
spoof_url: value.cli.spoof_url.clone(),
|
||||
referer: value.cli.referer.clone(),
|
||||
cookie: value.cli.cookie.clone(),
|
||||
player_version: value.cli.player_version,
|
||||
player_runtime: value.cli.player_runtime,
|
||||
frame_rate: value.cli.frame_rate,
|
||||
|
@ -192,6 +194,8 @@ impl ActivePlayer {
|
|||
.base
|
||||
.to_owned()
|
||||
.unwrap_or_else(|| movie_url.clone()),
|
||||
opt.player.referer.clone(),
|
||||
opt.player.cookie.clone(),
|
||||
future_spawner,
|
||||
opt.proxy.clone(),
|
||||
opt.player.upgrade_to_https.unwrap_or_default(),
|
||||
|
|
|
@ -9,7 +9,7 @@ use async_net::TcpStream;
|
|||
use futures::future::select;
|
||||
use futures::{AsyncReadExt, AsyncWriteExt};
|
||||
use futures_lite::FutureExt;
|
||||
use reqwest::Proxy;
|
||||
use reqwest::{cookie, header, Proxy};
|
||||
use ruffle_core::backend::navigator::{
|
||||
async_return, create_fetch_error, ErrorResponse, NavigationMethod, NavigatorBackend,
|
||||
OpenURLMode, OwnedFuture, Request, SocketMode, SuccessResponse,
|
||||
|
@ -70,6 +70,8 @@ impl<F: FutureSpawner, I: NavigatorInterface> ExternalNavigatorBackend<F, I> {
|
|||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
mut base_url: Url,
|
||||
referer: Option<Url>,
|
||||
cookie: Option<String>,
|
||||
future_spawner: F,
|
||||
proxy: Option<Url>,
|
||||
upgrade_to_https: bool,
|
||||
|
@ -81,6 +83,19 @@ impl<F: FutureSpawner, I: NavigatorInterface> ExternalNavigatorBackend<F, I> {
|
|||
) -> Self {
|
||||
let mut builder = reqwest::ClientBuilder::new().cookie_store(true);
|
||||
|
||||
if let Some(referer) = referer {
|
||||
let mut headers = header::HeaderMap::new();
|
||||
headers.insert(header::REFERER, referer.to_string().parse().unwrap());
|
||||
builder = builder.default_headers(headers);
|
||||
}
|
||||
|
||||
if let Some(cookie) = cookie {
|
||||
let cookie_jar = cookie::Jar::default();
|
||||
cookie_jar.add_cookie_str(&cookie, &base_url);
|
||||
let cookie_store = std::sync::Arc::new(cookie_jar);
|
||||
builder = builder.cookie_provider(cookie_store)
|
||||
}
|
||||
|
||||
if let Some(proxy) = proxy {
|
||||
match Proxy::all(proxy.clone()) {
|
||||
Ok(proxy) => {
|
||||
|
@ -535,6 +550,8 @@ mod tests {
|
|||
let url = Url::parse("https://example.com/path/").unwrap();
|
||||
ExternalNavigatorBackend::new(
|
||||
url.clone(),
|
||||
None,
|
||||
None,
|
||||
TestFutureSpawner,
|
||||
None,
|
||||
false,
|
||||
|
|
|
@ -21,6 +21,8 @@ pub struct PlayerOptions {
|
|||
pub load_behavior: Option<LoadBehavior>,
|
||||
pub letterbox: Option<Letterbox>,
|
||||
pub spoof_url: Option<Url>,
|
||||
pub referer: Option<Url>,
|
||||
pub cookie: Option<String>,
|
||||
pub player_version: Option<u8>,
|
||||
pub player_runtime: Option<PlayerRuntime>,
|
||||
pub frame_rate: Option<f64>,
|
||||
|
@ -44,6 +46,8 @@ impl PlayerOptions {
|
|||
load_behavior: self.load_behavior.or(other.load_behavior),
|
||||
letterbox: self.letterbox.or(other.letterbox),
|
||||
spoof_url: self.spoof_url.clone().or_else(|| other.spoof_url.clone()),
|
||||
referer: self.referer.clone().or_else(|| other.referer.clone()),
|
||||
cookie: self.cookie.clone().or_else(|| other.cookie.clone()),
|
||||
player_version: self.player_version.or(other.player_version),
|
||||
player_runtime: self.player_runtime.or(other.player_runtime),
|
||||
frame_rate: self.frame_rate.or(other.frame_rate),
|
||||
|
|
Loading…
Reference in New Issue