diff options
author | Hubert Chathi <hubert@uhoreg.ca> | 2020-09-17 22:46:21 -0400 |
---|---|---|
committer | Hubert Chathi <hubert@uhoreg.ca> | 2020-09-17 22:46:21 -0400 |
commit | 810f00a3c44dd5a2b35cb1428ba1a581b0c0acf4 (patch) | |
tree | 7abd29e058d4be9d3a62504d926d59b2bcd8b57e | |
parent | encode filename in URL (diff) |
improve endpoint protocol and HttpSpec
29 files changed, 274 insertions, 352 deletions
diff --git a/lib/polyjuice/client.ex b/lib/polyjuice/client.ex index a39ac08..152735f 100644 --- a/lib/polyjuice/client.ex +++ b/lib/polyjuice/client.ex @@ -266,13 +266,6 @@ defmodule Polyjuice.Client do } end - @doc "The r0 client URL prefix" - def prefix_r0, do: "_matrix/client/r0" - @doc "The unstable client URL prefix" - def prefix_unstable, do: "_matrix/client/unstable" - @doc "The r0 media URL prefix" - def prefix_media_r0, do: "_matrix/media/r0" - defprotocol API do @moduledoc """ Protocol for calling the Matrix client API. @@ -323,19 +316,25 @@ defmodule Polyjuice.Client do %Polyjuice.Client.Endpoint.HttpSpec{ method: method, headers: headers, - url: url, + path: path, + query: query, body: body, auth_required: auth_required, stream_response: stream_response - } = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint, base_url) + } = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint) + + url = + %{ + URI.merge(base_url, path) + | query: if(query, do: URI.encode_query(query)) + } + |> to_string() Logger.debug("calling #{method} #{url}") access_token = if auth_required do GenServer.call(pid, :get_state) |> Map.get(:access_token) - else - nil end if auth_required and access_token == nil do diff --git a/lib/polyjuice/client/endpoint.ex b/lib/polyjuice/client/endpoint.ex index bbd68b1..f41b5ec 100644 --- a/lib/polyjuice/client/endpoint.ex +++ b/lib/polyjuice/client/endpoint.ex @@ -21,7 +21,8 @@ defmodule Polyjuice.Client.Endpoint do - `method` is the HTTP verb - `headers` is a list of the HTTP headers - - `url` is the URL to call + - `path` is the path of the endpoint, relative to the homeserver's base URL + - `query` is an enumerable of `{key, value}` tuples giving the query parameters - `body` is the HTTP body (if any) as a binary, or `{:file, filename}` - `transform` is a function to transform the result (status code, headers, content) to a return value @@ -29,21 +30,94 @@ defmodule Polyjuice.Client.Endpoint do """ @type t :: %__MODULE__{ method: atom, + path: String.t(), headers: [{String.t(), String.t()}], - url: String.t(), + query: Keyword.t(), body: iodata() | {:file, String.t()} | {Enumerable.t(), integer}, auth_required: boolean, stream_response: boolean } - @enforce_keys [:method, :headers, :url] + @enforce_keys [:method, :path, :headers] defstruct [ :method, + :path, :headers, - :url, + :query, body: "", auth_required: true, stream_response: false ] + + @doc "The r0 client URL prefix" + def prefix_r0, do: "_matrix/client/r0" + @doc "The unstable client URL prefix" + def prefix_unstable, do: "_matrix/client/unstable" + @doc "The r0 media URL prefix" + def prefix_media_r0, do: "_matrix/media/r0" + + @doc "Headers for endpoints that accept JSON." + def accept_json, do: [{"Accept", "application/json"}] + @doc "Headers for endpoints that send and accept JSON." + def send_json, + do: [ + {"Accept", "application/json"}, + {"Content-Type", "application/json"} + ] + + @doc """ + Create a `GET` request. + + `prefix` is a prefix for the path. It can be one of `r0` (indicating + `_matrix/client/r0`), `unstable` (indicating `_matrix/client/unstable`), + `media_r0` (indicating `_matrix/media/r0`), or a string giving any other + prefix. + + `opts` is a keyword list giving any of the other parameters for `Polyjuice.Client.Endpoint.HttpSpec.t()`. + + """ + def get(prefix, path, opts \\ []) when is_binary(path) and is_list(opts) do + create(:get, prefix, path, accept_json(), opts) + end + + @doc """ + Create a `POST` request. + + See `get/3`. + """ + def post(prefix, path, opts \\ []) when is_binary(path) and is_list(opts) do + create(:post, prefix, path, send_json(), opts) + end + + @doc """ + Create a `PUT` request. + + See `get/3`. + """ + def put(prefix, path, opts \\ []) when is_binary(path) and is_list(opts) do + create(:put, prefix, path, send_json(), opts) + end + + defp create(method, prefix, path, default_headers, opts) do + prefix = + case prefix do + :r0 -> Polyjuice.Client.Endpoint.HttpSpec.prefix_r0() + :unstable -> Polyjuice.Client.Endpoint.HttpSpec.prefix_unstable() + :media_r0 -> Polyjuice.Client.Endpoint.HttpSpec.prefix_media_r0() + p when is_binary(p) -> String.trim_leading(p, "/") + end + + path = if String.starts_with?(path, "/"), do: [path], else: ["/", path] + + %Polyjuice.Client.Endpoint.HttpSpec{ + method: method, + headers: Keyword.get(opts, :headers, default_headers), + path: IO.iodata_to_binary([prefix, path]), + query: Keyword.get(opts, :query, nil), + body: Keyword.get(opts, :body, ""), + auth_required: Keyword.get(opts, :auth_required, true), + stream_response: Keyword.get(opts, :stream_response, false) + } + end end defprotocol Proto do @@ -54,11 +128,8 @@ defmodule Polyjuice.Client.Endpoint do @doc """ Generate the spec for calling the endpoint via HTTP. """ - @spec http_spec( - endpoint_args :: __MODULE__.t(), - base_url :: URI.t() - ) :: Polyjuice.Client.Endpoint.HttpSpec.t() - def http_spec(endpoint_args, base_url) + @spec http_spec(endpoint_args :: __MODULE__.t()) :: Polyjuice.Client.Endpoint.HttpSpec.t() + def http_spec(endpoint_args) @doc """ Transform the HTTP result into a return value. diff --git a/lib/polyjuice/client/endpoint/get_media_download.ex b/lib/polyjuice/client/endpoint/get_media_download.ex index 2a00e86..7bd9e35 100644 --- a/lib/polyjuice/client/endpoint/get_media_download.ex +++ b/lib/polyjuice/client/endpoint/get_media_download.ex @@ -34,14 +34,11 @@ defmodule Polyjuice.Client.Endpoint.GetMediaDownload do ] defimpl Polyjuice.Client.Endpoint.Proto do - def http_spec( - %{ - url: mxc_url, - allow_remote: allow_remote, - filename: filename - }, - base_url - ) do + def http_spec(%{ + url: mxc_url, + allow_remote: allow_remote, + filename: filename + }) do e = &URI.encode_www_form/1 {server_name, media_id} = @@ -68,24 +65,15 @@ defmodule Polyjuice.Client.Endpoint.GetMediaDownload do filename_part = if is_binary(filename), do: "/" <> e.(filename), else: "" - url = %{ - URI.merge( - base_url, - "#{Polyjuice.Client.prefix_media_r0()}/download/#{e.(server_name)}/#{e.(media_id)}#{ - filename_part - }" - ) - | query: if(allow_remote, do: nil, else: "allow_remote=false") - } - - %Polyjuice.Client.Endpoint.HttpSpec{ - method: :get, + Polyjuice.Client.Endpoint.HttpSpec.get( + :media_r0, + "download/#{e.(server_name)}/#{e.(media_id)}#{filename_part}", + query: if(!allow_remote, do: [allow_remote: "false"]), headers: [ {"Accept", "*/*"} ], - url: to_string(url), stream_response: true - } + ) end def transform_http_result(req, status_code, resp_headers, body) do diff --git a/lib/polyjuice/client/endpoint/get_rooms_messages.ex b/lib/polyjuice/client/endpoint/get_rooms_messages.ex index 542fa62..920be5b 100644 --- a/lib/polyjuice/client/endpoint/get_rooms_messages.ex +++ b/lib/polyjuice/client/endpoint/get_rooms_messages.ex @@ -39,43 +39,29 @@ defmodule Polyjuice.Client.Endpoint.GetRoomsMessages do ] defimpl Polyjuice.Client.Endpoint.Proto do - def http_spec( - req, - base_url - ) do + def http_spec(req) do e = &URI.encode_www_form/1 query = [ [ - {"from", req.from}, + {:from, req.from}, case req.dir do - :forward -> {"dir", "f"} - :backward -> {"dir", "b"} + :forward -> {:dir, "f"} + :backward -> {:dir, "b"} end ], - if(req.to, do: [{"to", req.to}], else: []), - if(req.limit, do: [{"limit", req.limit}], else: []), - if(req.filter, do: [{"filter", Jason.encode!(req.filter)}], else: []) + if(req.to, do: [to: req.to], else: []), + if(req.limit, do: [limit: req.limit], else: []), + if(req.filter, do: [filter: Jason.encode!(req.filter)], else: []) ] |> Enum.concat() - |> URI.encode_query() - url = %{ - URI.merge( - base_url, - "#{Polyjuice.Client.prefix_r0()}/rooms/#{e.(req.room)}/messages" - ) - | query: query - } - - %Polyjuice.Client.Endpoint.HttpSpec{ - method: :get, - headers: [ - {"Accept", "application/json"} - ], - url: to_string(url) - } + Polyjuice.Client.Endpoint.HttpSpec.get( + :r0, + "rooms/#{e.(req.room)}/messages", + query: query + ) end def transform_http_result(req, status_code, resp_headers, body) do diff --git a/lib/polyjuice/client/endpoint/get_rooms_state.ex b/lib/polyjuice/client/endpoint/get_rooms_state.ex index 4d05dd5..f274892 100644 --- a/lib/polyjuice/client/endpoint/get_rooms_state.ex +++ b/lib/polyjuice/client/endpoint/get_rooms_state.ex @@ -35,34 +35,21 @@ defmodule Polyjuice.Client.Endpoint.GetRoomsState do ] defimpl Polyjuice.Client.Endpoint.Proto do - def http_spec( - %Polyjuice.Client.Endpoint.GetRoomsState{ - room: room, - event_type: event_type, - state_key: state_key - }, - base_url - ) do + def http_spec(%Polyjuice.Client.Endpoint.GetRoomsState{ + room: room, + event_type: event_type, + state_key: state_key + }) do e = &URI.encode_www_form/1 path = if event_type == nil do - "#{Polyjuice.Client.prefix_r0()}/rooms/#{e.(room)}/state" + "rooms/#{e.(room)}/state" else - "#{Polyjuice.Client.prefix_r0()}/rooms/#{e.(room)}/state/#{e.(event_type)}/#{ - e.(state_key) - }" + "rooms/#{e.(room)}/state/#{e.(event_type)}/#{e.(state_key)}" end - url = URI.merge(base_url, path) - - %Polyjuice.Client.Endpoint.HttpSpec{ - method: :get, - headers: [ - {"Accept", "application/json"} - ], - url: to_string(url) - } + Polyjuice.Client.Endpoint.HttpSpec.get(:r0, path) end def transform_http_result(req, status_code, resp_headers, body) do diff --git a/lib/polyjuice/client/endpoint/get_sync.ex b/lib/polyjuice/client/endpoint/get_sync.ex index 42477a6..9f64234 100644 --- a/lib/polyjuice/client/endpoint/get_sync.ex +++ b/lib/polyjuice/client/endpoint/get_sync.ex @@ -36,52 +36,32 @@ defmodule Polyjuice.Client.Endpoint.GetSync do ] defimpl Polyjuice.Client.Endpoint.Proto do - def http_spec( - %Polyjuice.Client.Endpoint.GetSync{ - filter: filter, - since: since, - full_state: full_state, - set_presence: set_presence, - timeout: timeout - }, - base_url - ) do + def http_spec(%Polyjuice.Client.Endpoint.GetSync{ + filter: filter, + since: since, + full_state: full_state, + set_presence: set_presence, + timeout: timeout + }) do query = [ - [ - {"timeout", timeout} - ], - if(since, do: [{"since", since}], else: []), - if(full_state, do: [{"full_state", "true"}], else: []), + [timeout: timeout], + if(since, do: [since: since], else: []), + if(full_state, do: [full_state: "true"], else: []), case filter do - %{} -> [{"filter", Jason.encode!(filter)}] + %{} -> [filter: Jason.encode!(filter)] nil -> [] - _ -> [{"filter", filter}] + _ -> [filter: filter] end, case set_presence do - :offline -> [{"set_presence", "offline"}] - :unavailable -> [{"set_presence", "unavailable"}] + :offline -> [set_presence: "offline"] + :unavailable -> [set_presence: "unavailable"] :online -> [] end ] |> Enum.concat() - |> URI.encode_query() - url = %{ - URI.merge( - base_url, - "#{Polyjuice.Client.prefix_r0()}/sync" - ) - | query: query - } - - %Polyjuice.Client.Endpoint.HttpSpec{ - method: :get, - headers: [ - {"Accept", "application/json"} - ], - url: to_string(url) - } + Polyjuice.Client.Endpoint.HttpSpec.get(:r0, "sync", query: query) end def transform_http_result(req, status_code, resp_headers, body) do diff --git a/lib/polyjuice/client/endpoint/post_join.ex b/lib/polyjuice/client/endpoint/post_join.ex index 1ddc922..c22a074 100644 --- a/lib/polyjuice/client/endpoint/post_join.ex +++ b/lib/polyjuice/client/endpoint/post_join.ex @@ -33,14 +33,11 @@ defmodule Polyjuice.Client.Endpoint.PostJoin do ] defimpl Polyjuice.Client.Endpoint.Proto do - def http_spec( - %{ - room: room, - servers: servers, - third_party_signed: third_party_signed - }, - base_url - ) do + def http_spec(%{ + room: room, + servers: servers, + third_party_signed: third_party_signed + }) do e = &URI.encode_www_form/1 body = @@ -52,28 +49,19 @@ defmodule Polyjuice.Client.Endpoint.PostJoin do end ) - url = %{ - URI.merge( - base_url, - "#{Polyjuice.Client.prefix_r0()}/join/#{e.(room)}" - ) - | query: - if servers == [] do - nil - else - servers |> Enum.map(&{"server_name", &1}) |> URI.encode_query() - end - } + query = + if servers == [] do + nil + else + servers |> Enum.map(&{:server_name, &1}) + end - %Polyjuice.Client.Endpoint.HttpSpec{ - method: :post, - headers: [ - {"Accept", "application/json"}, - {"Content-Type", "application/json"} - ], - url: to_string(url), + Polyjuice.Client.Endpoint.HttpSpec.post( + :r0, + "join/#{e.(room)}", + query: query, body: body - } + ) end def transform_http_result(req, status_code, resp_headers, body) do diff --git a/lib/polyjuice/client/endpoint/post_login.ex b/lib/polyjuice/client/endpoint/post_login.ex index 808708a..c300d3f 100644 --- a/lib/polyjuice/client/endpoint/post_login.ex +++ b/lib/polyjuice/client/endpoint/post_login.ex @@ -40,17 +40,14 @@ defmodule Polyjuice.Client.Endpoint.PostLogin do ] defimpl Polyjuice.Client.Endpoint.Proto do - def http_spec( - %Polyjuice.Client.Endpoint.PostLogin{ - type: type, - identifier: identifier, - password: password, - token: token, - device_id: device_id, - initial_device_display_name: initial_device_display_name - }, - base_url - ) do + def http_spec(%Polyjuice.Client.Endpoint.PostLogin{ + type: type, + identifier: identifier, + password: password, + token: token, + device_id: device_id, + initial_device_display_name: initial_device_display_name + }) do body = [ [{"type", type}, {"identifier", identifier}], @@ -66,21 +63,12 @@ defmodule Polyjuice.Client.Endpoint.PostLogin do |> Map.new() |> Jason.encode_to_iodata!() - %Polyjuice.Client.Endpoint.HttpSpec{ - method: :post, - headers: [ - {"Accept", "application/json"}, - {"Content-Type", "application/json"} - ], - url: - URI.merge( - base_url, - "#{Polyjuice.Client.prefix_r0()}/login" - ) - |> to_string(), + Polyjuice.Client.Endpoint.HttpSpec.post( + :r0, + "login", body: body, auth_required: false - } + ) end def transform_http_result(req, status_code, resp_headers, body) do diff --git a/lib/polyjuice/client/endpoint/post_logout.ex b/lib/polyjuice/client/endpoint/post_logout.ex index f16889c..95ecafe 100644 --- a/lib/polyjuice/client/endpoint/post_logout.ex +++ b/lib/polyjuice/client/endpoint/post_logout.ex @@ -24,24 +24,12 @@ defmodule Polyjuice.Client.Endpoint.PostLogout do defstruct [] defimpl Polyjuice.Client.Endpoint.Proto do - def http_spec( - %Polyjuice.Client.Endpoint.PostLogout{}, - base_url - ) do - %Polyjuice.Client.Endpoint.HttpSpec{ - method: :post, - headers: [ - {"Accept", "application/json"}, - {"Content-Type", "application/json"} - ], - url: - URI.merge( - base_url, - "#{Polyjuice.Client.prefix_r0()}/logout" - ) - |> to_string(), + def http_spec(_) do + Polyjuice.Client.Endpoint.HttpSpec.post( + :r0, + "logout", body: "{}" - } + ) end def transform_http_result(req, status_code, resp_headers, body) do diff --git a/lib/polyjuice/client/endpoint/post_media_upload.ex b/lib/polyjuice/client/endpoint/post_media_upload.ex index 27fca1a..b1e7238 100644 --- a/lib/polyjuice/client/endpoint/post_media_upload.ex +++ b/lib/polyjuice/client/endpoint/post_media_upload.ex @@ -33,33 +33,21 @@ defmodule Polyjuice.Client.Endpoint.PostMediaUpload do ] defimpl Polyjuice.Client.Endpoint.Proto do - def http_spec( - %{ - filename: filename, - data: data, - mimetype: mimetype - }, - base_url - ) do - e = &URI.encode_www_form/1 - - url = %{ - URI.merge( - base_url, - "#{Polyjuice.Client.prefix_media_r0()}/upload" - ) - | query: "filename=#{e.(filename)}" - } - - %Polyjuice.Client.Endpoint.HttpSpec{ - method: :post, + def http_spec(%{ + filename: filename, + data: data, + mimetype: mimetype + }) do + Polyjuice.Client.Endpoint.HttpSpec.post( + :media_r0, + "upload", headers: [ {"Accept", "application/json"}, {"Content-Type", mimetype} ], - url: to_string(url), + query: [filename: filename], body: data - } + ) end def transform_http_result(req, status_code, resp_headers, body) do diff --git a/lib/polyjuice/client/endpoint/post_rooms_receipt.ex b/lib/polyjuice/client/endpoint/post_rooms_receipt.ex index 9b83891..9ac66d1 100644 --- a/lib/polyjuice/client/endpoint/post_rooms_receipt.ex +++ b/lib/polyjuice/client/endpoint/post_rooms_receipt.ex @@ -34,32 +34,18 @@ defmodule Polyjuice.Client.Endpoint.PostRoomsReceipt do ] defimpl Polyjuice.Client.Endpoint.Proto do - def http_spec( - %Polyjuice.Client.Endpoint.PostRoomsReceipt{ - room: room, - event_id: event_id, - receipt_type: receipt_type - }, - base_url - ) do + def http_spec(%Polyjuice.Client.Endpoint.PostRoomsReceipt{ + room: room, + event_id: event_id, + receipt_type: receipt_type + }) do e = &URI.encode_www_form/1 - %Polyjuice.Client.Endpoint.HttpSpec{ - method: :post, - headers: [ - {"Accept", "application/json"}, - {"Content-Type", "application/json"} - ], - url: - URI.merge( - base_url, - "#{Polyjuice.Client.prefix_r0()}/rooms/#{e.(room)}/receipt/#{e.(receipt_type)}/#{ - e.(event_id) - }" - ) - |> to_string(), + Polyjuice.Client.Endpoint.HttpSpec.post( + :r0, + "rooms/#{e.(room)}/receipt/#{e.(receipt_type)}/#{e.(event_id)}", body: "{}" - } + ) end def transform_http_result(req, status_code, resp_headers, body) do diff --git a/lib/polyjuice/client/endpoint/post_user_filter.ex b/lib/polyjuice/client/endpoint/post_user_filter.ex index 22605aa..dea95ec 100644 --- a/lib/polyjuice/client/endpoint/post_user_filter.ex +++ b/lib/polyjuice/client/endpoint/post_user_filter.ex @@ -31,30 +31,18 @@ defmodule Polyjuice.Client.Endpoint.PostUserFilter do ] defimpl Polyjuice.Client.Endpoint.Proto do - def http_spec( - %{ - user_id: user_id, - filter: filter - }, - base_url - ) do + def http_spec(%{ + user_id: user_id, + filter: filter + }) do e = &URI.encode_www_form/1 body = Jason.encode_to_iodata!(filter) - %Polyjuice.Client.Endpoint.HttpSpec{ - method: :post, - headers: [ - {"Accept", "application/json"}, - {"Content-Type", "application/json"} - ], - url: - URI.merge( - base_url, - "#{Polyjuice.Client.prefix_r0()}/user/#{e.(user_id)}/filter" - ) - |> to_string(), + Polyjuice.Client.Endpoint.HttpSpec.post( + :r0, + "user/#{e.(user_id)}/filter", body: body - } + ) end def transform_http_result(req, status_code, resp_headers, body) do diff --git a/lib/polyjuice/client/endpoint/put_rooms_send.ex b/lib/polyjuice/client/endpoint/put_rooms_send.ex index 1bb2ee8..5b5920b 100644 --- a/lib/polyjuice/client/endpoint/put_rooms_send.ex +++ b/lib/polyjuice/client/endpoint/put_rooms_send.ex @@ -35,34 +35,20 @@ defmodule Polyjuice.Client.Endpoint.PutRoomsSend do ] defimpl Polyjuice.Client.Endpoint.Proto do - def http_spec( - %Polyjuice.Client.Endpoint.PutRoomsSend{ - room: room, - event_type: event_type, - message: message, - txn_id: txn_id - }, - base_url - ) do + def http_spec(%Polyjuice.Client.Endpoint.PutRoomsSend{ + room: room, + event_type: event_type, + message: message, + txn_id: txn_id + }) do e = &URI.encode_www_form/1 body = Jason.encode_to_iodata!(message) - %Polyjuice.Client.Endpoint.HttpSpec{ - method: :put, - headers: [ - {"Accept", "application/json"}, - {"Content-Type", "application/json"} - ], - url: - URI.merge( - base_url, - "#{Polyjuice.Client.prefix_r0()}/rooms/#{e.(room)}/send/#{e.(event_type)}/#{ - e.(txn_id) - }" - ) - |> to_string(), + Polyjuice.Client.Endpoint.HttpSpec.put( + :r0, + "rooms/#{e.(room)}/send/#{e.(event_type)}/#{e.(txn_id)}", body: body - } + ) end def transform_http_result(req, status_code, resp_headers, body) do diff --git a/lib/polyjuice/client/endpoint/put_rooms_state.ex b/lib/polyjuice/client/endpoint/put_rooms_state.ex index ca87c42..9440ee7 100644 --- a/lib/polyjuice/client/endpoint/put_rooms_state.ex +++ b/lib/polyjuice/client/endpoint/put_rooms_state.ex @@ -35,34 +35,20 @@ defmodule Polyjuice.Client.Endpoint.PutRoomsState do ] defimpl Polyjuice.Client.Endpoint.Proto do - def http_spec( - %Polyjuice.Client.Endpoint.PutRoomsState{ - room: room, - event_type: event_type, - state_key: state_key, - content: content - }, - base_url - ) do + def http_spec(%Polyjuice.Client.Endpoint.PutRoomsState{ + room: room, + event_type: event_type, + state_key: state_key, + content: content + }) do e = &URI.encode_www_form/1 body = Jason.encode_to_iodata!(content) - %Polyjuice.Client.Endpoint.HttpSpec{ - method: :put, - headers: [ - {"Accept", "application/json"}, - {"Content-Type", "application/json"} - ], - url: - URI.merge( - base_url, - "#{Polyjuice.Client.prefix_r0()}/rooms/#{e.(room)}/state/#{e.(event_type)}/#{ - e.(state_key) - }" - ) - |> to_string(), + Polyjuice.Client.Endpoint.HttpSpec.put( + :r0, + "rooms/#{e.(room)}/state/#{e.(event_type)}/#{e.(state_key)}", body: body - } + ) end def transform_http_result(req, status_code, resp_headers, body) do diff --git a/lib/polyjuice/client/low_level.ex b/lib/polyjuice/client/low_level.ex index f41cf8c..6e0b656 100644 --- a/lib/polyjuice/client/low_level.ex +++ b/lib/polyjuice/client/low_level.ex @@ -55,11 +55,19 @@ defmodule Polyjuice.Client.LowLevel do %Polyjuice.Client.Endpoint.HttpSpec{ method: method, headers: headers, - url: url, + path: path, + query: query, body: body, auth_required: auth_required, stream_response: stream_response - } = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint, base_url) + } = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint) + + url = + %{ + URI.merge(base_url, path) + | query: if(query, do: URI.encode_query(query)) + } + |> to_string() Logger.debug("calling #{method} #{url}") diff --git a/lib/polyjuice/client/sync.ex b/lib/polyjuice/client/sync.ex index 573af71..752cada 100644 --- a/lib/polyjuice/client/sync.ex +++ b/lib/polyjuice/client/sync.ex @@ -146,7 +146,7 @@ defmodule Polyjuice.Client.Sync do path = URI.merge( state.homeserver_url, - "#{Polyjuice.Client.prefix_r0()}/user/#{e.(user_id)}/filter" + "#{Polyjuice.Client.Endpoint.HttpSpec.prefix_r0()}/user/#{e.(user_id)}/filter" ).path headers = [ diff --git a/test/polyjuice/client/endpoint/get_rooms_messages_test.exs b/test/polyjuice/client/endpoint/get_rooms_messages_test.exs index 6d2002c..f1d8787 100644 --- a/test/polyjuice/client/endpoint/get_rooms_messages_test.exs +++ b/test/polyjuice/client/endpoint/get_rooms_messages_test.exs @@ -21,7 +21,7 @@ defmodule Polyjuice.Client.Endpoint.GetRoomsMessagesTest do from: "token", dir: :forward } do - http_spec = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint, "https://example.com") + http_spec = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint) assert http_spec == %Polyjuice.Client.Endpoint.HttpSpec{ auth_required: true, @@ -30,8 +30,8 @@ defmodule Polyjuice.Client.Endpoint.GetRoomsMessagesTest do {"Accept", "application/json"} ], method: :get, - url: - "https://example.com/_matrix/client/r0/rooms/%21roomid/messages?from=token&dir=f" + path: "_matrix/client/r0/rooms/%21roomid/messages", + query: [from: "token", dir: "f"] } assert Polyjuice.Client.Endpoint.Proto.transform_http_result( @@ -59,7 +59,7 @@ defmodule Polyjuice.Client.Endpoint.GetRoomsMessagesTest do limit: 20, filter: %{} } do - http_spec = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint, "https://example.com") + http_spec = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint) assert http_spec == %Polyjuice.Client.Endpoint.HttpSpec{ auth_required: true, @@ -68,8 +68,8 @@ defmodule Polyjuice.Client.Endpoint.GetRoomsMessagesTest do {"Accept", "application/json"} ], method: :get, - url: - "https://example.com/_matrix/client/r0/rooms/%21roomid/messages?from=token&dir=b&to=endtoken&limit=20&filter=%7B%7D" + path: "_matrix/client/r0/rooms/%21roomid/messages", + query: [from: "token", dir: "b", to: "endtoken", limit: 20, filter: "{}"] } end end diff --git a/test/polyjuice/client/endpoint/get_rooms_state_test.exs b/test/polyjuice/client/endpoint/get_rooms_state_test.exs index ec7911f..3c59b80 100644 --- a/test/polyjuice/client/endpoint/get_rooms_state_test.exs +++ b/test/polyjuice/client/endpoint/get_rooms_state_test.exs @@ -22,7 +22,7 @@ defmodule Polyjuice.Client.Endpoint.GetRoomsStateTest do state_key: "" } - http_spec = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint, "https://example.com") + http_spec = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint) assert http_spec == %Polyjuice.Client.Endpoint.HttpSpec{ auth_required: true, @@ -31,7 +31,7 @@ defmodule Polyjuice.Client.Endpoint.GetRoomsStateTest do {"Accept", "application/json"} ], method: :get, - url: "https://example.com/_matrix/client/r0/rooms/%21room_id/state" + path: "_matrix/client/r0/rooms/%21room_id/state" } assert Polyjuice.Client.Endpoint.Proto.transform_http_result( @@ -57,7 +57,7 @@ defmodule Polyjuice.Client.Endpoint.GetRoomsStateTest do state_key: "" } - http_spec = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint, "https://example.com") + http_spec = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint) assert http_spec == %Polyjuice.Client.Endpoint.HttpSpec{ auth_required: true, @@ -66,7 +66,7 @@ defmodule Polyjuice.Client.Endpoint.GetRoomsStateTest do {"Accept", "application/json"} ], method: :get, - url: "https://example.com/_matrix/client/r0/rooms/%21room_id/state/m.room.name/" + path: "_matrix/client/r0/rooms/%21room_id/state/m.room.name/" } assert Polyjuice.Client.Endpoint.Proto.transform_http_result( diff --git a/test/polyjuice/client/endpoint/get_sync_test.exs b/test/polyjuice/client/endpoint/get_sync_test.exs index ae03aed..02aa580 100644 --- a/test/polyjuice/client/endpoint/get_sync_test.exs +++ b/test/polyjuice/client/endpoint/get_sync_test.exs @@ -17,7 +17,7 @@ defmodule Polyjuice.Client.Endpoint.GetSyncTest do test "GET sync" do with endpoint = %Polyjuice.Client.Endpoint.GetSync{} do - http_spec = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint, "https://example.com") + http_spec = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint) assert http_spec == %Polyjuice.Client.Endpoint.HttpSpec{ auth_required: true, @@ -26,7 +26,8 @@ defmodule Polyjuice.Client.Endpoint.GetSyncTest do {"Accept", "application/json"} ], method: :get, - url: "https://example.com/_matrix/client/r0/sync?timeout=0" + path: "_matrix/client/r0/sync", + query: [timeout: 0] } assert Polyjuice.Client.Endpoint.Proto.transform_http_result( @@ -53,7 +54,7 @@ defmodule Polyjuice.Client.Endpoint.GetSyncTest do set_presence: :offline, timeout: 120 } do - http_spec = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint, "https://example.com") + http_spec = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint) assert http_spec == %Polyjuice.Client.Endpoint.HttpSpec{ auth_required: true, @@ -62,8 +63,14 @@ defmodule Polyjuice.Client.Endpoint.GetSyncTest do {"Accept", "application/json"} ], method: :get, - url: - "https://example.com/_matrix/client/r0/sync?timeout=120&since=token&full_state=true&filter=1&set_presence=offline" + path: "_matrix/client/r0/sync", + query: [ + timeout: 120, + since: "token", + full_state: "true", + filter: "1", + set_presence: "offline" + ] } end @@ -71,7 +78,7 @@ defmodule Polyjuice.Client.Endpoint.GetSyncTest do filter: %{}, set_presence: :unavailable } do - http_spec = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint, "https://example.com") + http_spec = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint) assert http_spec == %Polyjuice.Client.Endpoint.HttpSpec{ auth_required: true, @@ -80,8 +87,8 @@ defmodule Polyjuice.Client.Endpoint.GetSyncTest do {"Accept", "application/json"} ], method: :get, - url: - "https://example.com/_matrix/client/r0/sync?timeout=0&filter=%7B%7D&set_presence=unavailable" + path: "_matrix/client/r0/sync", + query: [timeout: 0, filter: "{}", set_presence: "unavailable"] } end end diff --git a/test/polyjuice/client/endpoint/post_join_test.exs b/test/polyjuice/client/endpoint/post_join_test.exs index fef86b1..9f21c52 100644 --- a/test/polyjuice/client/endpoint/post_join_test.exs +++ b/test/polyjuice/client/endpoint/post_join_test.exs @@ -29,7 +29,7 @@ defmodule Polyjuice.Client.Endpoint.PostJoinTest do } } } do - http_spec = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint, "https://example.com") + http_spec = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint) assert %{http_spec | body: nil} == %Polyjuice.Client.Endpoint.HttpSpec{ auth_required: true, @@ -39,7 +39,7 @@ defmodule Polyjuice.Client.Endpoint.PostJoinTest do {"Content-Type", "application/json"} ], method: :post, - url: "https://example.com/_matrix/client/r0/join/%21room" + path: "_matrix/client/r0/join/%21room" } assert Jason.decode!(http_spec.body) == %{ @@ -76,7 +76,7 @@ defmodule Polyjuice.Client.Endpoint.PostJoinTest do room: "!room", servers: ["example.com", "example.org"] } do - http_spec = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint, "https://example.com") + http_spec = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint) assert http_spec == %Polyjuice.Client.Endpoint.HttpSpec{ auth_required: true, @@ -86,8 +86,8 @@ defmodule Polyjuice.Client.Endpoint.PostJoinTest do {"Content-Type", "application/json"} ], method: :post, - url: - "https://example.com/_matrix/client/r0/join/%21room?server_name=example.com&server_name=example.org" + path: "_matrix/client/r0/join/%21room", + query: [server_name: "example.com", server_name: "example.org"] } assert Polyjuice.Client.Endpoint.Proto.transform_http_result( diff --git a/test/polyjuice/client/endpoint/post_login_test.exs b/test/polyjuice/client/endpoint/post_login_test.exs index 6bf7781..4a2fa96 100644 --- a/test/polyjuice/client/endpoint/post_login_test.exs +++ b/test/polyjuice/client/endpoint/post_login_test.exs @@ -25,7 +25,7 @@ defmodule Polyjuice.Client.Endpoint.PostLoginTest do password: "12345" } - http_spec = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint, "https://example.com") + http_spec = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint) assert %{http_spec | body: nil} == %Polyjuice.Client.Endpoint.HttpSpec{ auth_required: false, @@ -35,7 +35,7 @@ defmodule Polyjuice.Client.Endpoint.PostLoginTest do {"Content-Type", "application/json"} ], method: :post, - url: "https://example.com/_matrix/client/r0/login" + path: "_matrix/client/r0/login" } assert Jason.decode!(http_spec.body) == %{ diff --git a/test/polyjuice/client/endpoint/post_logout_test.exs b/test/polyjuice/client/endpoint/post_logout_test.exs index 9dde596..07c8211 100644 --- a/test/polyjuice/client/endpoint/post_logout_test.exs +++ b/test/polyjuice/client/endpoint/post_logout_test.exs @@ -18,7 +18,7 @@ defmodule Polyjuice.Client.Endpoint.PostLogoutTest do test "POST logout" do endpoint = %Polyjuice.Client.Endpoint.PostLogout{} - http_spec = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint, "https://example.com") + http_spec = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint) assert http_spec == %Polyjuice.Client.Endpoint.HttpSpec{ auth_required: true, @@ -28,7 +28,7 @@ defmodule Polyjuice.Client.Endpoint.PostLogoutTest do {"Content-Type", "application/json"} ], method: :post, - url: "https://example.com/_matrix/client/r0/logout" + path: "_matrix/client/r0/logout" } assert Polyjuice.Client.Endpoint.Proto.transform_http_result( diff --git a/test/polyjuice/client/endpoint/post_rooms_receipt_test.exs b/test/polyjuice/client/endpoint/post_rooms_receipt_test.exs index 39a7453..fdb9490 100644 --- a/test/polyjuice/client/endpoint/post_rooms_receipt_test.exs +++ b/test/polyjuice/client/endpoint/post_rooms_receipt_test.exs @@ -21,7 +21,7 @@ defmodule Polyjuice.Client.Endpoint.PostRoomsReceiptTest do event_id: "$event_id" } - http_spec = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint, "https://example.com") + http_spec = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint) assert http_spec == %Polyjuice.Client.Endpoint.HttpSpec{ auth_required: true, @@ -31,8 +31,7 @@ defmodule Polyjuice.Client.Endpoint.PostRoomsReceiptTest do {"Content-Type", "application/json"} ], method: :post, - url: - "https://example.com/_matrix/client/r0/rooms/%21room_id/receipt/m.read/%24event_id" + path: "_matrix/client/r0/rooms/%21room_id/receipt/m.read/%24event_id" } assert Polyjuice.Client.Endpoint.Proto.transform_http_result( diff --git a/test/polyjuice/client/endpoint/post_user_filter_test.exs b/test/polyjuice/client/endpoint/post_user_filter_test.exs index 947474c..947aa1e 100644 --- a/test/polyjuice/client/endpoint/post_user_filter_test.exs +++ b/test/polyjuice/client/endpoint/post_user_filter_test.exs @@ -25,7 +25,7 @@ defmodule Polyjuice.Client.Endpoint.PostUserfilterTest do } } - http_spec = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint, "https://example.com") + http_spec = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint) assert TestUtil.http_spec_body_to_binary(http_spec) == %Polyjuice.Client.Endpoint.HttpSpec{ auth_required: true, @@ -35,7 +35,7 @@ defmodule Polyjuice.Client.Endpoint.PostUserfilterTest do {"Content-Type", "application/json"} ], method: :post, - url: "https://example.com/_matrix/client/r0/user/%40alice%3Aexample.com/filter" + path: "_matrix/client/r0/user/%40alice%3Aexample.com/filter" } assert Polyjuice.Client.Endpoint.Proto.transform_http_result( diff --git a/test/polyjuice/client/endpoint/put_rooms_send_test.exs b/test/polyjuice/client/endpoint/put_rooms_send_test.exs index eeee870..db4a4bc 100644 --- a/test/polyjuice/client/endpoint/put_rooms_send_test.exs +++ b/test/polyjuice/client/endpoint/put_rooms_send_test.exs @@ -25,7 +25,7 @@ defmodule Polyjuice.Client.Endpoint.PutRoomsSendTest do } } - http_spec = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint, "https://example.com") + http_spec = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint) assert TestUtil.http_spec_body_to_binary(http_spec) == %Polyjuice.Client.Endpoint.HttpSpec{ auth_required: true, @@ -35,8 +35,7 @@ defmodule Polyjuice.Client.Endpoint.PutRoomsSendTest do {"Content-Type", "application/json"} ], method: :put, - url: - "https://example.com/_matrix/client/r0/rooms/%21room_id/send/m.room.message/txn_id" + path: "_matrix/client/r0/rooms/%21room_id/send/m.room.message/txn_id" } assert Polyjuice.Client.Endpoint.Proto.transform_http_result( diff --git a/test/polyjuice/client/endpoint/put_rooms_state_test.exs b/test/polyjuice/client/endpoint/put_rooms_state_test.exs index 690c885..cb745e3 100644 --- a/test/polyjuice/client/endpoint/put_rooms_state_test.exs +++ b/test/polyjuice/client/endpoint/put_rooms_state_test.exs @@ -25,7 +25,7 @@ defmodule Polyjuice.Client.Endpoint.PutRoomsStateTest do } } - http_spec = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint, "https://example.com") + http_spec = Polyjuice.Client.Endpoint.Proto.http_spec(endpoint) assert TestUtil.http_spec_body_to_binary(http_spec) == %Polyjuice.Client.Endpoint.HttpSpec{ auth_required: true, @@ -35,7 +35,7 @@ defmodule Polyjuice.Client.Endpoint.PutRoomsStateTest do {"Content-Type", "application/json"} ], method: :put, - url: "https://example.com/_matrix/client/r0/rooms/%21room_id/state/m.room.name/" + path: "_matrix/client/r0/rooms/%21room_id/state/m.room.name/" } assert Polyjuice.Client.Endpoint.Proto.transform_http_result( diff --git a/test/polyjuice/client/low_level_test.exs b/test/polyjuice/client/low_level_test.exs index cab80c2..7840e83 100644 --- a/test/polyjuice/client/low_level_test.exs +++ b/test/polyjuice/client/low_level_test.exs @@ -60,7 +60,7 @@ defmodule Polyjuice.Client.LowLevelTest do %DummyEndpoint{ http_spec: %Polyjuice.Client.Endpoint.HttpSpec{ method: :put, - url: "foo", + path: "foo", headers: [], body: "foobar", auth_required: false @@ -74,7 +74,7 @@ defmodule Polyjuice.Client.LowLevelTest do %DummyEndpoint{ http_spec: %Polyjuice.Client.Endpoint.HttpSpec{ method: :put, - url: "foo", + path: "foo", headers: [], body: [?f, ["oo"], ["b", [?a | "r"]]], auth_required: false diff --git a/test/polyjuice/client_test.exs b/test/polyjuice/client_test.exs index 96dc829..c516096 100644 --- a/test/polyjuice/client_test.exs +++ b/test/polyjuice/client_test.exs @@ -167,7 +167,7 @@ defmodule Polyjuice.ClientTest do %DummyEndpoint{ http_spec: %Polyjuice.Client.Endpoint.HttpSpec{ method: :put, - url: "foo", + path: "foo", headers: [], body: "foobar", auth_required: false @@ -181,7 +181,7 @@ defmodule Polyjuice.ClientTest do %DummyEndpoint{ http_spec: %Polyjuice.Client.Endpoint.HttpSpec{ method: :put, - url: "foo", + path: "foo", headers: [], body: [?f, ["oo"], ["b", [?a | "r"]]], auth_required: false diff --git a/test/support/dummy_endpoint.ex b/test/support/dummy_endpoint.ex index 9b0ea32..7986c60 100644 --- a/test/support/dummy_endpoint.ex +++ b/test/support/dummy_endpoint.ex @@ -19,8 +19,8 @@ defmodule DummyEndpoint do ] defimpl Polyjuice.Client.Endpoint.Proto do - def http_spec(%{http_spec: http_spec}, base_url) do - %{http_spec | url: URI.merge(base_url, http_spec.url) |> to_string()} + def http_spec(%{http_spec: http_spec}) do + http_spec end def transform_http_result(req, status_code, resp_headers, body) do |