Skip to content

Commit

Permalink
Support for Base64 encoded websocket payloads
Browse files Browse the repository at this point in the history
  • Loading branch information
essenciary committed Nov 2, 2023
1 parent 45f7ac5 commit 4205201
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 11 deletions.
4 changes: 3 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
name = "Genie"
uuid = "c43c736e-a2d1-11e8-161f-af95117fbd1e"
authors = ["Adrian Salceanu <[email protected]>"]
version = "5.20.1"
version = "5.21.0"

[deps]
ArgParse = "c7e460c6-2fb9-53a9-8c5b-16f535851c63"
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b"
DotEnv = "4dc1fcf4-5e3b-5448-94ab-0c38ec0385c1"
Expand Down Expand Up @@ -37,6 +38,7 @@ YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6"

[compat]
ArgParse = "1"
Base64 = "1.6"
Dates = "1.6"
Distributed = "1.6"
DotEnv = "0.3"
Expand Down
19 changes: 12 additions & 7 deletions assets/js/channels.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,26 +141,31 @@ Genie.WebChannels.processingHandlers.push(event => {

Genie.WebChannels.messageHandlers.push(event => {
try {
event.data = event.data.trim();
let ed = event.data.trim();

if (event.data.startsWith('{') && event.data.endsWith('}')) {
window.parse_payload(JSON.parse(event.data, function (key, value) {
// if payload is marked as base64 encoded, remove the marker and decode
if (ed.startsWith(Genie.Settings.webchannels_base64_marker)) {
ed = atob(ed.substring(Genie.Settings.webchannels_base64_marker.length).trim());
}

if (ed.startsWith('{') && ed.endsWith('}')) {
window.parse_payload(JSON.parse(ed, function (key, value) {
if (value == '__undefined__') {
return undefined;
} else {
return value;
}
}));
} else if (event.data.startsWith(Genie.Settings.webchannels_eval_command)) {
return Function('"use strict";return (' + event.data.substring(Genie.Settings.webchannels_eval_command.length).trim() + ')')();
} else if (event.data == 'Subscription: OK') {
} else if (ed.startsWith(Genie.Settings.webchannels_eval_command)) {
return Function('"use strict";return (' + ed.substring(Genie.Settings.webchannels_eval_command.length).trim() + ')')();
} else if (ed == 'Subscription: OK') {
window.subscription_ready();
} else {
window.process_payload(event);
}
} catch (ex) {
console.error(ex);
console.error(event.data);
console.error(ed);
}
});

Expand Down
4 changes: 4 additions & 0 deletions assets/js/webthreads.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ Genie.WebChannels.messageHandlers.push(function(code, result, headers){
});

function processMessage(message) {
if (message.startsWith(Genie.Settings.webchannels_base64_marker)) {
message = atob(message.substring(Genie.Settings.webchannels_base64_marker.length).trim());
}

if (message.startsWith(Genie.Settings.webchannels_eval_command)) {
return Function('"use strict";return (' + message.substring(Genie.Settings.webchannels_eval_command.length).trim() + ')')();
} else if (message == 'Subscription: OK') {
Expand Down
1 change: 1 addition & 0 deletions src/Assets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ function js_settings(channel::String = Genie.config.webchannels_default_route) :
:webchannels_unsubscribe_channel => Genie.config.webchannels_unsubscribe_channel,
:webchannels_autosubscribe => Genie.config.webchannels_autosubscribe,
:webchannels_eval_command => Genie.config.webchannels_eval_command,
:webchannels_base64_marker => Genie.config.webchannels_base64_marker,
:webchannels_timeout => Genie.config.webchannels_timeout,
:webchannels_keepalive_frequency => Genie.config.webchannels_keepalive_frequency,
:webchannels_server_gone_alert_timeout => Genie.config.webchannels_server_gone_alert_timeout,
Expand Down
1 change: 1 addition & 0 deletions src/Configuration.jl
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ Base.@kwdef mutable struct Settings
webchannels_unsubscribe_channel::String = "unsubscribe"
webchannels_autosubscribe::Bool = true
webchannels_eval_command::String = ">eval:"
webchannels_base64_marker::String = "base64:"
webchannels_timeout::Int = 1_000
webchannels_keepalive_frequency::Int = 30_000 # 30 seconds
webchannels_server_gone_alert_timeout::Int = 10_000 # 10 seconds
Expand Down
4 changes: 2 additions & 2 deletions src/Loader.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ end
Kickstarts the loading of a Genie app by loading the environment settings.
"""
function bootstrap(context::Union{Module,Nothing} = default_context(context)) :: Nothing
function bootstrap(context::Union{Module,Nothing} = default_context(context); show_banner::Bool = true) :: Nothing
ENV_FILE_NAME = "env.jl"
GLOBAL_ENV_FILE_NAME = "global.jl"

Expand All @@ -76,7 +76,7 @@ function bootstrap(context::Union{Module,Nothing} = default_context(context)) ::
Genie.config.app_env = ENV["GENIE_ENV"] # ENV might have changed
importenv()

get!(ENV, "GENIE_BANNER", "true") |> strip |> lowercase != "false" && print_banner()
get!(ENV, "GENIE_BANNER", "true") |> strip |> lowercase != "false" && show_banner && print_banner()

if isfile(Genie.config.env_file)
DotEnv.config(;path=Genie.config.env_file)
Expand Down
18 changes: 17 additions & 1 deletion src/WebChannels.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Handles WebSockets communication logic.
"""
module WebChannels

import HTTP, Distributed, Logging, JSON3, Sockets, Dates
import HTTP, Distributed, Logging, JSON3, Sockets, Dates, Base64
import Genie, Genie.Renderer

const ClientId = UInt # web socket hash
Expand Down Expand Up @@ -290,4 +290,20 @@ function message(client::ChannelClient, msg::String) :: Int
message(client.client, msg)
end


"""
Encodes `msg` in Base64 and tags it with `Genie.config.webchannels_base64_marker`.
"""
function tagbase64encode(msg)
Genie.config.webchannels_base64_marker * Base64.base64encode(msg)
end


"""
Decodes `msg` from Base64 and removes the `Genie.config.webchannels_base64_marker` tag.
"""
function tagbase64decode(msg)
Base64.base64decode(msg[length(Genie.config.webchannels_base64_marker):end])
end

end

2 comments on commit 4205201

@essenciary
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/94635

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v5.21.0 -m "<description of version>" 42052011d9b13b84f3e8daca40d87ec143d7bef3
git push origin v5.21.0

Please sign in to comment.