Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements #67

Merged
merged 1 commit into from
Apr 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .github/workflows/erlang.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@ on:
jobs:

tests:
name: OTP ${{ matrix.otp }}

runs-on: ubuntu-latest
name: OTP ${{ matrix.otp }}

container:
image: erlang:${{ matrix.otp }}

strategy:
matrix:
otp: [20.3, 21.3, 22.2]
otp: ['20.3', '21.3', '22.3', '23.3', '24.0-rc2']

steps:
- uses: actions/checkout@v2

- uses: gleam-lang/[email protected]
with:
otp-version: ${{ matrix.otp }}
- uses: actions/[email protected]

- name: Run tests
run: rebar3 do eunit, ct, dialyzer
Expand Down
28 changes: 15 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

# Bookish spork #

Copyright (c) 2018-2020 Alexey Nikitin
Copyright (c) 2018-2021 Alexey Nikitin

__Version:__ 0.3.6
__Version:__ 0.4.0

__Authors:__ Alexey Nikitin ([`[email protected]`](mailto:[email protected])) (_web site:_ [`https://twitter.com/tank_bohr`](https://twitter.com/tank_bohr)).

Expand Down Expand Up @@ -52,7 +52,7 @@ First step: add to your rebar config
{profiles, [
{test, [
{deps, [
{bookish_spork, "0.3.6"}
{bookish_spork, "0.4.0"}
]}
]}
]}.
Expand Down Expand Up @@ -111,13 +111,15 @@ It returns you an opaque structure of the request. You can inspect it with

#### <a name="Bypass_comparision">Bypass comparision</a> ####

An elixir library [bypass](https://github.com/PSPDFKit-labs/bypass) does pretty much the same. And illustrates the same approach. It starts a cowboy web-server to replace a real service for test
An elixir library [bypass](https://github.com/PSPDFKit-labs/bypass) does pretty much the same. And illustrates the same approach. It starts a cowboy web-server to replace a real service for test. It's a beautiful library with great API, documentation, and very concise source code. If you are an elixir developer, most likely, it will be a good fit for you.

But bookish_spork has some advantages:
But nevertheless bookish_spork has some advantages:

* Bypass depends on `cowboy` and `plug`. Bookish spork has zero dependencies
* Bookish spork works seamlessly with both erlang and elixir. Bypass is supposed to be an elixir only library
* Bookish spork much simpler (I believe)
* Bypass depends on `cowboy` and `plug`. Bookish spork has zero dependencies.
* Bookish spork works seamlessly with both erlang and elixir. Bypass is supposed to be an elixir only library.
* <strike>Bookish spork much simpler (I believe)</strike>
(not any more).
* Bookish spork allows you to inspect the request very deeply and accurate. For example take a look at [`bookish_spork_request:raw_headers/1`](http://github.com/tank-bohr/bookish_spork/blob/master/doc/bookish_spork_request.md#raw_headers-1) and [`bookish_spork_request:ssl_info/1`](http://github.com/tank-bohr/bookish_spork/blob/master/doc/bookish_spork_request.md#ssl_info-1) and [`bookish_spork_request:tls_ext/1`](http://github.com/tank-bohr/bookish_spork/blob/master/doc/bookish_spork_request.md#tls_ext-1). It can be useful for HTTP clients testing.


#### <a name="Elli_comparision">Elli comparision</a> ####
Expand Down Expand Up @@ -227,9 +229,9 @@ defmodule ChuckNorrisApiTest do
use ExUnit.Case
doctest ChuckNorrisApi

setup_all do
{:ok, _} = :bookish_spork.start_server
{:ok, %{}}
setup do
{:ok, _} = :bookish_spork.start_server()
on_exit(fn -> :bookish_spork.stop_server() end)
end

test "retrieves a random joke" do
Expand All @@ -238,8 +240,8 @@ defmodule ChuckNorrisApiTest do
}"])
assert ChuckNorrisApi.random == "Chuck norris tried to crank that soulja boy but it wouldn't crank up"

{:ok, request} = :bookish_spork.capture_request
assert request.uri == '/jokes/random'
{:ok, request} = :bookish_spork.capture_request()
assert request.uri === "/jokes/random"
end
end

Expand Down
28 changes: 15 additions & 13 deletions doc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

# Bookish spork #

Copyright (c) 2018-2020 Alexey Nikitin
Copyright (c) 2018-2021 Alexey Nikitin

__Version:__ 0.3.6
__Version:__ 0.4.0

__Authors:__ Alexey Nikitin ([`[email protected]`](mailto:[email protected])) (_web site:_ [`https://twitter.com/tank_bohr`](https://twitter.com/tank_bohr)).

Expand Down Expand Up @@ -52,7 +52,7 @@ First step: add to your rebar config
{profiles, [
{test, [
{deps, [
{bookish_spork, "0.3.6"}
{bookish_spork, "0.4.0"}
]}
]}
]}.
Expand Down Expand Up @@ -111,13 +111,15 @@ It returns you an opaque structure of the request. You can inspect it with

#### <a name="Bypass_comparision">Bypass comparision</a> ####

An elixir library [bypass](https://github.com/PSPDFKit-labs/bypass) does pretty much the same. And illustrates the same approach. It starts a cowboy web-server to replace a real service for test
An elixir library [bypass](https://github.com/PSPDFKit-labs/bypass) does pretty much the same. And illustrates the same approach. It starts a cowboy web-server to replace a real service for test. It's a beautiful library with great API, documentation, and very concise source code. If you are an elixir developer, most likely, it will be a good fit for you.

But bookish_spork has some advantages:
But nevertheless bookish_spork has some advantages:

* Bypass depends on `cowboy` and `plug`. Bookish spork has zero dependencies
* Bookish spork works seamlessly with both erlang and elixir. Bypass is supposed to be an elixir only library
* Bookish spork much simpler (I believe)
* Bypass depends on `cowboy` and `plug`. Bookish spork has zero dependencies.
* Bookish spork works seamlessly with both erlang and elixir. Bypass is supposed to be an elixir only library.
* <strike>Bookish spork much simpler (I believe)</strike>
(not any more).
* Bookish spork allows you to inspect the request very deeply and accurate. For example take a look at [`bookish_spork_request:raw_headers/1`](bookish_spork_request.md#raw_headers-1) and [`bookish_spork_request:ssl_info/1`](bookish_spork_request.md#ssl_info-1) and [`bookish_spork_request:tls_ext/1`](bookish_spork_request.md#tls_ext-1). It can be useful for HTTP clients testing.


#### <a name="Elli_comparision">Elli comparision</a> ####
Expand Down Expand Up @@ -227,9 +229,9 @@ defmodule ChuckNorrisApiTest do
use ExUnit.Case
doctest ChuckNorrisApi

setup_all do
{:ok, _} = :bookish_spork.start_server
{:ok, %{}}
setup do
{:ok, _} = :bookish_spork.start_server()
on_exit(fn -> :bookish_spork.stop_server() end)
end

test "retrieves a random joke" do
Expand All @@ -238,8 +240,8 @@ defmodule ChuckNorrisApiTest do
}"])
assert ChuckNorrisApi.random == "Chuck norris tried to crank that soulja boy but it wouldn't crank up"

{:ok, request} = :bookish_spork.capture_request
assert request.uri == '/jokes/random'
{:ok, request} = :bookish_spork.capture_request()
assert request.uri === "/jokes/random"
end
end

Expand Down
21 changes: 16 additions & 5 deletions doc/bookish_spork_request.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ __abstract datatype__: `t()`
## Function Index ##


<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#body-1">body/1</a></td><td>request body.</td></tr><tr><td valign="top"><a href="#content_length-1">content_length/1</a></td><td>Content-Length header value as intger.</td></tr><tr><td valign="top"><a href="#from_transport-1">from_transport/1</a></td><td></td></tr><tr><td valign="top"><a href="#header-2">header/2</a></td><td>Returns a particular header from request.</td></tr><tr><td valign="top"><a href="#headers-1">headers/1</a></td><td>http headers map.</td></tr><tr><td valign="top"><a href="#is_keepalive-1">is_keepalive/1</a></td><td>tells you if the request is keepalive or not <a href="https://tools.ietf.org.md/rfc6223" target="_top"><tt>https://tools.ietf.org/html/rfc6223</tt></a></td></tr><tr><td valign="top"><a href="#method-1">method/1</a></td><td>http verb: 'GET', 'POST','PUT', 'DELETE', 'OPTIONS', ...</td></tr><tr><td valign="top"><a href="#transport-1">transport/1</a></td><td></td></tr><tr><td valign="top"><a href="#uri-1">uri/1</a></td><td>path with query string.</td></tr><tr><td valign="top"><a href="#version-1">version/1</a></td><td>http protocol version tuple.</td></tr></table>
<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#body-1">body/1</a></td><td>request body.</td></tr><tr><td valign="top"><a href="#content_length-1">content_length/1</a></td><td>Content-Length header value as intger.</td></tr><tr><td valign="top"><a href="#from_transport-1">from_transport/1</a></td><td></td></tr><tr><td valign="top"><a href="#header-2">header/2</a></td><td>Returns a particular header from request.</td></tr><tr><td valign="top"><a href="#headers-1">headers/1</a></td><td>HTTP headers map.</td></tr><tr><td valign="top"><a href="#is_keepalive-1">is_keepalive/1</a></td><td>tells you if the request is keepalive or not <a href="https://tools.ietf.org.md/rfc6223" target="_top"><tt>https://tools.ietf.org/html/rfc6223</tt></a></td></tr><tr><td valign="top"><a href="#method-1">method/1</a></td><td>http verb in lower case: get, post, put, delete, options, ...</td></tr><tr><td valign="top"><a href="#raw_headers-1">raw_headers/1</a></td><td>HTTP raw headers.</td></tr><tr><td valign="top"><a href="#transport-1">transport/1</a></td><td></td></tr><tr><td valign="top"><a href="#uri-1">uri/1</a></td><td>path with query string.</td></tr><tr><td valign="top"><a href="#version-1">version/1</a></td><td>http protocol version tuple.</td></tr></table>


<a name="functions"></a>
Expand Down Expand Up @@ -65,11 +65,11 @@ from_transport(Transport::<a href="bookish_spork_transport.md#type-t">bookish_sp
### header/2 ###

<pre><code>
header(Request::<a href="#type-t">t()</a>, HeaderName::string()) -&gt; string() | nil
header(Request::<a href="#type-t">t()</a>, HeaderName::string() | binary()) -&gt; binary() | nil
</code></pre>
<br />

Returns a particular header from request. Header name is lowerced
Returns a particular header from request.

<a name="headers-1"></a>

Expand All @@ -80,7 +80,7 @@ headers(Request::<a href="#type-t">t()</a>) -&gt; map()
</code></pre>
<br />

http headers map. Header names are normalized and lowercased
HTTP headers map. Header names are normalized and lowercased

<a name="is_keepalive-1"></a>

Expand All @@ -102,7 +102,18 @@ method(Request::<a href="#type-t">t()</a>) -&gt; atom()
</code></pre>
<br />

http verb: 'GET', 'POST','PUT', 'DELETE', 'OPTIONS', ...
http verb in lower case: get, post, put, delete, options, ...

<a name="raw_headers-1"></a>

### raw_headers/1 ###

<pre><code>
raw_headers(Request::<a href="#type-t">t()</a>) -&gt; <a href="proplists.md#type-proplist">proplists:proplist()</a>
</code></pre>
<br />

HTTP raw headers. Headers order and case are preserved

<a name="transport-1"></a>

Expand Down
22 changes: 12 additions & 10 deletions doc/overview.edoc
Original file line number Diff line number Diff line change
Expand Up @@ -112,17 +112,19 @@ It returns you an opaque structure of the request. You can inspect it with

=== Bypass comparision ===

An elixir library <a target="_blank" href="https://github.com/PSPDFKit-labs/bypass">bypass</a> does pretty much the same. And illustrates the same approach. It starts a cowboy web-server to replace a real service for test
An elixir library <a target="_blank" href="https://github.com/PSPDFKit-labs/bypass">bypass</a> does pretty much the same. And illustrates the same approach. It starts a cowboy web-server to replace a real service for test. It's a beautiful library with great API, documentation, and very concise source code. If you are an elixir developer, most likely, it will be a good fit for you.

But bookish_spork has some advantages:
But nevertheless bookish_spork has some advantages:

<ul>

<li>Bypass depends on `cowboy' and `plug'. Bookish spork has zero dependencies</li>
<li>Bypass depends on `cowboy' and `plug'. Bookish spork has zero dependencies.</li>

<li>Bookish spork works seamlessly with both erlang and elixir. Bypass is supposed to be an elixir only library</li>
<li>Bookish spork works seamlessly with both erlang and elixir. Bypass is supposed to be an elixir only library.</li>

<li>Bookish spork much simpler (I believe)</li>
<li><strike>Bookish spork much simpler (I believe)</strike> (not any more).</li>

<li>Bookish spork allows you to inspect the request very deeply and accurate. For example take a look at {@link bookish_spork_request:raw_headers/1} and {@link bookish_spork_request:ssl_info/1} and {@link bookish_spork_request:tls_ext/1}. It can be useful for HTTP clients testing.</li>

</ul>

Expand Down Expand Up @@ -221,9 +223,9 @@ defmodule ChuckNorrisApiTest do
use ExUnit.Case
doctest ChuckNorrisApi

setup_all do
{:ok, _} = :bookish_spork.start_server
{:ok, %{}}
setup do
{:ok, _} = :bookish_spork.start_server()
on_exit(fn -> :bookish_spork.stop_server() end)
end

test "retrieves a random joke" do
Expand All @@ -232,8 +234,8 @@ defmodule ChuckNorrisApiTest do
}"])
assert ChuckNorrisApi.random == "Chuck norris tried to crank that soulja boy but it wouldn't crank up"

{:ok, request} = :bookish_spork.capture_request
assert request.uri == '/jokes/random'
{:ok, request} = :bookish_spork.capture_request()
assert request.uri === "/jokes/random"
end
end
</pre>
Expand Down
6 changes: 6 additions & 0 deletions elvis.config
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
{elvis_style, function_naming_convention, #{
ignore => [bookish_spork_request],
regex => "^([a-z][a-z0-9]*_?)*$"
}},
{elvis_style, state_record_and_type, #{
ignore => [
bookish_spork_acceptor,
bookish_spork_blocking_queue
]
}}
],
ruleset => erl_files
Expand Down
4 changes: 2 additions & 2 deletions rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
{profiles, [
{test, [
{deps, [
{gun, "1.3.1"}
{gun, "1.3.3"}
]},

{plugins, [
Expand All @@ -33,7 +33,7 @@
]},
{elvis, [
{plugins, [
{rebar3_lint, "0.1.11"}
{rebar3_lint, "0.4.0"}
]}
]}
]}.
Expand Down
8 changes: 7 additions & 1 deletion src/bookish_spork_handler.erl
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ receive_request(#state{transport = Transport, request = RequestIn} = State) ->
{ok, {http_request, Method, {abs_path, Uri}, Version}} ->
RequestOut = bookish_spork_request:request_line(RequestIn, Method, Uri, Version),
?FUNCTION_NAME(State#state{request = RequestOut});
{ok, {http_header, _, Header, _, Value}} ->
{ok, {http_header, _, NormalizedHeader, PreserveCaseHeader, Value}} ->
Header = choose_header(NormalizedHeader, PreserveCaseHeader),
RequestOut = bookish_spork_request:add_header(RequestIn, Header, Value),
?FUNCTION_NAME(State#state{request = RequestOut});
{ok, http_eoh} ->
Expand Down Expand Up @@ -136,6 +137,11 @@ complete_connection(State = #state{transport = Transport, request = Request}) ->
{halt, normal}
end.

choose_header(NormalizedHeader, undefined) ->
NormalizedHeader;
choose_header(_NormalizedHeader, PreserveCaseHeader) ->
PreserveCaseHeader.

reduce_while(State, []) ->
{noreply, State};
reduce_while(State, [Fun|Rest]) ->
Expand Down
Loading