mirror of
https://github.com/denoland/deno.git
synced 2025-01-02 20:38:47 -05:00
fix(websocket): Fix PermissionDenied error being caught in constructor (#8402)
This commit is contained in:
parent
fb13967d1d
commit
d40b0711a7
4 changed files with 45 additions and 2 deletions
|
@ -8,12 +8,12 @@ use deno_core::error::AnyError;
|
||||||
use deno_core::futures::future::poll_fn;
|
use deno_core::futures::future::poll_fn;
|
||||||
use deno_core::futures::StreamExt;
|
use deno_core::futures::StreamExt;
|
||||||
use deno_core::futures::{ready, SinkExt};
|
use deno_core::futures::{ready, SinkExt};
|
||||||
use deno_core::serde_json;
|
|
||||||
use deno_core::serde_json::json;
|
use deno_core::serde_json::json;
|
||||||
use deno_core::serde_json::Value;
|
use deno_core::serde_json::Value;
|
||||||
use deno_core::url;
|
use deno_core::url;
|
||||||
use deno_core::BufVec;
|
use deno_core::BufVec;
|
||||||
use deno_core::OpState;
|
use deno_core::OpState;
|
||||||
|
use deno_core::{serde_json, ZeroCopyBuf};
|
||||||
use http::{Method, Request, Uri};
|
use http::{Method, Request, Uri};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
@ -34,6 +34,7 @@ use tokio_tungstenite::{client_async, WebSocketStream};
|
||||||
use webpki::DNSNameRef;
|
use webpki::DNSNameRef;
|
||||||
|
|
||||||
pub fn init(rt: &mut deno_core::JsRuntime) {
|
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_create", op_ws_create);
|
||||||
super::reg_json_async(rt, "op_ws_send", op_ws_send);
|
super::reg_json_async(rt, "op_ws_send", op_ws_send);
|
||||||
super::reg_json_async(rt, "op_ws_close", op_ws_close);
|
super::reg_json_async(rt, "op_ws_close", op_ws_close);
|
||||||
|
@ -45,6 +46,29 @@ type MaybeTlsStream =
|
||||||
|
|
||||||
type WsStream = WebSocketStream<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)]
|
#[derive(Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
struct CreateArgs {
|
struct CreateArgs {
|
||||||
|
@ -58,11 +82,16 @@ pub async fn op_ws_create(
|
||||||
_bufs: BufVec,
|
_bufs: BufVec,
|
||||||
) -> Result<Value, AnyError> {
|
) -> Result<Value, AnyError> {
|
||||||
let args: CreateArgs = serde_json::from_value(args)?;
|
let args: CreateArgs = serde_json::from_value(args)?;
|
||||||
|
|
||||||
{
|
{
|
||||||
let s = state.borrow();
|
let s = state.borrow();
|
||||||
s.borrow::<Permissions>()
|
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 ca_file = {
|
||||||
let cli_state = super::global_state2(&state);
|
let cli_state = super::global_state2(&state);
|
||||||
cli_state.flags.ca_file.clone()
|
cli_state.flags.ca_file.clone()
|
||||||
|
|
|
@ -33,6 +33,10 @@
|
||||||
|
|
||||||
this.#url = wsURL.href;
|
this.#url = wsURL.href;
|
||||||
|
|
||||||
|
core.jsonOpSync("op_ws_check_permission", {
|
||||||
|
url: this.#url,
|
||||||
|
});
|
||||||
|
|
||||||
if (protocols && typeof protocols === "string") {
|
if (protocols && typeof protocols === "string") {
|
||||||
protocols = [protocols];
|
protocols = [protocols];
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,3 +79,4 @@ import "./write_file_test.ts";
|
||||||
import "./write_text_file_test.ts";
|
import "./write_text_file_test.ts";
|
||||||
import "./performance_test.ts";
|
import "./performance_test.ts";
|
||||||
import "./version_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 a new issue