为什么 cURL 不读取完整的@file 并设置 Content-Length: 8186?
why is cURL not reading full @file and setting Content-Length: 8186?
我在 Windows 7 上使用 cURL 来测试 RESTful API.
我的数据在一个 JSON 文件中,该文件的长度为 16,987 个字符。
当我不设置内容长度时,cURL 假定 Content-Length: 8186
并且不发送整个 JSON 负载。我从服务器得到 Unexpected end-of-input
。
当我设置 -H "Content-Length: 17000"
时,cURL 似乎在没有正确构建请求 body(或其他)的情况下发送前 8186 个字节...服务器花了一些时间考虑这个问题,最后给出 400 Bad Request
.
没有明确的内容类型header:
C:\...>curl -v -X POST -H "Content-Type: application/json" -H "Expect:" -H "Authorization=Bearer ...etc..." --data @quotedGood.json https://web.domain.com/NewApp/rest/invoice/
Note: Unnecessary use of -X or --request, POST is already inferred.
* STATE: INIT => CONNECT handle 0x60006a600; line 1103 (connection #-5000)
* Added connection 0. The cache now contains 1 members
* Trying 192.168.0.0...
* STATE: CONNECT => WAITCONNECT handle 0x60006a600; line 1156 (connection #0)
* Connected to web.domain.com (192.168.0.0) port 443 (#0)
* STATE: WAITCONNECT => SENDPROTOCONNECT handle 0x60006a600; line 1253 (connection #0)
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: /usr/ssl/certs/ca-bundle.crt
CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* STATE: SENDPROTOCONNECT => PROTOCONNECT handle 0x60006a600; line 1267 (connection #0)
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: C=CA; ST=prov; L=town; O=Company; CN=*.domain.com
* start date: Mar 5 17:57:58 2015 GMT
* expire date: Nov 10 23:57:20 2018 GMT
* subjectAltName: web.domain.com matched
* issuer: C=US; O=Entrust, Inc.; OU=...etc...
* SSL certificate verify ok.
* STATE: PROTOCONNECT => DO handle 0x60006a600; line 1288 (connection #0)
> POST /NewApp/rest/invoice/ HTTP/1.1
> Host: web.domain.com
> User-Agent: curl/7.47.1
> Accept: */*
> Content-Type: application/json
> Content-Length: 8186
>
* upload completely sent off: 8186 out of 8186 bytes
* STATE: DO => DO_DONE handle 0x60006a600; line 1350 (connection #0)
* STATE: DO_DONE => WAITPERFORM handle 0x60006a600; line 1477 (connection #0)
* STATE: WAITPERFORM => PERFORM handle 0x60006a600; line 1487 (connection #0)
* HTTP 1.1 or later with persistent connection, pipelining supported
< HTTP/1.1 400 Bad Request
< Date: Mon, 05 Mar 2018 21:37:26 GMT
< Content-Type: application/json
< Set-Cookie: SERVERID=web8; path=/; HttpOnly; Secure
< Connection: close
< Transfer-Encoding: chunked
< X-Frame-Options: DENY
< Strict-Transport-Security: max-age=31536000; includeSubDomains
<
* STATE: PERFORM => DONE handle 0x60006a600; line 1645 (connection #0)
* Curl_done
* Closing connection 0
* The cache now contains 0 members
* TLSv1.2 (OUT), TLS alert, Client hello (1):
* Expire cleared
{"summary":"There was a problem with your invoice request. If you require technical assistance, please note the following identifier [NEWAPP-EX-646744087] to help trace the issue.","timestamp":"2018-03-05 16:37:26.105","errorMsgs":["Unexpected end-of-input in field name\n at [Source: org.jboss.resteasy.core.interception.MessageBodyReaderContextImpl$InputStreamWrapper@74d44e80; line: 245, column: 205]"]}
具有明确的内容长度。注意与上面 * upload completely sent off: 8186 out of 8186 bytes
相同的日志,即使 Content-Length 是 17000...让我觉得 cURL 没有读取整个文件:
C:\...>curl -v -X POST -H "Content-Type: application/json" -H "Content-Length: 17000" -H "Expect:" -H "Authorization=Bearer ...etc..." --data @quotedGood.json https://web.domain.com/NewApp/rest/invoice/
Note: Unnecessary use of -X or --request, POST is already inferred.
* STATE: INIT => CONNECT handle 0x60006a690; line 1103 (connection #-5000)
* Added connection 0. The cache now contains 1 members
* Trying 192.168.0.0...
* STATE: CONNECT => WAITCONNECT handle 0x60006a690; line 1156 (connection #0)
* Connected to web.domain.com (192.168.0.0) port 443 (#0)
* STATE: WAITCONNECT => SENDPROTOCONNECT handle 0x60006a690; line 1253 (connection #0)
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: /usr/ssl/certs/ca-bundle.crt
CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* STATE: SENDPROTOCONNECT => PROTOCONNECT handle 0x60006a690; line 1267 (connection #0)
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: C=CA; ST=prov; L=town; O=Company; CN=*.domain.com
* start date: Mar 5 17:57:58 2015 GMT
* expire date: Nov 10 23:57:20 2018 GMT
* subjectAltName: web.domain.com matched
* issuer: C=US; O=Entrust, Inc.; OU=...etc...
* SSL certificate verify ok.
* STATE: PROTOCONNECT => DO handle 0x60006a690; line 1288 (connection #0)
> POST /NewApp/rest/invoice/ HTTP/1.1
> Host: web.domain.com
> User-Agent: curl/7.47.1
> Accept: */*
> Content-Type: application/json
> Content-Length: 17000
>
* upload completely sent off: 8186 out of 8186 bytes
* STATE: DO => DO_DONE handle 0x60006a690; line 1350 (connection #0)
* STATE: DO_DONE => WAITPERFORM handle 0x60006a690; line 1477 (connection #0)
* STATE: WAITPERFORM => PERFORM handle 0x60006a690; line 1487 (connection #0)
* HTTP 1.1 or later with persistent connection, pipelining supported
< HTTP/1.1 400 Bad Request
< Date: Mon, 05 Mar 2018 21:48:11 GMT
< Content-Length: 226
< Connection: close
< Content-Type: text/html; charset=iso-8859-1
< X-Frame-Options: DENY
< Strict-Transport-Security: max-age=31536000; includeSubDomains
<
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
</body></html>
* STATE: PERFORM => DONE handle 0x60006a690; line 1645 (connection #0)
* Curl_done
* Closing connection 0
* The cache now contains 0 members
* TLSv1.2 (OUT), TLS alert, Client hello (1):
您的 Content-Length
header 被 Transfer-Encoding
header 忽略。
根据 docs 你可以试试 -H "Transfer-Encoding: identity"
这是我在 Windows 7
上的 cmd 提示符下终于让它工作时的结果
curl --request POST ^
--url http://127.0.0.1:8080/MyApp/rest/invoice ^
--header "Content-Type:application/json" ^
--header "Authorization: some-proprietary-auth-code" ^
--header "Content-Length:9905" --header "Expect:" ^
--data-binary "@.\compressedGood.json"
compressedGood.json
是一个包含未转义双引号字段且所有空格和 eol
都已删除的文件。喜欢:
{"externalId":null,"companyName":ACME,"companyProvince":ON,"salesFirstName":null,"salesLastName":null,"products":[ {"name":"Name of Product", ... etc ... } ] }
我在 Windows 7 上使用 cURL 来测试 RESTful API.
我的数据在一个 JSON 文件中,该文件的长度为 16,987 个字符。
当我不设置内容长度时,cURL 假定 Content-Length: 8186
并且不发送整个 JSON 负载。我从服务器得到 Unexpected end-of-input
。
当我设置 -H "Content-Length: 17000"
时,cURL 似乎在没有正确构建请求 body(或其他)的情况下发送前 8186 个字节...服务器花了一些时间考虑这个问题,最后给出 400 Bad Request
.
没有明确的内容类型header:
C:\...>curl -v -X POST -H "Content-Type: application/json" -H "Expect:" -H "Authorization=Bearer ...etc..." --data @quotedGood.json https://web.domain.com/NewApp/rest/invoice/
Note: Unnecessary use of -X or --request, POST is already inferred.
* STATE: INIT => CONNECT handle 0x60006a600; line 1103 (connection #-5000)
* Added connection 0. The cache now contains 1 members
* Trying 192.168.0.0...
* STATE: CONNECT => WAITCONNECT handle 0x60006a600; line 1156 (connection #0)
* Connected to web.domain.com (192.168.0.0) port 443 (#0)
* STATE: WAITCONNECT => SENDPROTOCONNECT handle 0x60006a600; line 1253 (connection #0)
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: /usr/ssl/certs/ca-bundle.crt
CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* STATE: SENDPROTOCONNECT => PROTOCONNECT handle 0x60006a600; line 1267 (connection #0)
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: C=CA; ST=prov; L=town; O=Company; CN=*.domain.com
* start date: Mar 5 17:57:58 2015 GMT
* expire date: Nov 10 23:57:20 2018 GMT
* subjectAltName: web.domain.com matched
* issuer: C=US; O=Entrust, Inc.; OU=...etc...
* SSL certificate verify ok.
* STATE: PROTOCONNECT => DO handle 0x60006a600; line 1288 (connection #0)
> POST /NewApp/rest/invoice/ HTTP/1.1
> Host: web.domain.com
> User-Agent: curl/7.47.1
> Accept: */*
> Content-Type: application/json
> Content-Length: 8186
>
* upload completely sent off: 8186 out of 8186 bytes
* STATE: DO => DO_DONE handle 0x60006a600; line 1350 (connection #0)
* STATE: DO_DONE => WAITPERFORM handle 0x60006a600; line 1477 (connection #0)
* STATE: WAITPERFORM => PERFORM handle 0x60006a600; line 1487 (connection #0)
* HTTP 1.1 or later with persistent connection, pipelining supported
< HTTP/1.1 400 Bad Request
< Date: Mon, 05 Mar 2018 21:37:26 GMT
< Content-Type: application/json
< Set-Cookie: SERVERID=web8; path=/; HttpOnly; Secure
< Connection: close
< Transfer-Encoding: chunked
< X-Frame-Options: DENY
< Strict-Transport-Security: max-age=31536000; includeSubDomains
<
* STATE: PERFORM => DONE handle 0x60006a600; line 1645 (connection #0)
* Curl_done
* Closing connection 0
* The cache now contains 0 members
* TLSv1.2 (OUT), TLS alert, Client hello (1):
* Expire cleared
{"summary":"There was a problem with your invoice request. If you require technical assistance, please note the following identifier [NEWAPP-EX-646744087] to help trace the issue.","timestamp":"2018-03-05 16:37:26.105","errorMsgs":["Unexpected end-of-input in field name\n at [Source: org.jboss.resteasy.core.interception.MessageBodyReaderContextImpl$InputStreamWrapper@74d44e80; line: 245, column: 205]"]}
具有明确的内容长度。注意与上面 * upload completely sent off: 8186 out of 8186 bytes
相同的日志,即使 Content-Length 是 17000...让我觉得 cURL 没有读取整个文件:
C:\...>curl -v -X POST -H "Content-Type: application/json" -H "Content-Length: 17000" -H "Expect:" -H "Authorization=Bearer ...etc..." --data @quotedGood.json https://web.domain.com/NewApp/rest/invoice/
Note: Unnecessary use of -X or --request, POST is already inferred.
* STATE: INIT => CONNECT handle 0x60006a690; line 1103 (connection #-5000)
* Added connection 0. The cache now contains 1 members
* Trying 192.168.0.0...
* STATE: CONNECT => WAITCONNECT handle 0x60006a690; line 1156 (connection #0)
* Connected to web.domain.com (192.168.0.0) port 443 (#0)
* STATE: WAITCONNECT => SENDPROTOCONNECT handle 0x60006a690; line 1253 (connection #0)
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: /usr/ssl/certs/ca-bundle.crt
CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* STATE: SENDPROTOCONNECT => PROTOCONNECT handle 0x60006a690; line 1267 (connection #0)
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: C=CA; ST=prov; L=town; O=Company; CN=*.domain.com
* start date: Mar 5 17:57:58 2015 GMT
* expire date: Nov 10 23:57:20 2018 GMT
* subjectAltName: web.domain.com matched
* issuer: C=US; O=Entrust, Inc.; OU=...etc...
* SSL certificate verify ok.
* STATE: PROTOCONNECT => DO handle 0x60006a690; line 1288 (connection #0)
> POST /NewApp/rest/invoice/ HTTP/1.1
> Host: web.domain.com
> User-Agent: curl/7.47.1
> Accept: */*
> Content-Type: application/json
> Content-Length: 17000
>
* upload completely sent off: 8186 out of 8186 bytes
* STATE: DO => DO_DONE handle 0x60006a690; line 1350 (connection #0)
* STATE: DO_DONE => WAITPERFORM handle 0x60006a690; line 1477 (connection #0)
* STATE: WAITPERFORM => PERFORM handle 0x60006a690; line 1487 (connection #0)
* HTTP 1.1 or later with persistent connection, pipelining supported
< HTTP/1.1 400 Bad Request
< Date: Mon, 05 Mar 2018 21:48:11 GMT
< Content-Length: 226
< Connection: close
< Content-Type: text/html; charset=iso-8859-1
< X-Frame-Options: DENY
< Strict-Transport-Security: max-age=31536000; includeSubDomains
<
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
</body></html>
* STATE: PERFORM => DONE handle 0x60006a690; line 1645 (connection #0)
* Curl_done
* Closing connection 0
* The cache now contains 0 members
* TLSv1.2 (OUT), TLS alert, Client hello (1):
您的 Content-Length
header 被 Transfer-Encoding
header 忽略。
根据 docs 你可以试试 -H "Transfer-Encoding: identity"
这是我在 Windows 7
上的 cmd 提示符下终于让它工作时的结果
curl --request POST ^
--url http://127.0.0.1:8080/MyApp/rest/invoice ^
--header "Content-Type:application/json" ^
--header "Authorization: some-proprietary-auth-code" ^
--header "Content-Length:9905" --header "Expect:" ^
--data-binary "@.\compressedGood.json"
compressedGood.json
是一个包含未转义双引号字段且所有空格和 eol
都已删除的文件。喜欢:
{"externalId":null,"companyName":ACME,"companyProvince":ON,"salesFirstName":null,"salesLastName":null,"products":[ {"name":"Name of Product", ... etc ... } ] }