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

Content-Length sent for OPTIONS requests #1310

Closed
2 tasks done
ansman opened this issue Mar 1, 2022 · 2 comments · Fixed by #1319
Closed
2 tasks done

Content-Length sent for OPTIONS requests #1310

ansman opened this issue Mar 1, 2022 · 2 comments · Fixed by #1319
Labels
bug Something isn't working

Comments

@ansman
Copy link

ansman commented Mar 1, 2022

Checklist

  • I've searched for similar issues.
  • I'm using the latest version of HTTPie.

Minimal reproduction code and steps

  1. $ http OPTIONS https://example.com -v

Current result

OPTIONS / HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 0
Host: example.com
User-Agent: HTTPie/3.0.2

Expected result

OPTIONS / HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: example.com
User-Agent: HTTPie/3.0.2

Debug output

Please re-run the command with --debug, then copy the entire command & output and paste both below:

$ http OPTIONS https://example.com -v --debug
HTTPie 3.0.2
Requests 2.27.1
Pygments 2.11.2
Python 3.10.2 (main, Feb  2 2022, 05:51:25) [Clang 13.0.0 (clang-1300.0.29.3)]
/opt/homebrew/Cellar/httpie/3.0.2/libexec/bin/python3.10
Darwin 21.2.0

<Environment {'as_silent': <function Environment.as_silent at 0x105790700>,
 'colors': 256,
 'config': {'default_options': []},
 'config_dir': PosixPath('/Users/nicklas/.config/httpie'),
 'devnull': <property object at 0x1057753a0>,
 'is_windows': False,
 'log_error': <function Environment.log_error at 0x105790790>,
 'program_name': 'http',
 'stderr': <_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>,
 'stderr_isatty': True,
 'stdin': <_io.TextIOWrapper name='<stdin>' mode='r' encoding='utf-8'>,
 'stdin_encoding': 'utf-8',
 'stdin_isatty': True,
 'stdout': <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>,
 'stdout_encoding': 'utf-8',
 'stdout_isatty': True}>

<PluginManager {'adapters': [],
 'auth': [<class 'httpie.plugins.builtin.BasicAuthPlugin'>,
          <class 'httpie.plugins.builtin.DigestAuthPlugin'>,
          <class 'httpie.plugins.builtin.BearerAuthPlugin'>],
 'converters': [],
 'formatters': [<class 'httpie.output.formatters.headers.HeadersFormatter'>,
                <class 'httpie.output.formatters.json.JSONFormatter'>,
                <class 'httpie.output.formatters.xml.XMLFormatter'>,
                <class 'httpie.output.formatters.colors.ColorFormatter'>]}>

>>> requests.request(**{'auth': None,
 'data': RequestJSONDataDict(),
 'headers': <HTTPHeadersDict('User-Agent': b'HTTPie/3.0.2')>,
 'method': 'options',
 'params': <generator object MultiValueOrderedDict.items at 0x105a373e0>,
 'url': 'https://example.com'})

OPTIONS / HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 0
Host: example.com
User-Agent: HTTPie/3.0.2



HTTP/1.1 200 OK
Allow: OPTIONS, GET, HEAD, POST
Cache-Control: max-age=604800
Content-Length: 0
Content-Type: text/html; charset=UTF-8
Date: Tue, 01 Mar 2022 17:47:08 GMT
Expires: Tue, 08 Mar 2022 17:47:08 GMT
Server: EOS (vny/0453)

Additional information, screenshots, or code examples

Since OPTIONS requests are not permitted to have a body the Content-Length header should not be included by default.

@ansman ansman added bug Something isn't working new Needs triage. Comments are welcome! labels Mar 1, 2022
@isidentical
Copy link
Contributor

Thanks for the report @ansman, this seems like an issue in the underlying library we use (requests):
https://github.com/psf/requests/blob/79f60274f7e461b8fd2f579e741f748438d7eadb/requests/models.py#L545-L548

I'll send a temporary fix for HTTPie, and a more permanent fix for the the requests library.

@isidentical isidentical added benchmark and removed new Needs triage. Comments are welcome! labels Mar 1, 2022
@isidentical
Copy link
Contributor

Since OPTIONS requests are not permitted to have a body the Content-Length header should not be included by default.

Even though MDN agrees this by stating

OPTIONS
  Request has body: No

RFC 7231 claims:

4.3.7 OPTIONS:

[...]

A client that generates an OPTIONS request containing a payload body
MUST send a valid Content-Type header field describing the
representation media type.  Although this specification does not
define any use for such a payload, future extensions to HTTP might
use the OPTIONS body to make more detailed queries about the target
resource.

which implies that OPTIONS can have payload unlike GET and HEAD whose payload is strictly discouraged:

4.3.1 GET:

[...]

A payload within a GET request message has no defined semantics;
sending a payload body on a GET request might cause some existing
implementations to reject the request.
4.3.2 HEAD:

[...]

A payload within a HEAD request message has no defined semantics;
sending a payload body on a HEAD request might cause some existing
implementations to reject the request.

I am not sure whether we should omit the Content-Length on our side or not (since this seems to be in a gray area).


cURL seem to omit it:

$ curl --trace-ascii - -X OPTIONS http://example.org -i
== Info:   Trying 93.184.216.34:80...
== Info:   Trying 2606:2800:220:1:248:1893:25c8:1946:80...
== Info: Immediate connect fail for 2606:2800:220:1:248:1893:25c8:1946: Network is unreachable
== Info: Connected to example.org (93.184.216.34) port 80 (#0)
=> Send header, 79 bytes (0x4f)
0000: OPTIONS / HTTP/1.1
0014: Host: example.org
0027: User-Agent: curl/7.74.0
0040: Accept: */*
004d: 
$ curl --trace-ascii - -X OPTIONS http://example.org -i --data 'x'
== Info:   Trying 93.184.216.34:80...
== Info: Connected to example.org (93.184.216.34) port 80 (#0)
=> Send header, 147 bytes (0x93)
0000: OPTIONS / HTTP/1.1
0014: Host: example.org
0027: User-Agent: curl/7.74.0
0040: Accept: */*
004d: Content-Length: 1
0060: Content-Type: application/x-www-form-urlencoded
0091: 
=> Send data, 1 bytes (0x1)
0000: x

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants