Skip to content

Conversation

@jukkar
Copy link
Member

@jukkar jukkar commented Oct 10, 2017

This is a proposal for new HTTP library that uses net-app API instead of running things directly on top of net_context.
This supports both HTTP client and server functionality, both are also supporting TLS. Old HTTP API is deprecated.
I will also send a PR that will add websocket support to this new API.

@jukkar jukkar self-assigned this Oct 10, 2017
@jukkar jukkar requested review from mike-scott and pfalcon October 10, 2017 07:55
@jukkar jukkar mentioned this pull request Oct 10, 2017
Copy link
Member

Choose a reason for hiding this comment

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

Although this won't crash, if buflen=NET_IPV4_ADDR_LEN, this will truncate this string if the address family is invalid.

Copy link
Member Author

Choose a reason for hiding this comment

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

Sure, not a big issue thou as this is just used for debug printing.

Copy link
Member

Choose a reason for hiding this comment

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

A future improvement could redirect all HTTP requests to HTTPS if TLS is enabled.

Copy link
Member Author

Choose a reason for hiding this comment

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

Sure, but this depends on how application is doing things. If we have enabled HTTPS, then HTTP port is not normally listened at all. So application would need to create a listener to port 80 and then re-direct traffic to HTTPS port in this case.

Copy link
Member

Choose a reason for hiding this comment

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

If the URLs array is sorted by URL length, it's possible to quickly perform a longest subprefix match without requiring fancier data structures like a trie. This should simplify URL matching as well.

Copy link
Member Author

Choose a reason for hiding this comment

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

This can be done by application which can fill the url array in desired order.

Copy link
Member

Choose a reason for hiding this comment

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

This is unused.

Copy link
Member Author

Choose a reason for hiding this comment

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

Indeed, good catch.

@mike-scott
Copy link
Contributor

I'll try and review the next version posted as I'm a bit buried atm.

Copy link
Contributor

Choose a reason for hiding this comment

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

add a comma before the "and" for the last item in this list.

Copy link
Contributor

Choose a reason for hiding this comment

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

s/like/such as/

Copy link
Contributor

Choose a reason for hiding this comment

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

add a comma before the "and" for the last item in this list.

Copy link
Contributor

Choose a reason for hiding this comment

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

s/must be/is/

Copy link
Contributor

Choose a reason for hiding this comment

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

s/must be understood as/is/

Copy link
Contributor

Choose a reason for hiding this comment

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

s/The inspection of/Inspecting/

Copy link
Contributor

@dbkinder dbkinder left a comment

Choose a reason for hiding this comment

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

some suggested edits

Copy link
Member

@nashif nashif left a comment

Choose a reason for hiding this comment

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

Get rid of all those http_app_xxx just call it http, there is no reason why we should have app in the name

Copy link
Contributor

Choose a reason for hiding this comment

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

It might happen in TCP client, that the TCP connection is terminated in which case net_context is freed. Check this and mark corresponding net_context inside net_app to NULL. This way there will be no issue to access already freed net_context.

This is very dangerous. What if it's freed and already reused?

Such condition should not happen, it's a bug and we should be fix it (which should be as simple as incrementing a refcount for it, or not so simple).

I'm writing in particular because I see some weird issues in MicroPython which could be explained by this issue to.

Copy link
Member Author

Choose a reason for hiding this comment

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

What if it's freed and already reused?

That is why we mark the context as NULL here so that we do not reuse it in net-app.

I am not sure if adding refcount here would help as if TCP connection is closed, then we would need to inform the users of the net_context that it is closed. Probably using other flags in net_context we could figure this out in users of net_context.

Copy link
Contributor

Choose a reason for hiding this comment

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

That is why we mark the context as NULL here so that we do not reuse it in net-app.

What if it's reused by non-net-app?

I am not sure if adding refcount here would help as if TCP connection is closed, then we would need to inform the users of the net_context that it is closed.

Well, (at the very least) we just need to make sure that the closed context is properly marked so (so any further operation on it will return appropriate error), but it's not freed until user closes ("puts") its own reference to it.

Copy link
Contributor

@pfalcon pfalcon left a comment

Choose a reason for hiding this comment

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

As discussed in RFC on the mailing list and in review comments to #980, I really think that the new API doesn't offer enough improvements over old one, and even calls for particular, questionable design choices in the underlying stack (e.g. #1330).

So, I'd like to propose to rework it. Let me start with a first: reworking a TX path for HTTP.

Proposal:

  1. There should be a single function to handle sending of HTTP content, let it be called http_send_data() (this reuses the name of function used in this PR for completely different semantics, hope that's not too confusing with this note.
  2. It's prototype to be int http_send_data(struct http_ctx *ctx, const char *payload, size_t payload_len); Note - no references to network packets or something.
  3. struct http_ctx should have a member struct net_pkt *tx_pkt, initially set to NULL.
  4. Algorithm of the function described in below points.
  5. If ctx->tx_pkt is not allocated, allocate it.
  6. Add to the packet whatever data of payload fits. (This will require #119).
  7. If all user data handled, return.
  8. When full, send the packet to the network and set ctx->tx_pkt to NULL.
  9. Repeat from 5. for remaining user data.

All other functions can be implemented in terms of http_send_data().

In addition to http_send_data(), should have http_flush_data(), which will send whatever data has already buffered (useful e.g. for websockets), and http_finish_data() (HTTP 1.0 would close connection here).

The names are tentative. Possibly, http_send_data() won't be user-facing function (likely wrappers will be required to be user-facing to abstract away chunked encoding), so that function can be called differently and "http_send_data" reused for more user-facing func.

@jukkar
Copy link
Member Author

jukkar commented Oct 27, 2017

even calls for particular, questionable design choices in the underlying stack (e.g. #1330).

I do not understand how #1330 is related to this PR, could you elaborate this claim?

@pfalcon
Copy link
Contributor

pfalcon commented Oct 27, 2017

I do not understand how #1330 is related to this PR, could you elaborate this claim?

This PR introduces such an HTTP API which then requires #1330 to handle some of the API "aspects". If the API is redesigned, going for solution like #1330 won't be required (with many issues raised with it).

@jukkar
Copy link
Member Author

jukkar commented Oct 27, 2017

This PR introduces such an HTTP API which then requires #1330 to handle some of the API "aspects".

This is false, the API does not mandate the use of #1330
I just wanted to simplify the sample application logic and avoid looping through data.

Anyway, I will investigate your proposal for API functions more next week.

@pfalcon
Copy link
Contributor

pfalcon commented Oct 27, 2017

Anyway, I will investigate your proposal for API functions more next week.

I appreciate that. I'll be happy to help with the implementation in any way I can.

@pfalcon
Copy link
Contributor

pfalcon commented Nov 1, 2017

So, I don't see http_client_send_post_req() in the code, only in the header, was anything done to it, or am I missing something?

Hmm, I do not recall any comment regarding that API, you want that changed too?

The comment is here: #4243 (comment) , I suggested that it's not general enough to not take the payload size (rules out use with binary payloads).

@jukkar
Copy link
Member Author

jukkar commented Nov 1, 2017

The comment is here: #4243 (comment) , I suggest that it's not general enough to not take the payload size (rules out use with binary payloads).

Indeed. I will remove the POST helper, one is able to send a POST request without it anyway.

@pfalcon
Copy link
Contributor

pfalcon commented Nov 1, 2017

Makes sense, thanks!

@jukkar
Copy link
Member Author

jukkar commented Nov 1, 2017

Changes:

  • fix merge conflicts
  • fix sanity errors
  • removed POST req client helper
  • moved functions around in http_app.c
  • combined two chunk send functions together

Copy link
Contributor

@pfalcon pfalcon left a comment

Choose a reason for hiding this comment

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

Ok, I think this is a very good progress in the right direction. My general suggestion is that we treated such work as an iterative process, and didn't try to replace an older API version at once. For example, I may imagine, further changes/fixes will be required as this API gets more use.

But for iteration one it's really good, +1.

@jukkar
Copy link
Member Author

jukkar commented Nov 1, 2017

@dbkinder the documentation checker fails with this message

/home/buildslave/src/github.com/zephyrproject-rtos/zephyr/include/net/http_app.h:1040: warning: reached end of file while inside a verbatim block!
The command that should end the block seems to be missing!

/home/buildslave/src/github.com/zephyrproject-rtos/zephyr/include/net/http_app.h:1040: warning: end of file while inside a group

I have spent several hours trying to understand what goes wrong but have failed so far. The header file contains proper @{ and @} markers so it baffles me what is the root cause of this warning. And doxygen does not tell what is the actual problem it encountered. Could you help here to solve this issue?
I also verified that the "make htmldocs" generates proper documentation for the HTTP api.

@jukkar
Copy link
Member Author

jukkar commented Nov 2, 2017

@nashif Ping, does this look something that is acceptable to you? I deprecated the old API, but if you want I can certainly remove it alltogether.

@dbkinder
Copy link
Contributor

dbkinder commented Nov 3, 2017

@jukkar @nashif It took quite a while but I found the culprit. I ended up just deleting chunks of lines, running doxygen on just this file, and finding the line(s) causing the problem. Doxygen doesn't like to see \r in a doxygen comment. You've got a few in here as \r\n that I deleted (leaving just the \n) the the verbatim block and end of file in a group warning went away, yea! Maybe replace use of \r\n in doxygen comments as HTTP_CRLF (as in the #define you have).

That then exposed some errors because you missed the documentation for a couple of function parameters:

http_app.h:967: warning: The following parameters of http_add_header(struct http_ctx *ctx, const char *http_header_field, void *user_send_data) are not documented:
parameter 'user_send_data'

http_app.h:983: warning: The following parameters of http_add_header_field(struct http_ctx *ctx, const char *name, const char *value, void *user_send_data) are not documented:
parameter 'user_send_data'

Copy link
Contributor

@dbkinder dbkinder left a comment

Choose a reason for hiding this comment

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

\r in doxygen comments can cause odd "end of file while inside a verbatim block" warnings

Copy link
Contributor

Choose a reason for hiding this comment

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

Can't use \r in a doxygen comment. Recommend something like this instead:

 The format is "name: value<HTTP_CRLF>"

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks David! Really peculiar issue indeed, especially as the warning did not match the root cause.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can't use \r in a doxygen comment.

Maybe it should be double-quoted, like \\r? @jukkar , please try that first, because having \r\n is clearer than <HTTP_CRLF>.

@jukkar
Copy link
Member Author

jukkar commented Nov 3, 2017

Changed the documentation so that sanity check passes without warnings.

Copy link
Contributor

Choose a reason for hiding this comment

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

If we're starting a trend to ignore *_legacy.h files, better would be to delete these individual files listed here and change the line below to be:

 EXCLUDE_PATTERNS = *_legacy.h

Copy link
Member Author

Choose a reason for hiding this comment

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

I am ok with this. Perhaps this could be a separate patch and not part of this set.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok. I’ll submit a separate patch for ignoring all _legacy.h files.

Copy link
Contributor

Choose a reason for hiding this comment

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

I've verified that using \\r\\n works in doxygen, so if you'd like to use that, I think the output would be nicer, though the way you've written this works for me since it references the #define above.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok, I think too that \r\n looks better in the documentation. I will send a new version that changes this.

@jukkar
Copy link
Member Author

jukkar commented Nov 6, 2017

Updated the documentation and changed <HTTP_CRLF> to \\r\\n

Create http library that uses net-app instead of net_context
directly. The old HTTP API is deprecated.

Signed-off-by: Jukka Rissanen <[email protected]>
The old HTTP server and client library code is deprecated. The
new HTTP library will be based on net-app API code which requires
changes to function names and parameters that are not compatible
with old library.

Signed-off-by: Jukka Rissanen <[email protected]>
As the old HTTP API is deprecated, the old samples can be removed.

Signed-off-by: Jukka Rissanen <[email protected]>
This is a sample HTTP server application that uses new http API
instead of legacy one.

Signed-off-by: Jukka Rissanen <[email protected]>
This is a sample HTTP client application that uses new http API
instead of legacy one.

Signed-off-by: Jukka Rissanen <[email protected]>
Mysterious TLS errors are printed if we try to work with too
small crypto buffer when https is enabled.

Signed-off-by: Jukka Rissanen <[email protected]>
@jukkar
Copy link
Member Author

jukkar commented Nov 6, 2017

Fixed the http_url_flags enum values in header file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants