Skip to content

Commit

Permalink
feat(linux): add headers to URL scheme request (#721)
Browse files Browse the repository at this point in the history
Co-authored-by: Wu Yu Wei <wusyong9104@gmail.com>
Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
  • Loading branch information
3 people committed Oct 17, 2022
1 parent 17d324b commit 2944d91
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 25 deletions.
5 changes: 5 additions & 0 deletions .changes/linux-headers.md
@@ -0,0 +1,5 @@
---
"wry": patch
---

On Linux, Improve custom protocol with http headers / method added to request, and status code / http headers added to response. This feature is 2.36 only, version below it will fallback to previous implementation.
4 changes: 3 additions & 1 deletion Cargo.toml
Expand Up @@ -50,12 +50,13 @@ tempfile = "3.3.0"
http-range = "0.1.5"

[target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
webkit2gtk = { version = "0.18", features = [ "v2_22" ] }
webkit2gtk = { version = "0.18.2", features = [ "v2_36" ] }
webkit2gtk-sys = "0.18"
gio = "0.15"
glib = "0.15"
gtk = "0.15"
gdk = "0.15"
soup2 = "0.2"

[target."cfg(target_os = \"windows\")".dependencies]
webview2-com = "0.19.1"
Expand Down Expand Up @@ -91,3 +92,4 @@ kuchiki = "0.8"
html5ever = "0.25"
sha2 = "0.10"
base64 = "0.13"

1 change: 0 additions & 1 deletion src/webview/webkitgtk/mod.rs
Expand Up @@ -251,7 +251,6 @@ impl InnerWebView {
if let Some(settings) = WebViewExt::settings(&*webview) {
settings.set_enable_webgl(true);
settings.set_enable_webaudio(true);
settings.set_enable_accelerated_2d_canvas(true);

// Enable clipboard
if attributes.clipboard {
Expand Down
77 changes: 54 additions & 23 deletions src/webview/webkitgtk/web_context.rs
Expand Up @@ -6,7 +6,11 @@

use crate::{webview::web_context::WebContextData, Error};
use glib::FileError;
use http::{header::CONTENT_TYPE, Request, Response};
use http::{
header::{HeaderName, CONTENT_TYPE},
HeaderValue, Request, Response,
};
use soup::{MessageHeaders, MessageHeadersType};
use std::{
collections::{HashSet, VecDeque},
rc::Rc,
Expand All @@ -16,11 +20,14 @@ use std::{
},
};
use url::Url;
//use webkit2gtk_sys::webkit_uri_request_get_http_headers;
use webkit2gtk::{
traits::*, ApplicationInfo, CookiePersistentStorage, LoadEvent, UserContentManager, WebContext,
WebContextBuilder, WebView, WebsiteDataManagerBuilder,
traits::*, ApplicationInfo, CookiePersistentStorage, LoadEvent, URISchemeResponse,
UserContentManager, WebContext, WebContextBuilder, WebView, WebsiteDataManagerBuilder,
};
use webkit2gtk_sys::webkit_get_minor_version;

// header support was introduced in webkit2gtk 2.36
const HEADER_MINOR_RELEASE: u32 = 36;

#[derive(Debug)]
pub struct WebContextImpl {
Expand All @@ -30,6 +37,7 @@ pub struct WebContextImpl {
registered_protocols: HashSet<String>,
automation: bool,
app_info: Option<ApplicationInfo>,
webkit2gtk_minor: u32,
}

impl WebContextImpl {
Expand Down Expand Up @@ -76,13 +84,16 @@ impl WebContextImpl {
.expect("invalid wry version patch"),
);

let webkit2gtk_minor = unsafe { webkit_get_minor_version() };

Self {
context,
automation,
manager: UserContentManager::new(),
registered_protocols: Default::default(),
webview_uri_loader: Rc::default(),
app_info: Some(app_info),
webkit2gtk_minor,
}
}

Expand Down Expand Up @@ -210,6 +221,7 @@ where
F: Fn(&Request<Vec<u8>>) -> crate::Result<Response<Vec<u8>>> + 'static,
{
use webkit2gtk::traits::*;
let webkit2gtk_minor = context.os.webkit2gtk_minor;
let context = &context.os.context;
// Enable secure context
context
Expand All @@ -221,14 +233,26 @@ where
if let Some(uri) = request.uri() {
let uri = uri.as_str();

//let headers = unsafe {
// webkit_uri_request_get_http_headers(request.clone().to_glib_none().0)
//};

// FIXME: Read the method
// FIXME: Read the headers
// FIXME: Read the body (forms post)
let http_request = match Request::builder().uri(uri).method("GET").body(Vec::new()) {
let mut http_request = Request::builder().uri(uri).method("GET");
if webkit2gtk_minor >= HEADER_MINOR_RELEASE {
if let Some(mut headers) = request.http_headers() {
if let Some(map) = http_request.headers_mut() {
headers.foreach(move |k, v| {
if let Ok(name) = HeaderName::from_bytes(k.as_bytes()) {
if let Ok(value) = HeaderValue::from_bytes(v.as_bytes()) {
map.insert(name, value);
}
}
});
}
}

if let Some(method) = request.http_method() {
http_request = http_request.method(method.as_str());
}
}
let http_request = match http_request.body(Vec::new()) {
Ok(req) => req,
Err(_) => {
request.finish_error(&mut glib::Error::new(
Expand All @@ -243,19 +267,26 @@ where
match handler(&http_request) {
Ok(http_response) => {
let buffer = http_response.body();

// FIXME: Set status code
// FIXME: Set sent headers

let input = gio::MemoryInputStream::from_bytes(&glib::Bytes::from(buffer));
request.finish(
&input,
buffer.len() as i64,
http_response
.headers()
.get(CONTENT_TYPE)
.map(|h| h.to_str().unwrap_or("text/plain")),
)
let content_type = http_response
.headers()
.get(CONTENT_TYPE)
.map(|h| h.to_str().unwrap_or("text/plain"));
if webkit2gtk_minor >= HEADER_MINOR_RELEASE {
let response = URISchemeResponse::new(&input, buffer.len() as i64);
response.set_status(http_response.status().as_u16() as u32, None);
response.set_content_type(content_type.unwrap());

let mut headers = MessageHeaders::new(MessageHeadersType::Response);
for (name, value) in http_response.headers().into_iter() {
headers.append(name.as_str(), value.to_str().unwrap_or(""));
}
response.set_http_headers(&mut headers);

request.finish_with_response(&response);
} else {
request.finish(&input, buffer.len() as i64, content_type)
}
}
Err(_) => request.finish_error(&mut glib::Error::new(
FileError::Exist,
Expand Down

0 comments on commit 2944d91

Please sign in to comment.