Menu

#1349 "Expect: 100-continue" used when "Content-Length:0" in PUT request

closed-fixed
None
5
2014-10-30
2014-03-25
JimS
No

When doing a POST of a zero length file, or any file when using digest authentication curl will issue an "Expect: 100-continue" header as well as a "Content-Length: 0". This violates RFC-2616 and earns a 400 error code from servers written in Go 1.2.

Section 8.2.3 includes:

A client MUST NOT send an Expect request-header field (Expect) with the "100-continue" expectation if it does not intend to send a request body.

Once the problem is understood, using "-H Expect:" suppresses the header and allows the command to function normally.

If a Content-Length: 0 for a zero length POST constitutes not sending a body is debatable. Omitting the body when digest authentication probes to get a nonce is clearly against the RFC.

Maximum compatibility would be achieved by omitting the "Expect" header in both of these cases, the queries would save a turnaround, and there is no performance downside, since the bodies are empty anyway. There is probably an applicable code path, since doing a POST of /dev/null does not send the Expect header.

$ curl --version
curl 7.26.0 (x86_64-pc-linux-gnu) libcurl/7.26.0 OpenSSL/1.0.1e zlib/1.2.7 libidn/1.25 libssh2/1.4.2 librtmp/2.3
Protocols: dict file ftp ftps gopher http https imap imaps ldap pop3 pop3s rtmp rtsp scp sftp smtp smtps telnet tftp 
Features: Debug GSS-Negotiate IDN IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP

Related

Bugs: #1349

Discussion

  • Daniel Stenberg

    Daniel Stenberg - 2014-03-25
    • assigned_to: Daniel Stenberg
     
    • JimS

      JimS - 2014-04-01

      I've confused this bug report by typing POST instead of PUT, so just continue as if I said PUT the first time.

      To replicate the problem with a recent curl I moved a machine to Debian jessie, same problem...

      jim@future:~$ curl -v -T empty.txt http://127.0.0.1:8080/images/ -H Content-Type:image/png
      Hostname was NOT found in DNS cache
      Trying 127.0.0.1...
      * Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)

      PUT /images/empty.txt HTTP/1.1
      User-Agent: curl/7.35.0
      Host: 127.0.0.1:8080
      Accept: /
      Content-Type:image/png
      Content-Length: 0
      Expect: 100-continue

      < HTTP/1.1 400 Bad Request
      < Connection: close
      < Date: Tue, 01 Apr 2014 19:22:28 GMT
      < Content-Length: 0
      < Content-Type: text/plain; charset=utf-8
      <
      * Closing connection 0

      The crux of the problem having both a Content-Length:0 and an Expect: 100-continue. This will happen communicating with any server written using the standard Go http packages. They interpret a Content-Length of 0 as "no body" and in violating section 8.2.3 of RFC-2616. I would say they are wrong. I think section 4.3 is clear that messages can be of zero length. The fact remains that curl will fail on Go servers for no benefit. Expanding the header to explicitly wait for a network turnaround before transferring zero bytes is nonsensical.

      Moving on to the htdigest, zero length body optimization to get a nonce, this is dangerous, non compliant default behavior. It fails with Go because it trips the same Content-Length: 0, Expect conflict, again the Expect gains nothing with a zero length body. The dangerous part comes because a PUT of a fictitious zero length body might succeed and overwrite an existing resource leaving an erroneous state available in the server. In the best case when the eventual PUT of the data arrives it will be accepted, but if the server does validation of the body and rejects the operation you will have effectively destroyed the previous contents.

      On Mar 25, 2014, at 2:20 AM, Daniel Stenberg bagder@users.sf.net wrote:

      • assigned_to: Daniel Stenberg
      • Comment:
      Can you show us a command line to get zero content-length? I'm not sure I can repeat it with a recent curl version.

      "If a Content-Length: 0 for a zero length POST constitutes not sending a body is debatable. " What else would it mean?

      "Omitting the body when digest authentication probes to get a nonce is clearly against the RFC." Which RFC are you talking about here? I know it is far from ideal to do it like that, but it is a shortcut that is wildly supported and you can tell curl to not do it so we've opted to keep the shortcut for the faster operation for those who can use it.

      [bugs:#1349] Expect: 100-continue sent with no body violates RFC.

      Status: open
      Created: Tue Mar 25, 2014 12:40 AM UTC by JimS
      Last Updated: Tue Mar 25, 2014 12:40 AM UTC
      Owner: Daniel Stenberg

      When doing a POST of a zero length file, or any file when using digest authentication curl will issue an "Expect: 100-continue" header as well as a "Content-Length: 0". This violates RFC-2616 and earns a 400 error code from servers written in Go 1.2.

      Section 8.2.3 includes:

      A client MUST NOT send an Expect request-header field (Expect) with the "100-continue" expectation if it does not intend to send a request body.

      Once the problem is understood, using "-H Expect:" suppresses the header and allows the command to function normally.

      If a Content-Length: 0 for a zero length POST constitutes not sending a body is debatable. Omitting the body when digest authentication probes to get a nonce is clearly against the RFC.

      Maximum compatibility would be achieved by omitting the "Expect" header in both of these cases, the queries would save a turnaround, and there is no performance downside, since the bodies are empty anyway. There is probably an applicable code path, since doing a POST of /dev/null does not send the Expect header.

      $ curl --version
      curl 7.26.0 (x86_64-pc-linux-gnu) libcurl/7.26.0 OpenSSL/1.0.1e zlib/1.2.7 libidn/1.25 libssh2/1.4.2 librtmp/2.3
      Protocols: dict file ftp ftps gopher http https imap imaps ldap pop3 pop3s rtmp rtsp scp sftp smtp smtps telnet tftp

      Features: Debug GSS-Negotiate IDN IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP
      Sent from sourceforge.net because you indicated interest in https://sourceforge.net/p/curl/bugs/1349/

      To unsubscribe from further messages, please visit https://sourceforge.net/auth/subscriptions/

       

      Related

      Bugs: #1349

      • Daniel Stenberg

        Daniel Stenberg - 2014-04-04

        I agree that "Content-Length: 0" together with "Expect: 100-continue" is plain nonsense and that's the main bug I take from this bug report.

        "Content-Length: 0" in a request without the Expect: header is perfectly fine. It is a signal that there's 0 bytes sent in a request, which for PUT or POST is not the norm. If you want to persue to somehow limit the use of that, I suggest we do that as a separate bug report to not confuse matters too much here.

         
  • Daniel Stenberg

    Daniel Stenberg - 2014-03-25

    Can you show us a command line to get zero content-length? I'm not sure I can repeat it with a recent curl version.

    "If a Content-Length: 0 for a zero length POST constitutes not sending a body is debatable. " What else would it mean?

    "Omitting the body when digest authentication probes to get a nonce is clearly against the RFC." Which RFC are you talking about here? I know it is far from ideal to do it like that, but it is a shortcut that is wildly supported and you can tell curl to not do it so we've opted to keep the shortcut for the faster operation for those who can use it.

     
  • Daniel Stenberg

    Daniel Stenberg - 2014-04-04
    • summary: Expect: 100-continue sent with no body violates RFC. --> "Expect: 100-continue" used when "Content-Length:0" in PUT request
    • status: open --> open-confirmed
     
  • Daniel Stenberg

    Daniel Stenberg - 2014-04-04
    • status: open-confirmed --> closed-fixed
     
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.