Skip to content

Commit

Permalink
fix(websocket): Fix PermissionDenied error being caught in constructor (
Browse files Browse the repository at this point in the history
  • Loading branch information
crowlKats committed Nov 25, 2020
1 parent fb13967 commit d40b071
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 2 deletions.
33 changes: 31 additions & 2 deletions cli/ops/websocket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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 {
Expand All @@ -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()
Expand Down
4 changes: 4 additions & 0 deletions cli/rt/27_websocket.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@

this.#url = wsURL.href;

core.jsonOpSync("op_ws_check_permission", {
url: this.#url,
});

if (protocols && typeof protocols === "string") {
protocols = [protocols];
}
Expand Down
1 change: 1 addition & 0 deletions cli/tests/unit/unit_tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 9 additions & 0 deletions cli/tests/unit/websocket_test.ts
Original file line number Diff line number Diff line change
@@ -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:https://localhost"),
Deno.errors.PermissionDenied,
);
});

0 comments on commit d40b071

Please sign in to comment.