Skip to content

Commit

Permalink
Add Conn.parse_url/1
Browse files Browse the repository at this point in the history
- When a url without a path is parsed add a "/" path.
  - Fixes Azolo#38
- Allow parsing `http` and `https` schemes.
  - This is strictly for user experience, they act just like `ws` and
    `wss`.
  • Loading branch information
Azolo committed Nov 24, 2017
1 parent f3db7dc commit ebc53c7
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 20 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
- Allow `:via` and `:global` tuples for named registration. This includes
handling for `cast/2` and `send_frame/2`.
- Add access to response headers during `handle_connect/2` via `Conn.resp_headers`.
- Add `Conn.parse_url/1` to handle url to URI conversion.
- Automatically add a "/" path to a pathless url.
- The HTTP request will break without a valid path!

### Bug Fixes
- No longer invoke `handle_disconnect` if there is reason to exit from invoking
Expand Down
21 changes: 2 additions & 19 deletions lib/websockex.ex
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ defmodule WebSockex do
Utils.spawn(:no_link, conn, module, state, opts)
end
def start(url, module, state, opts) do
case parse_uri(url) do
case WebSockex.Conn.parse_url(url) do
{:ok, uri} ->
conn = WebSockex.Conn.new(uri, opts)
start(conn, module, state, opts)
Expand All @@ -309,7 +309,7 @@ defmodule WebSockex do
Utils.spawn(:link, conn, module, state, opts)
end
def start_link(url, module, state, opts) do
case parse_uri(url) do
case WebSockex.Conn.parse_url(url) do
{:ok, uri} ->
conn = WebSockex.Conn.new(uri, opts)
start_link(conn, module, state, opts)
Expand Down Expand Up @@ -942,23 +942,6 @@ defmodule WebSockex do
end
end

defp parse_uri(url) do
case URI.parse(url) do
%URI{port: port, scheme: protocol} when protocol in ["ws", "wss"] and is_nil(port) ->
# Someone may have deleted the URI config but I'm going to assume it's
# just that the application didn't get them registered.
{:error, %WebSockex.ApplicationError{reason: :not_started}}
# This is confusing to look at. But it's just a match with multiple guards
%URI{host: host, port: port, scheme: protocol}
when is_nil(host)
when is_nil(port)
when not protocol in ["ws", "wss"] ->
{:error, %WebSockex.URLError{url: url}}
%URI{} = uri ->
{:ok, uri}
end
end

defp purge_timer(ref, msg) do
case Process.cancel_timer(ref) do
i when is_integer(i) -> :ok
Expand Down
25 changes: 24 additions & 1 deletion lib/websockex/conn.ex
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ defmodule WebSockex.Conn do
@type t :: %__MODULE__{conn_mod: :gen_tcp | :ssl,
host: String.t,
port: non_neg_integer,
path: String.t | nil,
path: String.t,
query: String.t | nil,
extra_headers: [header],
transport: transport,
Expand Down Expand Up @@ -86,6 +86,29 @@ defmodule WebSockex.Conn do
socket_recv_timeout: Keyword.get(opts, :socket_recv_timeout, @socket_recv_timeout_default)}
end

@doc """
Parses a url string for a valid URI
"""
@spec parse_url(String.t) :: {:ok, URI.t} | {:error, %WebSockex.URLError{}}
def parse_url(url) do
case URI.parse(url) do
%URI{port: port, scheme: protocol} when protocol in ["ws", "wss"] and is_nil(port) ->
# Someone may have deleted the URI config but I'm going to assume it's
# just that the application didn't get them registered.
{:error, %WebSockex.ApplicationError{reason: :not_started}}
# This is confusing to look at. But it's just a match with multiple guards
%URI{host: host, port: port, scheme: protocol}
when is_nil(host)
when is_nil(port)
when not protocol in ["ws", "wss", "http", "https"] ->
{:error, %WebSockex.URLError{url: url}}
%URI{path: nil} = uri ->
{:ok, %{uri | path: "/"}}
%URI{} = uri ->
{:ok, uri}
end
end

@doc """
Sends data using the `conn_mod` module.
"""
Expand Down
20 changes: 20 additions & 0 deletions test/websockex/conn_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,26 @@ defmodule WebSockex.ConnTest do
socket_recv_timeout: 5000}
end

test "parse_url" do
assert WebSockex.Conn.parse_url("lemon_pie") ==
{:error, %WebSockex.URLError{url: "lemon_pie"}}

ws_url = "ws://localhost/ws"
assert WebSockex.Conn.parse_url(ws_url) == {:ok, URI.parse(ws_url)}

wss_url = "wss://localhost/ws"
assert WebSockex.Conn.parse_url(wss_url) == {:ok, URI.parse(wss_url)}

http_url = "https://localhost/ws"
assert WebSockex.Conn.parse_url(http_url) == {:ok, URI.parse(http_url)}

https_url = "https://localhost/wss"
assert WebSockex.Conn.parse_url(https_url) == {:ok, URI.parse(https_url)}

pathless_url = "ws://localhost"
assert WebSockex.Conn.parse_url(pathless_url) == {:ok, %{URI.parse(pathless_url) | path: "/"}}
end

test "open_socket", context do
%{host: host, port: port, path: path} = context.uri

Expand Down

0 comments on commit ebc53c7

Please sign in to comment.