Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/nightly_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
uses: actions/checkout@v6

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
targets: ${{ matrix.target }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
fetch-depth: 0

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@master
with:
toolchain: stable

Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
uses: actions/checkout@v6

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@master
with:
toolchain: stable

Expand Down Expand Up @@ -52,7 +52,7 @@ jobs:
uses: actions/checkout@v6

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
targets: wasm32-unknown-unknown
Expand Down Expand Up @@ -112,7 +112,7 @@ jobs:
uses: actions/checkout@v6

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
targets: ${{ matrix.target }}
Expand Down
21 changes: 12 additions & 9 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ jobs:
uses: actions/checkout@v6

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@master
with:
toolchain: stable

- name: Cache cargo
uses: actions/cache@v5
Expand Down Expand Up @@ -82,7 +84,7 @@ jobs:
uses: actions/checkout@v6

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@master
with:
toolchain: stable

Expand Down Expand Up @@ -128,8 +130,9 @@ jobs:
uses: actions/checkout@v6

- name: Install Rust nightly with miri
uses: dtolnay/rust-toolchain@nightly
uses: dtolnay/rust-toolchain@master
with:
toolchain: nightly
components: miri

- name: Cache cargo
Expand Down Expand Up @@ -165,7 +168,7 @@ jobs:
run: echo "rust_version=$(grep '^rust-version' Cargo.toml | cut -d' ' -f3 | tr -d '"')" >> $GITHUB_OUTPUT

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ steps.rust_version.outputs.rust_version }}

Expand All @@ -185,7 +188,7 @@ jobs:
uses: actions/checkout@v6

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
components: rustfmt
Expand Down Expand Up @@ -217,7 +220,7 @@ jobs:
uses: actions/checkout@v6

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
components: clippy
Expand Down Expand Up @@ -260,7 +263,7 @@ jobs:
uses: actions/checkout@v6

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@master
with:
toolchain: stable

Expand Down Expand Up @@ -289,7 +292,7 @@ jobs:
uses: actions/checkout@v6

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@master
with:
toolchain: stable

Expand Down Expand Up @@ -321,7 +324,7 @@ jobs:
uses: actions/checkout@v6

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@master
with:
toolchain: stable

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test262_pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
ref: ${{ github.event.pull_request.head.sha }}

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@master
with:
toolchain: stable

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test262_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:

# Install Rust toolchain
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@master
with:
toolchain: stable

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/webassembly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
uses: actions/checkout@v6

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@master
with:
toolchain: stable

Expand Down
5 changes: 4 additions & 1 deletion core/engine/src/module/loader/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ pub fn resolve_module_specifier(

// On Windows, also replace `/` with `\`. JavaScript imports use `/` as path separator.
#[cfg(target_family = "windows")]
let specifier = specifier.replace('/', "\\");
let specifier = {
use cow_utils::CowUtils;
specifier.cow_replace('/', "\\").into_owned()
};

let short_path = Path::new(&specifier);

Expand Down
2 changes: 1 addition & 1 deletion core/runtime/src/fetch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ async fn fetch_inner<T: Fetcher>(
};

let mut request = if let Some(options) = options {
options.into_request_builder(Some(request))?
options.into_request_builder(Some(request), &mut context.borrow_mut())?
} else {
request
};
Expand Down
91 changes: 85 additions & 6 deletions core/runtime/src/fetch/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
//!
//! [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/Request
use super::HttpRequest;
use boa_engine::object::builtins::{JsArrayBuffer, JsDataView, JsSharedArrayBuffer, JsTypedArray};
use boa_engine::value::{Convert, TryFromJs};
use boa_engine::{
Finalize, JsData, JsObject, JsResult, JsString, JsValue, Trace, boa_class, js_error,
Expand Down Expand Up @@ -67,9 +68,11 @@ impl RequestInit {
///
/// # Errors
/// If the body is not a valid type, an error is returned.
#[allow(clippy::too_many_lines)]
pub fn into_request_builder(
mut self,
request: Option<HttpRequest<Vec<u8>>>,
context: &mut boa_engine::Context,
) -> JsResult<HttpRequest<Vec<u8>>> {
let mut builder = HttpRequest::builder();
let mut request_body = Vec::new();
Expand Down Expand Up @@ -104,12 +107,86 @@ impl RequestInit {
}

if let Some(body) = &self.body {
// TODO: add more support types.
if let Some(body) = body.as_string() {
let body = body.to_std_string().map_err(
// TODO: support additional Fetch body types (e.g., Blob, FormData, URLSearchParams).
if let Some(str_body) = body.as_string() {
let body_str = str_body.to_std_string().map_err(
|_| js_error!(TypeError: "Request constructor: body is not a valid string"),
)?;
request_body = body.into_bytes();
request_body = body_str.into_bytes();
} else if let Some(object) = body.as_object() {
if let Ok(buf) = JsArrayBuffer::from_object(object.clone()) {
if let Some(bytes) = buf.to_vec() {
request_body = bytes;
} else {
return Err(
js_error!(TypeError: "Request constructor: ArrayBuffer detached or unusable"),
);
}
} else if let Ok(buf) = JsSharedArrayBuffer::from_object(object.clone()) {
request_body = buf.to_vec();
} else if let Ok(ta) = JsTypedArray::from_object(object.clone()) {
let buffer = ta.buffer(context)?;
let buffer_obj = buffer
.as_object()
.ok_or_else(|| {
js_error!(TypeError: "Request constructor: TypedArray buffer must be an object")
})?
.clone();

let offset = ta.byte_offset(context)?;
let length = ta.byte_length(context)?;

if let Ok(array_buffer) = JsArrayBuffer::from_object(buffer_obj.clone()) {
if let Some(buffer_data) = array_buffer.data() {
let bytes = buffer_data.as_ref();
request_body = bytes[offset..offset + length].to_vec();
} else {
return Err(
js_error!(TypeError: "Request constructor: TypedArray buffer detached or unusable"),
);
}
} else if let Ok(shared_buffer) = JsSharedArrayBuffer::from_object(buffer_obj) {
let bytes = shared_buffer.to_vec();
request_body = bytes[offset..offset + length].to_vec();
} else {
return Err(
js_error!(TypeError: "Request constructor: TypedArray buffer is not an ArrayBuffer or SharedArrayBuffer"),
);
}
} else if let Ok(dv) = JsDataView::from_object(object.clone()) {
let buffer = dv.buffer(context)?;
let buffer_obj = buffer
.as_object()
.ok_or_else(|| {
js_error!(TypeError: "Request constructor: DataView buffer must be an object")
})?
.clone();

let offset = usize::try_from(dv.byte_offset(context)?).unwrap_or(0);
let length = usize::try_from(dv.byte_length(context)?).unwrap_or(0);

if let Ok(array_buffer) = JsArrayBuffer::from_object(buffer_obj.clone()) {
if let Some(buffer_data) = array_buffer.data() {
let bytes = buffer_data.as_ref();
request_body = bytes[offset..offset + length].to_vec();
} else {
return Err(
js_error!(TypeError: "Request constructor: DataView buffer detached or unusable"),
);
}
} else if let Ok(shared_buffer) = JsSharedArrayBuffer::from_object(buffer_obj) {
let bytes = shared_buffer.to_vec();
request_body = bytes[offset..offset + length].to_vec();
} else {
return Err(
js_error!(TypeError: "Request constructor: DataView buffer is not an ArrayBuffer or SharedArrayBuffer"),
);
}
} else {
return Err(
js_error!(TypeError: "Request constructor: body is not a supported type"),
);
}
} else {
return Err(
js_error!(TypeError: "Request constructor: body is not a supported type"),
Expand Down Expand Up @@ -158,6 +235,7 @@ impl JsRequest {
pub fn create_from_js(
input: Either<JsString, JsRequest>,
options: Option<RequestInit>,
context: &mut boa_engine::Context,
) -> JsResult<Self> {
let request = match input {
Either::Left(uri) => {
Expand All @@ -175,7 +253,7 @@ impl JsRequest {
};

if let Some(options) = options {
let inner = options.into_request_builder(Some(request))?;
let inner = options.into_request_builder(Some(request), context)?;
Ok(Self { inner })
} else {
Ok(Self { inner: request })
Expand All @@ -199,6 +277,7 @@ impl JsRequest {
pub fn constructor(
input: Either<JsString, JsObject>,
options: Option<RequestInit>,
context: &mut boa_engine::Context,
) -> JsResult<Self> {
// Need to use a match as `Either::map_right` does not have an equivalent
// `Either::map_right_ok`.
Expand All @@ -212,6 +291,6 @@ impl JsRequest {
}
Either::Left(i) => Either::Left(i),
};
JsRequest::create_from_js(input, options)
JsRequest::create_from_js(input, options, context)
}
}
Loading
Loading