mirror of
https://github.com/denoland/deno.git
synced 2024-11-22 04:51:22 +00:00
fix(websocket): Fix PermissionDenied error being caught in constructor (#8402)
This commit is contained in:
parent
fb13967d1d
commit
d40b0711a7
@ -8,12 +8,12 @@ use deno_core::error::AnyError;
|
||||
use deno_core::futures::future::poll_fn;
|
||||
use deno_core::futures::StreamExt;
|
||||
use deno_core::futures::{ready, SinkExt};
|
||||
use deno_core::serde_json;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_core::serde_json::Value;
|
||||
use deno_core::url;
|
||||
use deno_core::BufVec;
|
||||
use deno_core::OpState;
|
||||
use deno_core::{serde_json, ZeroCopyBuf};
|
||||
use http::{Method, Request, Uri};
|
||||
use serde::Deserialize;
|
||||
use std::borrow::Cow;
|
||||
@ -34,6 +34,7 @@ use tokio_tungstenite::{client_async, WebSocketStream};
|
||||
use webpki::DNSNameRef;
|
||||
|
||||
pub fn init(rt: &mut deno_core::JsRuntime) {
|
||||
super::reg_json_sync(rt, "op_ws_check_permission", op_ws_check_permission);
|
||||
super::reg_json_async(rt, "op_ws_create", op_ws_create);
|
||||
super::reg_json_async(rt, "op_ws_send", op_ws_send);
|
||||
super::reg_json_async(rt, "op_ws_close", op_ws_close);
|
||||
@ -45,6 +46,29 @@ type MaybeTlsStream =
|
||||
|
||||
type WsStream = WebSocketStream<MaybeTlsStream>;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct CheckPermissionArgs {
|
||||
url: String,
|
||||
}
|
||||
|
||||
// This op is needed because creating a WS instance in JavaScript is a sync
|
||||
// operation and should throw error when permissions are not fullfiled,
|
||||
// but actual op that connects WS is async.
|
||||
pub fn op_ws_check_permission(
|
||||
state: &mut OpState,
|
||||
args: Value,
|
||||
_zero_copy: &mut [ZeroCopyBuf],
|
||||
) -> Result<Value, AnyError> {
|
||||
let args: CheckPermissionArgs = serde_json::from_value(args)?;
|
||||
|
||||
state
|
||||
.borrow::<Permissions>()
|
||||
.check_net_url(&url::Url::parse(&args.url)?)?;
|
||||
|
||||
Ok(json!({}))
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct CreateArgs {
|
||||
@ -58,11 +82,16 @@ pub async fn op_ws_create(
|
||||
_bufs: BufVec,
|
||||
) -> Result<Value, AnyError> {
|
||||
let args: CreateArgs = serde_json::from_value(args)?;
|
||||
|
||||
{
|
||||
let s = state.borrow();
|
||||
s.borrow::<Permissions>()
|
||||
.check_net_url(&url::Url::parse(&args.url)?)?;
|
||||
.check_net_url(&url::Url::parse(&args.url)?)
|
||||
.expect(
|
||||
"Permission check should have been done in op_ws_check_permission",
|
||||
);
|
||||
}
|
||||
|
||||
let ca_file = {
|
||||
let cli_state = super::global_state2(&state);
|
||||
cli_state.flags.ca_file.clone()
|
||||
|
@ -33,6 +33,10 @@
|
||||
|
||||
this.#url = wsURL.href;
|
||||
|
||||
core.jsonOpSync("op_ws_check_permission", {
|
||||
url: this.#url,
|
||||
});
|
||||
|
||||
if (protocols && typeof protocols === "string") {
|
||||
protocols = [protocols];
|
||||
}
|
||||
|
@ -79,3 +79,4 @@ import "./write_file_test.ts";
|
||||
import "./write_text_file_test.ts";
|
||||
import "./performance_test.ts";
|
||||
import "./version_test.ts";
|
||||
import "./websocket_test.ts";
|
||||
|
9
cli/tests/unit/websocket_test.ts
Normal file
9
cli/tests/unit/websocket_test.ts
Normal file
@ -0,0 +1,9 @@
|
||||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
import { assertThrows, unitTest } from "./test_util.ts";
|
||||
|
||||
unitTest(function websocketPermissionless() {
|
||||
assertThrows(
|
||||
() => new WebSocket("ws://localhost"),
|
||||
Deno.errors.PermissionDenied,
|
||||
);
|
||||
});
|
Loading…
Reference in New Issue
Block a user