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

Add simple http client #1123

Merged
merged 2 commits into from
Jun 7, 2024
Merged

Add simple http client #1123

merged 2 commits into from
Jun 7, 2024

Conversation

bettio
Copy link
Collaborator

@bettio bettio commented Mar 31, 2024

Add simple http client inspired to mint.

This kind of API works well with memory constrained devices, since it allows to handle chunks and connection events one by one.

TODO after this PR:

  • Rework default headers handling, such as Host and Content-Lenght
  • Handle chuncked body with delimiters

These changes are made under both the "Apache 2.0" and the "GNU Lesser General
Public License 2.1 or later" license terms (dual license).

SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later

@bettio bettio changed the base branch from main to release-0.6 March 31, 2024 13:56
@bettio bettio force-pushed the http-client branch 3 times, most recently from 0bb3026 to 6f6bdf3 Compare May 7, 2024 22:24
Copy link
Collaborator

@UncleGrumpy UncleGrumpy left a comment

Choose a reason for hiding this comment

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

I am not sure about the format of your specs.

@bettio bettio force-pushed the http-client branch 2 times, most recently from 1e33d44 to 4470de7 Compare May 8, 2024 13:05
@UncleGrumpy
Copy link
Collaborator

UncleGrumpy commented May 8, 2024

That comment was about the function specs. Although it does apply to types as well. I did not get the first line highlighted and included in my comment so the context was not very clear.

@bettio bettio force-pushed the http-client branch 6 times, most recently from cb06fc9 to 1f23730 Compare May 13, 2024 21:15
@bettio bettio marked this pull request as ready for review May 13, 2024 21:16
Copy link
Collaborator

@UncleGrumpy UncleGrumpy left a comment

Choose a reason for hiding this comment

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

This looks good to me.

Copy link
Contributor

@arpunk arpunk left a comment

Choose a reason for hiding this comment

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

Thank you for this 🎉

Copy link
Collaborator

@pguyot pguyot left a comment

Choose a reason for hiding this comment

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

We are lacking tests beyond the example. When trying to test this code beyond a simple redirect on atomvm.net (e.g. to get HTTP errors), I ended up realizing our ssl implementation is not compatible with TLS 1.3 by lack of proper verification options.

libs/eavmlib/src/ahttp_client.erl Show resolved Hide resolved

-define(DEFAULT_WANTED_HEADERS, [<<"Content-Length">>]).

-record(http_client, {host, socket, parser, ref, parse_headers}).
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could we please have types for record fields?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed.

libs/eavmlib/src/ahttp_client.erl Show resolved Hide resolved
%% be provided.
%%
%% `stream' option can be used with `stream_request_body/3' in order to upload a bigger
%% binary in streaming mode. This option should be combined with `content-length' header.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Couldn't we stream without knowing the length? If it works we could just change the documentation with s/should be combined/may be combined/

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, but it requires chunked uploads with delimiters, that is beyond the scope of this PR. I would work on this with a further set of improvements.

libs/eavmlib/src/ahttp_client.erl Show resolved Hide resolved
split_header([Name | Tail], HeaderLine) ->
NameLen = byte_size(Name),
case HeaderLine of
<<Name:NameLen/binary, $:, Value/binary>> -> {ok, Name, Value};
Copy link
Collaborator

Choose a reason for hiding this comment

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

We have a case issue here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed.

%%
%% The updated returned connection should be used in place of the previous one as a
%% parameter for the next call.
%% The returned reference can be used later for matching responses when using `stream/2'.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I do not understand this usage, and it's not apparent in example.

Copy link
Collaborator

Choose a reason for hiding this comment

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

This is the only place that I find the documentation a bit unclear too. Perhaps inserting a short example here would help clear up any confusion.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

it can be used when handling multiple http requests from the same process, each request will have it's own reference.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I tried to clarify it

libs/eavmlib/src/ahttp_client.erl Show resolved Hide resolved
libs/eavmlib/src/ahttp_client.erl Show resolved Hide resolved
libs/eavmlib/src/ahttp_client.erl Show resolved Hide resolved
%% @param Method a http method such as "GET", "POST", "PUT", etc...
%% @param Path the path to the http resource, such as "/"
%% @param Headers a list of headers
%% @param Body the body that is sent to the server, may be undefined or nil when there is no body
Copy link
Collaborator

@UncleGrumpy UncleGrumpy May 14, 2024

Choose a reason for hiding this comment

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

Also whether it is nil or none the exact term should probably be code syntax highlighted with an Erlang (`') code block in the @param definition, so that it is understood to be a atom, and not "empty" or zero... Unless you go with the [] option.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed.

%% The first returned response to a new request is a status `{status, Ref, 200}' for
%% a successful response. After that headers and data may follow.
%%
%% Since the response might span multiple socket messages, `stream/3' may be called
Copy link
Collaborator

@UncleGrumpy UncleGrumpy May 16, 2024

Choose a reason for hiding this comment

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

Should this be stream/2, or stream_request_body/3? I don't see a stream/3.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed.

@bettio bettio force-pushed the http-client branch 4 times, most recently from af0e539 to 22ec303 Compare May 22, 2024 22:57
Add simple http client that can be used in different situations, such as
when performing updates, inspired to Mint Elixir http client.

Signed-off-by: Davide Bettio <[email protected]>
Disable it since `ahttp_client` cannot be run right now.

Signed-off-by: Davide Bettio <[email protected]>
@bettio bettio merged commit 007919b into atomvm:release-0.6 Jun 7, 2024
79 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants