]> granicus.if.org Git - curl/commitdiff
http: added options for allowing HTTP/0.9 responses
authorDaniel Stenberg <daniel@haxx.se>
Mon, 17 Dec 2018 14:46:56 +0000 (15:46 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 21 Dec 2018 09:49:30 +0000 (10:49 +0100)
Added CURLOPT_HTTP09_ALLOWED and --http0.9 for this purpose.

For now, both the tool and library allow HTTP/0.9 by default.
docs/DEPRECATE.md lays out the plan for when to reverse that default: 6
months after the 7.64.0 release. The options are added already now so
that applications/scripts can start using them already now.

Fixes #2873
Closes #3383

36 files changed:
docs/DEPRECATE.md
docs/cmdline-opts/Makefile.inc
docs/cmdline-opts/http0.9.d [new file with mode: 0644]
docs/libcurl/curl_easy_setopt.3
docs/libcurl/opts/CURLOPT_HTTP09_ALLOWED.3 [new file with mode: 0644]
docs/libcurl/opts/CURLOPT_HTTP_VERSION.3
docs/libcurl/opts/Makefile.inc
docs/libcurl/symbols-in-versions
include/curl/curl.h
lib/http.c
lib/setopt.c
lib/url.c
lib/urldata.h
src/tool_cfgable.c
src/tool_cfgable.h
src/tool_getparam.c
src/tool_help.c
src/tool_operate.c
tests/data/Makefile.inc
tests/data/test1144
tests/data/test1164
tests/data/test1172 [new file with mode: 0644]
tests/data/test1266
tests/data/test1267
tests/data/test1400
tests/data/test1401
tests/data/test1402
tests/data/test1403
tests/data/test1404
tests/data/test1405
tests/data/test1406
tests/data/test1407
tests/data/test1420
tests/data/test1429
tests/data/test306
tests/data/test66

index bb3c05fe1fbf806c279aa2b6446f6ada8e4e91ad..27bd22ff752a3449b94419fe7b011383ec1756ff 100644 (file)
@@ -64,3 +64,18 @@ revert if need be.
 
 Remove all global-cache related code from curl around April 2019 (might be
 7.66.0).
+
+## HTTP/0.9
+
+Supporting this is non-obvious and might even come as a surprise to some
+users. Potentially even being a security risk in some cases.
+
+### State
+
+curl 7.64.0 introduces options to disable/enable support for this protocol
+version. The default remains supported for now.
+
+### Removal
+
+The support for HTTP/0.9 will be switched to disabled by default in 6 months,
+in the September 2019 release (possibly called curl 7.68.0).
index 76fa5d45fdceb27edb3b735c1a095b58907054d3..b99a142eee78e1a2905a881231dad1496f247717 100644 (file)
 # Shared between Makefile.am and CMakeLists.txt
 
-DPAGES = abstract-unix-socket.d anyauth.d append.d basic.d cacert.d capath.d cert.d \
-  cert-status.d cert-type.d ciphers.d compressed.d compressed-ssh.d     \
-  config.d doh-url.d                                                    \
-  connect-timeout.d connect-to.d continue-at.d cookie.d cookie-jar.d    \
-  create-dirs.d crlf.d crlfile.d data-ascii.d data-binary.d data.d      \
-  data-raw.d data-urlencode.d delegation.d digest.d disable.d           \
-  disable-eprt.d disable-epsv.d dns-interface.d dns-ipv4-addr.d         \
-  dns-ipv6-addr.d dns-servers.d dump-header.d egd-file.d engine.d       \
-  expect100-timeout.d fail.d fail-early.d false-start.d                 \
-  form.d form-string.d ftp-account.d ftp-alternative-to-user.d          \
-  ftp-create-dirs.d ftp-method.d ftp-pasv.d ftp-port.d ftp-pret.d       \
-  ftp-skip-pasv-ip.d ftp-ssl-ccc.d ftp-ssl-ccc-mode.d ftp-ssl-control.d \
-  get.d globoff.d                                                       \
-  happy-eyeballs-timeout-ms.d                                           \
-  head.d header.d help.d hostpubmd5.d http1.0.d                         \
-  http1.1.d http2.d http2-prior-knowledge.d ignore-content-length.d     \
-  include.d insecure.d interface.d ipv4.d ipv6.d junk-session-cookies.d \
-  keepalive-time.d key.d key-type.d krb.d libcurl.d limit-rate.d        \
-  list-only.d local-port.d location.d location-trusted.d                \
-  login-options.d mail-auth.d mail-from.d mail-rcpt.d manual.d          \
-  max-filesize.d max-redirs.d max-time.d metalink.d negotiate.d netrc.d \
-  netrc-file.d netrc-optional.d next.d no-alpn.d no-buffer.d            \
-  no-keepalive.d no-npn.d noproxy.d no-sessionid.d ntlm.d ntlm-wb.d     \
-  oauth2-bearer.d output.d pass.d path-as-is.d pinnedpubkey.d post301.d \
-  post302.d post303.d preproxy.d progress-bar.d proto.d proto-default.d \
-  proto-redir.d proxy1.0.d proxy-anyauth.d proxy-basic.d proxy-cacert.d \
-  proxy-capath.d proxy-cert.d proxy-cert-type.d proxy-ciphers.d         \
-  proxy-crlfile.d proxy.d proxy-digest.d proxy-header.d                 \
-  proxy-insecure.d proxy-key.d proxy-key-type.d proxy-negotiate.d       \
-  proxy-ntlm.d proxy-pass.d proxy-service-name.d                        \
-  proxy-ssl-allow-beast.d proxy-tlsauthtype.d proxy-tlspassword.d       \
-  proxy-tlsuser.d proxy-tlsv1.d proxytunnel.d proxy-user.d pubkey.d     \
-  quote.d random-file.d range.d raw.d referer.d remote-header-name.d    \
-  remote-name-all.d remote-name.d remote-time.d request.d resolve.d     \
-  retry-connrefused.d retry.d retry-delay.d retry-max-time.d sasl-ir.d  \
-  service-name.d show-error.d silent.d socks4a.d socks4.d socks5.d      \
-  socks5-basic.d socks5-gssapi.d proxy-pinnedpubkey.d                   \
-  socks5-gssapi-nec.d socks5-gssapi-service.d socks5-hostname.d         \
-  speed-limit.d speed-time.d ssl-allow-beast.d ssl.d ssl-no-revoke.d    \
-  ssl-reqd.d sslv2.d sslv3.d stderr.d suppress-connect-headers.d        \
-  tcp-fastopen.d tcp-nodelay.d                                          \
-  telnet-option.d tftp-blksize.d tftp-no-options.d time-cond.d          \
-  tls-max.d                                                             \
-  tlsauthtype.d tlspassword.d tlsuser.d tlsv1.0.d tlsv1.1.d tlsv1.2.d   \
-  tlsv1.3.d tlsv1.d trace-ascii.d trace.d trace-time.d tr-encoding.d    \
-  unix-socket.d upload-file.d url.d use-ascii.d user-agent.d user.d     \
-  verbose.d version.d write-out.d xattr.d request-target.d              \
-  styled-output.d tls13-ciphers.d proxy-tls13-ciphers.d                 \
-  disallow-username-in-url.d haproxy-protocol.d
+DPAGES =                                       \
+  abstract-unix-socket.d                       \
+  anyauth.d                                    \
+  append.d basic.d                             \
+  cacert.d capath.d                            \
+  cert-status.d                                        \
+  cert-type.d                                  \
+  cert.d                                       \
+  ciphers.d                                    \
+  compressed-ssh.d                             \
+  compressed.d                                 \
+  config.d                                     \
+  connect-timeout.d                            \
+  connect-to.d                                 \
+  continue-at.d                                        \
+  cookie-jar.d                                 \
+  cookie.d                                     \
+  create-dirs.d                                        \
+  crlf.d crlfile.d                             \
+  data-ascii.d                                 \
+  data-binary.d                                        \
+  data-urlencode.d                             \
+  data.d data-raw.d                            \
+  delegation.d                                 \
+  digest.d                                     \
+  disable-eprt.d                               \
+  disable-epsv.d                               \
+  disable.d                                    \
+  disallow-username-in-url.d                   \
+  dns-interface.d                              \
+  dns-ipv4-addr.d                              \
+  dns-ipv6-addr.d                              \
+  dns-servers.d                                        \
+  doh-url.d                                    \
+  dump-header.d                                        \
+  egd-file.d                                   \
+  engine.d                                     \
+  expect100-timeout.d                          \
+  fail-early.d                                 \
+  fail.d                                       \
+  false-start.d                                        \
+  form-string.d                                        \
+  form.d                                       \
+  ftp-account.d                                        \
+  ftp-alternative-to-user.d                    \
+  ftp-create-dirs.d                            \
+  ftp-method.d                                 \
+  ftp-pasv.d                                   \
+  ftp-port.d                                   \
+  ftp-pret.d                                   \
+  ftp-skip-pasv-ip.d                           \
+  ftp-ssl-ccc-mode.d                           \
+  ftp-ssl-ccc.d                                        \
+  ftp-ssl-control.d                            \
+  get.d globoff.d                              \
+  happy-eyeballs-timeout-ms.d                  \
+  haproxy-protocol.d                           \
+  head.d header.d                              \
+  help.d                                       \
+  hostpubmd5.d                                 \
+  http0.9.d                                    \
+  http1.0.d                                    \
+  http1.1.d http2.d                            \
+  http2-prior-knowledge.d                      \
+  ignore-content-length.d                      \
+  include.d                                    \
+  insecure.d                                   \
+  interface.d                                  \
+  ipv4.d ipv6.d                                        \
+  junk-session-cookies.d                       \
+  keepalive-time.d                             \
+  key.d key-type.d                             \
+  krb.d libcurl.d                              \
+  limit-rate.d                                 \
+  list-only.d                                  \
+  local-port.d                                 \
+  location-trusted.d                           \
+  location.d                                   \
+  login-options.d                              \
+  mail-auth.d                                  \
+  mail-from.d                                  \
+  mail-rcpt.d                                  \
+  manual.d                                     \
+  max-filesize.d                               \
+  max-redirs.d                                 \
+  max-time.d                                   \
+  metalink.d                                   \
+  negotiate.d                                  \
+  netrc-file.d                                 \
+  netrc-optional.d                             \
+  netrc.d                                      \
+  next.d no-alpn.d                             \
+  no-buffer.d                                  \
+  no-keepalive.d                               \
+  no-npn.d                                     \
+  no-sessionid.d                               \
+  noproxy.d                                    \
+  ntlm.d ntlm-wb.d                             \
+  oauth2-bearer.d                              \
+  output.d pass.d                              \
+  path-as-is.d                                 \
+  pinnedpubkey.d                               \
+  post301.d                                    \
+  post302.d                                    \
+  post303.d                                    \
+  preproxy.d                                   \
+  progress-bar.d                               \
+  proto-default.d                              \
+  proto-redir.d                                        \
+  proto.d                                      \
+  proxy-anyauth.d                              \
+  proxy-basic.d                                        \
+  proxy-cacert.d                               \
+  proxy-capath.d                               \
+  proxy-cert-type.d                            \
+  proxy-cert.d                                 \
+  proxy-ciphers.d                              \
+  proxy-crlfile.d                              \
+  proxy-digest.d                               \
+  proxy-header.d                               \
+  proxy-insecure.d                             \
+  proxy-key-type.d                             \
+  proxy-key.d                                  \
+  proxy-negotiate.d                            \
+  proxy-ntlm.d                                 \
+  proxy-pass.d                                 \
+  proxy-pinnedpubkey.d                         \
+  proxy-service-name.d                         \
+  proxy-ssl-allow-beast.d                      \
+  proxy-tls13-ciphers.d                                \
+  proxy-tlsauthtype.d                          \
+  proxy-tlspassword.d                          \
+  proxy-tlsuser.d                              \
+  proxy-tlsv1.d                                        \
+  proxy-user.d                                 \
+  proxy.d                                      \
+  proxy1.0.d                                   \
+  proxytunnel.d                                        \
+  pubkey.d quote.d                             \
+  random-file.d                                        \
+  range.d raw.d                                        \
+  referer.d                                    \
+  remote-header-name.d                         \
+  remote-name-all.d                            \
+  remote-name.d                                        \
+  remote-time.d                                        \
+  request-target.d                             \
+  request.d                                    \
+  resolve.d                                    \
+  retry-connrefused.d                          \
+  retry-delay.d                                        \
+  retry-max-time.d                             \
+  retry.d                                      \
+  sasl-ir.d                                    \
+  service-name.d                               \
+  show-error.d                                 \
+  silent.d                                     \
+  socks4.d socks5.d                            \
+  socks4a.d                                    \
+  socks5-basic.d                               \
+  socks5-gssapi-nec.d                          \
+  socks5-gssapi-service.d                      \
+  socks5-gssapi.d                              \
+  socks5-hostname.d                            \
+  speed-limit.d                                        \
+  speed-time.d                                 \
+  ssl-allow-beast.d                            \
+  ssl-no-revoke.d                              \
+  ssl-reqd.d                                   \
+  ssl.d                                                \
+  sslv2.d sslv3.d                              \
+  stderr.d                                     \
+  styled-output.d                              \
+  suppress-connect-headers.d                   \
+  tcp-fastopen.d                               \
+  tcp-nodelay.d                                        \
+  telnet-option.d                              \
+  tftp-blksize.d                               \
+  tftp-no-options.d                            \
+  time-cond.d                                  \
+  tls-max.d                                    \
+  tls13-ciphers.d                              \
+  tlsauthtype.d                                        \
+  tlspassword.d                                        \
+  tlsuser.d                                    \
+  tlsv1.0.d                                    \
+  tlsv1.1.d                                    \
+  tlsv1.2.d                                    \
+  tlsv1.3.d tlsv1.d                            \
+  tr-encoding.d                                        \
+  trace-ascii.d                                        \
+  trace-time.d                                 \
+  trace.d                                      \
+  unix-socket.d                                        \
+  upload-file.d                                        \
+  url.d use-ascii.d                            \
+  user-agent.d                                 \
+  user.d verbose.d                             \
+  version.d                                    \
+  write-out.d                                  \
+  xattr.d
 
 OTHERPAGES = page-footer page-header
diff --git a/docs/cmdline-opts/http0.9.d b/docs/cmdline-opts/http0.9.d
new file mode 100644 (file)
index 0000000..33fe72d
--- /dev/null
@@ -0,0 +1,14 @@
+Long: http0.9
+Tags: Versions
+Protocols: HTTP
+Added:
+Help: Allow HTTP 0.9 responses
+---
+Tells curl to be fine with HTTP version 0.9 response.
+
+HTTP/0.9 is a completely headerless response and therefore you can also
+connect with this to non-HTTP servers and still get a response since curl will
+simply transparently downgrade - if allowed.
+
+A future curl version will deny continuing if the response isn't at least
+HTTP/1.0 unless this option is used.
index 1bec4c14dd5f03f08225a385f9a09ff2d0a723cf..6d63912d76e6dcb73a102ebf1458e8cbe385829b 100644 (file)
@@ -319,6 +319,8 @@ Do an HTTP GET request. See \fICURLOPT_HTTPGET(3)\fP
 Set the request target. \fICURLOPT_REQUEST_TARGET(3)\fP
 .IP CURLOPT_HTTP_VERSION
 HTTP version to use. \fICURLOPT_HTTP_VERSION(3)\fP
+.IP CURLOPT_HTTP09_ALLOWED
+Allow HTTP/0.9 responses. \fICURLOPT_HTTP09_ALLOWED(3)\fP
 .IP CURLOPT_IGNORE_CONTENT_LENGTH
 Ignore Content-Length. See \fICURLOPT_IGNORE_CONTENT_LENGTH(3)\fP
 .IP CURLOPT_HTTP_CONTENT_DECODING
diff --git a/docs/libcurl/opts/CURLOPT_HTTP09_ALLOWED.3 b/docs/libcurl/opts/CURLOPT_HTTP09_ALLOWED.3
new file mode 100644 (file)
index 0000000..3fa4499
--- /dev/null
@@ -0,0 +1,58 @@
+.\" **************************************************************************
+.\" *                                  _   _ ____  _
+.\" *  Project                     ___| | | |  _ \| |
+.\" *                             / __| | | | |_) | |
+.\" *                            | (__| |_| |  _ <| |___
+.\" *                             \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" *
+.\" * This software is licensed as described in the file COPYING, which
+.\" * you should have received as part of this distribution. The terms
+.\" * are also available at https://curl.haxx.se/docs/copyright.html.
+.\" *
+.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+.\" * copies of the Software, and permit persons to whom the Software is
+.\" * furnished to do so, under the terms of the COPYING file.
+.\" *
+.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+.\" * KIND, either express or implied.
+.\" *
+.\" **************************************************************************
+.\"
+.TH CURLOPT_HTTP09_ALLOWED 3 "17 Dec 2018" "libcurl 7.64.0" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_HTTP09 \- allow HTTP/0.9 response
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_HTTP09_ALLOWED, long allowed);
+.SH DESCRIPTION
+Pass the long argument \fIallowed\fP set to 1L to allow HTTP/0.9 responses.
+
+A HTTP/0.9 response is a server response entirely without headers and only a
+body, while you can connect to lots of random TCP services and still get a
+response that curl might consider to be HTTP/0.9.
+.SH DEFAULT
+curl allows HTTP/0.9 responses by default.
+
+A future curl version will require this option to be set to allow HTTP/0.9
+responses.
+.SH PROTOCOLS
+HTTP
+.SH EXAMPLE
+.nf
+CURL *curl = curl_easy_init();
+if(curl) {
+  CURLcode ret;
+  curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/");
+  curl_easy_setopt(curl, CURLOPT_HTTP09_ALLOWED, 1L);
+  ret = curl_easy_perform(curl);
+}
+.fi
+.SH AVAILABILITY
+Option added in 7.64.0, present along with HTTP.
+.SH RETURN VALUE
+Returns CURLE_OK if HTTP is supported, and CURLE_UNKNOWN_OPTION if not.
+.SH "SEE ALSO"
+.BR CURLOPT_SSLVERSION "(3), " CURLOPT_HTTP_VERSION "(3), "
index 060db75783de86b2edcceae798ae590a84e04ceb..7b7a0814470810ad0673adaa32ede0e159163621 100644 (file)
@@ -84,3 +84,4 @@ Along with HTTP
 Returns CURLE_OK if HTTP is supported, and CURLE_UNKNOWN_OPTION if not.
 .SH "SEE ALSO"
 .BR CURLOPT_SSLVERSION "(3), " CURLOPT_HTTP200ALIASES "(3), "
+.BR CURLOPT_HTTP09_ALLOWED "(3), "
index 9bfd555f1fc661ef034bb62dcebd32e0f4cf1b46..b21f32356c79338cb96a2e69d40453cc15653745 100644 (file)
@@ -154,6 +154,7 @@ man_MANS =                                      \
   CURLOPT_HEADERDATA.3                          \
   CURLOPT_HEADERFUNCTION.3                      \
   CURLOPT_HEADEROPT.3                           \
+  CURLOPT_HTTP09_ALLOWED.3                      \
   CURLOPT_HTTP200ALIASES.3                      \
   CURLOPT_HTTPAUTH.3                            \
   CURLOPT_HTTPGET.3                             \
@@ -163,9 +164,9 @@ man_MANS =                                      \
   CURLOPT_HTTP_CONTENT_DECODING.3               \
   CURLOPT_HTTP_TRANSFER_DECODING.3              \
   CURLOPT_HTTP_VERSION.3                        \
-  CURLOPT_TRAILERFUNCTION.3                     \
-  CURLOPT_TRAILERDATA.3                         \
   CURLOPT_IGNORE_CONTENT_LENGTH.3               \
+  CURLOPT_TRAILERDATA.3                         \
+  CURLOPT_TRAILERFUNCTION.3                     \
   CURLOPT_INFILESIZE.3                          \
   CURLOPT_INFILESIZE_LARGE.3                    \
   CURLOPT_INTERFACE.3                           \
index 8659346ce74e5c03afdea96139e2a1297ef1c499..f25009c2c3bdd7a4e3b82968cd43a866f0e21c83 100644 (file)
@@ -421,6 +421,7 @@ CURLOPT_HEADER                  7.1
 CURLOPT_HEADERDATA              7.10
 CURLOPT_HEADERFUNCTION          7.7.2
 CURLOPT_HEADEROPT               7.37.0
+CURLOPT_HTTP09_ALLOWED          7.64.0
 CURLOPT_HTTP200ALIASES          7.10.3
 CURLOPT_HTTPAUTH                7.10.6
 CURLOPT_HTTPGET                 7.8.1
index bd61838384a40d25bbb722f3b98c5e9aaadf6806..88e1f39e878e6a386d6f2eef7b7f243392d4943c 100644 (file)
@@ -1891,6 +1891,9 @@ typedef enum {
   /* pointer to be passed to HTTP_TRAILER_FUNCTION */
   CINIT(TRAILERDATA, OBJECTPOINT, 284),
 
+  /* set this to 1L to allow HTTP/0.9 responses or 0L to disallow */
+  CINIT(HTTP09_ALLOWED, LONG, 285),
+
   CURLOPT_LASTENTRY /* the last unused */
 } CURLoption;
 
index 07665743c8d95459b9af94b293bb32fe0935a4a8..8866fdf0a7883399bfa994f6e50aabced4378ca1 100644 (file)
@@ -3221,6 +3221,10 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
           k->header = FALSE;
           k->badheader = HEADER_ALLBAD;
           streamclose(conn, "bad HTTP: No end-of-message indicator");
+          if(!data->set.http09_allowed) {
+            failf(data, "Received HTTP/0.9 when not allowed\n");
+            return CURLE_UNSUPPORTED_PROTOCOL;
+          }
           break;
         }
       }
@@ -3254,6 +3258,10 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
       if(st == STATUS_BAD) {
         streamclose(conn, "bad HTTP: No end-of-message indicator");
         /* this is not the beginning of a protocol first header line */
+        if(!data->set.http09_allowed) {
+          failf(data, "Received HTTP/0.9 when not allowed\n");
+          return CURLE_UNSUPPORTED_PROTOCOL;
+        }
         k->header = FALSE;
         if(*nread)
           /* since there's more, this is a partial bad header */
index 27046768cf4532ea750c33b6edd63b7ae2049444..992bcf915c229896e0d16dd5d83a91973b54b002 100644 (file)
@@ -860,6 +860,12 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
     data->set.expect_100_timeout = arg;
     break;
 
+  case CURLOPT_HTTP09_ALLOWED:
+    arg = va_arg(param, unsigned long);
+    if(arg > 1L)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.http09_allowed = arg ? TRUE : FALSE;
+    break;
 #endif   /* CURL_DISABLE_HTTP */
 
   case CURLOPT_HTTPAUTH:
index 7839dfa7ce56fd0def123e9bc129a997e543f9f8..5cd286650da1a9e90538d5fb0f0880f7279cef3c 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -536,6 +536,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
   set->fnmatch = ZERO_NULL;
   set->upkeep_interval_ms = CURL_UPKEEP_INTERVAL_DEFAULT;
   set->maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */
+  set->http09_allowed = TRUE;
   set->httpversion =
 #ifdef USE_NGHTTP2
     CURL_HTTP_VERSION_2TLS
index b9658162c558c740718c5570398440ee993f14b8..a2655e9e02054cc44b236f4f2e1ba46137e75f30 100644 (file)
@@ -1743,6 +1743,7 @@ struct UserDefined {
   long upkeep_interval_ms;      /* Time between calls for connection upkeep. */
   bool doh; /* DNS-over-HTTPS enabled */
   bool doh_get; /* use GET for DoH requests, instead of POST */
+  bool http09_allowed; /* allow HTTP/0.9 responses */
   multidone_func fmultidone;
   struct Curl_easy *dohfor; /* this is a DoH request for that transfer */
   CURLU *uh; /* URL handle for the current parsed URL */
index 7d088ae0fb042724f45b585bcd1129da7d5faa59..0eb941ef6eb51711686491422e757c4c6199e43b 100644 (file)
@@ -43,6 +43,7 @@ void config_init(struct OperationConfig* config)
   config->proto_default = NULL;
   config->tcp_nodelay = TRUE; /* enabled by default */
   config->happy_eyeballs_timeout_ms = CURL_HET_DEFAULT;
+  config->http09_allowed = TRUE;
 }
 
 static void free_config_fields(struct OperationConfig *config)
index 501c961891aa2ecd6671b6dea0e5c09336e0cbd8..81680dbbbd278c2f20ad769dee91733c8e790031 100644 (file)
@@ -146,6 +146,7 @@ struct OperationConfig {
   char *krblevel;
   char *request_target;
   long httpversion;
+  bool http09_allowed;
   bool nobuffer;
   bool readbusy;            /* set when reading input returns EAGAIN */
   bool globoff;
index c0d3a84f236dd75f70a3b65d1146bc4599264fa5..c7ba5f243b0b59a767bc35b3de14fc89658252d9 100644 (file)
@@ -199,6 +199,7 @@ static const struct LongShort aliases[]= {
   {"01",  "http1.1",                 ARG_NONE},
   {"02",  "http2",                   ARG_NONE},
   {"03",  "http2-prior-knowledge",   ARG_NONE},
+  {"09",  "http0.9",                 ARG_BOOL},
   {"1",  "tlsv1",                    ARG_NONE},
   {"10",  "tlsv1.0",                 ARG_NONE},
   {"11",  "tlsv1.1",                 ARG_NONE},
@@ -1183,6 +1184,10 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
         /* HTTP version 2.0 over clean TCP*/
         config->httpversion = CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE;
         break;
+      case '9':
+        /* Allow HTTP/0.9 responses! */
+        config->http09_allowed = toggle;
+        break;
       }
       break;
     case '1': /* --tlsv1* options */
index 484c5219c20e6f53dbbe71cf64b11bed926819c5..92cb6ca05eca8adb174249c9facc5172348b1875 100644 (file)
@@ -176,6 +176,8 @@ static const struct helptxt helptext[] = {
    "This help text"},
   {"    --hostpubmd5 <md5>",
    "Acceptable MD5 hash of the host public key"},
+  {"    --http0.9",
+   "Allow HTTP 0.9 responses"},
   {"-0, --http1.0",
    "Use HTTP 1.0"},
   {"    --http1.1",
index 429e9cf469e367994252e0e878f116660eb1dd2a..7161714d61ad470ce5411e65453f8f3b3b1da6bf 100644 (file)
@@ -1005,6 +1005,8 @@ static CURLcode operate_do(struct GlobalConfig *global,
           /* new in libcurl 7.21.6 */
           if(config->tr_encoding)
             my_setopt(curl, CURLOPT_TRANSFER_ENCODING, 1L);
+          /* new in libcurl 7.64.0 */
+          my_setopt(curl, CURLOPT_HTTP09_ALLOWED, config->http09_allowed);
 
         } /* (built_in_protos & CURLPROTO_HTTP) */
 
index 52916c98344a738d609aaada543b9951741207c4..9c31d907eb92ec8c3d358c0ccb2a41b6213a8c25 100644 (file)
@@ -130,7 +130,8 @@ test1144 test1145 test1146 test1147 test1148 test1149 test1150 test1151 \
 test1152 test1153 test1154 test1155 test1156 test1157 test1158 test1159 \
 \
 test1160 test1161 test1162 test1163 test1164 \
-test1170 test1171 \
+test1170 test1171 test1172 \
+\
 test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 \
 test1208 test1209 test1210 test1211 test1212 test1213 test1214 test1215 \
 test1216 test1217 test1218 test1219 \
index 3fb90936a032980e1ca97a9fb56526bc250b1e7b..84c22dba24f304cedf88df6115a1ac480a1d9f36 100644 (file)
@@ -3,6 +3,7 @@
 <keywords>
 HTTP
 HTTP HEAD
+HTTP/0.9
 </keywords>
 </info>
 
@@ -46,7 +47,7 @@ http
 HTTP HEAD, receive no headers only body
  </name>
  <command>
--I http://%HOSTIP:%HTTPPORT/1144
+-I http://%HOSTIP:%HTTPPORT/1144 --http0.9
 </command>
 </client>
 
index be83aa4f320ec88a2aac70eeba4e983eebbcba28..a5ce6d11a79ce2340a013855f699941478b557cc 100644 (file)
@@ -29,7 +29,7 @@ http
 HTTP/0.9 GET and all zeroes
  </name>
  <command option="force-output">
-http://%HOSTIP:%HTTPPORT/1164 -w '%{size_download}\n'
+http://%HOSTIP:%HTTPPORT/1164 -w '%{size_download}\n' --http0.9
 </command>
 </client>
 
diff --git a/tests/data/test1172 b/tests/data/test1172
new file mode 100644 (file)
index 0000000..6e61720
--- /dev/null
@@ -0,0 +1,50 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP/0.9
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data>
+-foo- swsclose
+</data>
+<datacheck>
+</datacheck>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+ <name>
+HTTP/0.9 GET response denied
+ </name>
+ <command>
+http://%HOSTIP:%HTTPPORT/1172 --no-http0.9
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET /1172 HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+Accept: */*\r
+\r
+</protocol>
+# unsupported protocol
+<errorcode>
+1
+</errorcode>
+</verify>
+</testcase>
index 75ed7bdc952c04a54c787f64f40ff84e499236c2..cab11efa085a01ca150c600ba171a95322cd0f8c 100644 (file)
@@ -26,7 +26,7 @@ http
 HTTP GET with a single-byte HTTP/0.9 response
  </name>
  <command>
-http://%HOSTIP:%HTTPPORT/1266
+http://%HOSTIP:%HTTPPORT/1266 --http0.9
 </command>
 </client>
 
index 8f2a63b7846805e3ed4d0fd33c6cf9dfa398ec24..82d37445d41ecf68db429a5d226500dd57a65185 100644 (file)
@@ -26,7 +26,7 @@ http
 HTTP GET with a invalid HTTP/1 response line start
  </name>
  <command>
-http://%HOSTIP:%HTTPPORT/1267
+http://%HOSTIP:%HTTPPORT/1267 --http0.9
 </command>
 </client>
 
index 10faef39b9a49451d6cc0fafda13e0f11e6e8912..36ddd0e9102f9da6478dd30e5440e5639448d7b4 100644 (file)
@@ -54,6 +54,7 @@ s/(USERAGENT, \")[^\"]+/${1}stripped/
 $_ = '' if /CURLOPT_SSL_VERIFYPEER/
 $_ = '' if /CURLOPT_SSH_KNOWNHOSTS/
 $_ = '' if /CURLOPT_HTTP_VERSION/
+$_ = '' if /CURLOPT_HTTP09_ALLOWED/
 </stripfile>
 <file name="log/test1400.c" mode="text">
 /********* Sample code generated by the curl command line tool **********
index f330931c94754f28e146301873cd237315cacf80..d7033e0b55a3f31abd51c46254a0741ed55440a3 100644 (file)
@@ -87,6 +87,7 @@ int main(int argc, char *argv[])
   curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, slist1);
   curl_easy_setopt(hnd, CURLOPT_USERAGENT, "MyUA");
   curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L);
+  curl_easy_setopt(hnd, CURLOPT_HTTP09_ALLOWED, 1L);
   curl_easy_setopt(hnd, CURLOPT_COOKIE, "chocolate=chip");
   curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
   curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
index 9a9428376a55418a53d9dc8d902d2213e7e6bffc..978b2616204532019cca2a32bd7545858a39629f 100644 (file)
@@ -79,6 +79,7 @@ int main(int argc, char *argv[])
   curl_easy_setopt(hnd, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)16);
   curl_easy_setopt(hnd, CURLOPT_USERAGENT, "stripped");
   curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L);
+  curl_easy_setopt(hnd, CURLOPT_HTTP09_ALLOWED, 1L);
   curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
   curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
 
index 79cdf4964a7e3686b11b343a46511cc4f69c49ae..9c838d0ed6adb821c766f6cfbf14fca7d6eb8c05 100644 (file)
@@ -74,6 +74,7 @@ int main(int argc, char *argv[])
   curl_easy_setopt(hnd, CURLOPT_URL, "http://%HOSTIP:%HTTPPORT/we/want/1403?foo=bar&baz=quux");
   curl_easy_setopt(hnd, CURLOPT_USERAGENT, "stripped");
   curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L);
+  curl_easy_setopt(hnd, CURLOPT_HTTP09_ALLOWED, 1L);
   curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
   curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
 
index 9c6f2e726a0a645ff40219b685b0d9e1baf347fd..a00bf10a341f722087dcbec272e715b13d686f90 100644 (file)
@@ -143,6 +143,7 @@ int main(int argc, char *argv[])
   curl_easy_setopt(hnd, CURLOPT_MIMEPOST, mime1);
   curl_easy_setopt(hnd, CURLOPT_USERAGENT, "stripped");
   curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L);
+  curl_easy_setopt(hnd, CURLOPT_HTTP09_ALLOWED, 1L);
   curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
   curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
 
index 73769eed1a40c6b76fc8fc4f767ddff0376b1e16..4f477c7d995fb1f0bb76361339660a4463f92743 100644 (file)
@@ -136,6 +136,7 @@ $_ = '' if /CURLOPT_MAXREDIRS/
 $_ = '' if /CURLOPT_SSL_VERIFYPEER/
 $_ = '' if /CURLOPT_SSH_KNOWNHOSTS/
 $_ = '' if /CURLOPT_HTTP_VERSION/
+$_ = '' if /CURLOPT_HTTP09_ALLOWED/
 </stripfile>
 </verify>
 </testcase>
index 796dd22548c53111eb41965f652f98269c48026e..7d973e7ef65922148d3af7f91631781e8359c4c1 100644 (file)
@@ -122,6 +122,7 @@ $_ = '' if /CURLOPT_MAXREDIRS/
 $_ = '' if /CURLOPT_SSL_VERIFYPEER/
 $_ = '' if /CURLOPT_SSH_KNOWNHOSTS/
 $_ = '' if /CURLOPT_HTTP_VERSION/
+$_ = '' if /CURLOPT_HTTP09_ALLOWED/
 </stripfile>
 </verify>
 </testcase>
index 9800eeef37cccabf204f553fa3540ec01e2f71b6..883cf40640b6d9e533c209ff64ef78e980787315 100644 (file)
@@ -100,6 +100,7 @@ $_ = '' if /CURLOPT_MAXREDIRS/
 $_ = '' if /CURLOPT_SSL_VERIFYPEER/
 $_ = '' if /CURLOPT_SSH_KNOWNHOSTS/
 $_ = '' if /CURLOPT_HTTP_VERSION/
+$_ = '' if /CURLOPT_HTTP09_ALLOWED/
 </stripfile>
 </verify>
 </testcase>
index 081ac6bbb6b1dbb54de6944b34e7b0fdec52d751..c3d31f349ef3dc4f9b5153558fba4122666db682 100644 (file)
@@ -66,6 +66,7 @@ int main(int argc, char *argv[])
   curl_easy_setopt(hnd, CURLOPT_BUFFERSIZE, 102400L);
   curl_easy_setopt(hnd, CURLOPT_URL, "imap://%HOSTIP:%IMAPPORT/1420/;MAILINDEX=1");
   curl_easy_setopt(hnd, CURLOPT_USERPWD, "user:secret");
+  curl_easy_setopt(hnd, CURLOPT_HTTP09_ALLOWED, 1L);
   curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
   curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
 
index 114dc0dba984676c47fdcc658211eacf0adeb9af..20b031a1e314a27a0db5afb29d3d9a203db3bf2d 100644 (file)
@@ -3,6 +3,7 @@
 <keywords>
 HTTP
 HTTP GET
+HTTP/0.9
 </keywords>
 </info>
 
@@ -34,7 +35,7 @@ http
 HTTP GET with 4-digit response code
  </name>
  <command>
-http://%HOSTIP:%HTTPPORT/1429 --write-out '%{response_code}'
+http://%HOSTIP:%HTTPPORT/1429 --write-out '%{response_code}' --http0.9
 </command>
 </client>
 
index 95d4cef35616fbf51131b78d9b2ae0379897f027..17306f949b5a0c76dc1ff0952526034451746eee 100644 (file)
@@ -45,7 +45,7 @@ https
 HTTPS GET, receive no headers only data!
  </name>
  <command>
--k https://%HOSTIP:%HTTPSPORT/306
+-k https://%HOSTIP:%HTTPSPORT/306 --http0.9
 </command>
 </client>
 
index a018d8fd41de881bf29ab5a9edf105eba8e116a1..7b9af29538b650a741c9edc8da18141a6ab1dc94 100644 (file)
@@ -3,6 +3,7 @@
 <keywords>
 HTTP
 HTTP GET
+HTTP/0.9
 </keywords>
 </info>
 # Server-side
@@ -21,7 +22,7 @@ http
 HTTP GET without headers in the response
  </name>
  <command>
-http://%HOSTIP:%HTTPPORT/66
+http://%HOSTIP:%HTTPPORT/66 --http0.9
 </command>
 </client>