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

Do not omit mandatory null content-length headers. #985

Merged
merged 1 commit into from
Jun 30, 2023

Conversation

mefyl
Copy link
Contributor

@mefyl mefyl commented Jun 14, 2023

The code currently reuses the code that determines whether a body should be read to determine whether a Content-Length header should be sent. However, for unchunked bodies of size 0, there is no body to read, but Content-Length: 0 is still mandatory for methods which may allow a body.

@mefyl mefyl force-pushed the missing-null-content-length branch 3 times, most recently from df8ad8d to d0186f9 Compare June 15, 2023 08:14
@rgrinberg
Copy link
Member

@anuragsoni can you have a look?

Copy link
Contributor

@anuragsoni anuragsoni 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!

One note for future releases is to re-think how we track this in a future release as the encoding field this api depends on has been deprecated and will be removed in a future release (https://github.com/mirage/ocaml-cohttp/blob/master/http/src/http.mli#L388-L389)

@anuragsoni
Copy link
Contributor

Hmm, that said, going through the async implementation again as a refresher, it looks like the current scenarios that are handled are:

The header module does perform a check if there's a transfer encoding header present before updating the header value so this change should be safe, but it'd be nice to either run this header setup in the individual backends based on the body types written for each backend (I think I lean towards linking the encoding type to the body as opposed to request as it is in the current cohttp version), or rethink whether the encoding type needs to be deprecated/removed.

@mefyl
Copy link
Contributor Author

mefyl commented Jun 16, 2023

I also think it would be better to automatically deduce this from the body type and entirely abstract this from the users, because in the vast majority of cases they do not care. HTTP 1 is a bit messy because it mixes transport-level and application-level headers, but IMO content-length, transfer-encoding etc. should not be manually configurable by the user. If they really want some manual control on these, Request and Response provide primitives to manually send headers and chunks of body.

It is also probably possible and desirable to factor all these behavior once and for all in the common cohttp library to ensure consitency across all backends. I'm currently toying with such factoring in this MR.

@anuragsoni
Copy link
Contributor

I also think it would be better to automatically deduce this from the body type

+1

It is also probably possible and desirable to factor all these behavior once and for all in the common cohttp library to ensure consitency across all backends. I'm currently toying with such factoring in this MR.

I haven't looked at the other pull-request, (and I'm not a maintainer for cohttp so take this with a grain of salt), but I found the shared signature/functor approach in cohttp a little awkward to work with when working on the new parser. This was exacerbated in the lwt backend where there was another layer added on top with the split between lwt, lwt.unix, and mirage.

Personally my preference after working on cohttp and opium (which used to be built on top of cohttp), leans towards using the http library for writing the common types and operations on them (header manipulation, stateless parsers for requests/responses/chunked bodies etc), and letting each IO backend orchestrate the rest according to the best options available in each backend. As I see it, having the shared signatures in cohttp is a little helpful for maintainers of cohttp in that there can be a shared set of features that can be managed centrally, in-practice the shared signatures have been a little awkward to work with personally since any interaction with them necessitates instantiating a functor, which leads to either other libraries building on top of cohttp also being functorized, and/or picking a single backend and sticking to it.

@mefyl
Copy link
Contributor Author

mefyl commented Jun 16, 2023

I'm not talking about functors here, just :

module type CLIENT = sig
  type 'a io
  val call : request -> body -> (response * body) io
end

module Client_lwt : CLIENT with type 'a io = 'a Lw.t
module Client_eio : CLIENT with type 'a io = 'a

The end users don't need to instantiate a functor, they can use the values directly. Actually they needn't even know there is a common signature. The only aim would be indeed to help maintaining consistency, so that when switching backend the same feature set / API is guaranteed. One could also imagine writing a library that works with any cohttp backend, but that would indeed require a functor.

Now here I'm not even arguing for / against this, I just want to emulate the current API word-for-word to ease possible adoption of that MR, without bundling API design choice in it; that can come in a second time.

These discussion probably belong over there, for that matter :)

@rgrinberg
Copy link
Member

LGTM. can you rebase?

@mefyl mefyl force-pushed the missing-null-content-length branch from d5f776c to cdeed90 Compare June 30, 2023 12:47
	Content-Length, even if null, is mandatory for unchunked
        request which method may allow a body.
@mefyl mefyl force-pushed the missing-null-content-length branch from cdeed90 to e582f5d Compare June 30, 2023 13:02
@mseri mseri merged commit db032bf into mirage:master Jun 30, 2023
17 of 19 checks passed
@mseri
Copy link
Collaborator

mseri commented Jun 30, 2023

Thanks!

@mefyl mefyl deleted the missing-null-content-length branch June 30, 2023 16:12
mseri added a commit to mseri/opam-repository that referenced this pull request Aug 8, 2023
…p-mirage, cohttp-lwt, cohttp-lwt-unix, cohttp-lwt-jsoo, cohttp-eio, cohttp-curl, cohttp-curl-lwt, cohttp-curl-async, cohttp-bench and cohttp-async (6.0.0~alpha2)

CHANGES:

- cohttp-lwt: Do not leak exceptions to `Lwt.async_exception_hook`. (mefyl mirage/ocaml-cohttp#992, mirage/ocaml-cohttp#995)
- http.header, cohttp, cohttp-eio: remove "first" and "move_to_first" and the special treatment of the "host" header (mseri mirage/ocaml-cohttp#988, mirage/ocaml-cohttp#986)
- http.header: introduce "iter_ord" to guarantee iteration following the order of the entries in the headers (mseri mirage/ocaml-cohttp#986)
- do not omit mandatory null Content-Length headers (mefyl mirage/ocaml-cohttp#985)
- cohttp-async, cohttp-curl-async: compatibility with core/async v0.16.0 (mseri, dkalinichenko-js mirage/ocaml-cohttp#976)
- cohttp-lwt server: call conn_closed before drainig the body of response on error (pirbo mirage/ocaml-cohttp#982)
- cohttp-eio: Relax socket interface requirement on `Server.connection_handler`. (mefyl mirage/ocaml-cohttp#983)
mseri added a commit to mseri/opam-repository that referenced this pull request Aug 8, 2023
…p-mirage, cohttp-lwt, cohttp-lwt-unix, cohttp-lwt-jsoo, cohttp-eio, cohttp-curl, cohttp-curl-lwt, cohttp-curl-async and cohttp-async (6.0.0~alpha2)

CHANGES:

- cohttp-lwt: Do not leak exceptions to `Lwt.async_exception_hook`. (mefyl mirage/ocaml-cohttp#992, mirage/ocaml-cohttp#995)
- http.header, cohttp, cohttp-eio: remove "first" and "move_to_first" and the special treatment of the "host" header (mseri mirage/ocaml-cohttp#988, mirage/ocaml-cohttp#986)
- http.header: introduce "iter_ord" to guarantee iteration following the order of the entries in the headers (mseri mirage/ocaml-cohttp#986)
- do not omit mandatory null Content-Length headers (mefyl mirage/ocaml-cohttp#985)
- cohttp-async, cohttp-curl-async: compatibility with core/async v0.16.0 (mseri, dkalinichenko-js mirage/ocaml-cohttp#976)
- cohttp-lwt server: call conn_closed before drainig the body of response on error (pirbo mirage/ocaml-cohttp#982)
- cohttp-eio: Relax socket interface requirement on `Server.connection_handler`. (mefyl mirage/ocaml-cohttp#983)
nberth pushed a commit to nberth/opam-repository that referenced this pull request Jun 18, 2024
…p-mirage, cohttp-lwt, cohttp-lwt-unix, cohttp-lwt-jsoo, cohttp-eio, cohttp-curl, cohttp-curl-lwt, cohttp-curl-async and cohttp-async (6.0.0~alpha2)

CHANGES:

- cohttp-lwt: Do not leak exceptions to `Lwt.async_exception_hook`. (mefyl mirage/ocaml-cohttp#992, mirage/ocaml-cohttp#995)
- http.header, cohttp, cohttp-eio: remove "first" and "move_to_first" and the special treatment of the "host" header (mseri mirage/ocaml-cohttp#988, mirage/ocaml-cohttp#986)
- http.header: introduce "iter_ord" to guarantee iteration following the order of the entries in the headers (mseri mirage/ocaml-cohttp#986)
- do not omit mandatory null Content-Length headers (mefyl mirage/ocaml-cohttp#985)
- cohttp-async, cohttp-curl-async: compatibility with core/async v0.16.0 (mseri, dkalinichenko-js mirage/ocaml-cohttp#976)
- cohttp-lwt server: call conn_closed before drainig the body of response on error (pirbo mirage/ocaml-cohttp#982)
- cohttp-eio: Relax socket interface requirement on `Server.connection_handler`. (mefyl mirage/ocaml-cohttp#983)
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.

None yet

4 participants