我有一个套接字C语言程序,必须使用http2协议.它返回错误请求-HTTP错误400.请求的格式错误.
I have a C program of socket which has to use http2 protocol. It is returning Bad Request - HTTP Error 400. The request is badly formed.
最初,我通过curl 7.64发送了如下请求:
Initially, I sent a request like the following through curl 7.64:
curl -v -http2 -i mywebsite.xyz我得到以下输出:
* Expire in 0 ms for 6 (transfer 0x55cc25ec95c0) * Expire in 1 ms for 1 (transfer 0x55cc25ec95c0) * Expire in 0 ms for 1 (transfer 0x55cc25ec95c0) * Expire in 1 ms for 1 (transfer 0x55cc25ec95c0) * Expire in 0 ms for 1 (transfer 0x55cc25ec95c0) * Expire in 0 ms for 1 (transfer 0x55cc25ec95c0) * Expire in 1 ms for 1 (transfer 0x55cc25ec95c0) * Expire in 0 ms for 1 (transfer 0x55cc25ec95c0) * Expire in 0 ms for 1 (transfer 0x55cc25ec95c0) * Expire in 2 ms for 1 (transfer 0x55cc25ec95c0) * Expire in 1 ms for 1 (transfer 0x55cc25ec95c0) * Expire in 1 ms for 1 (transfer 0x55cc25ec95c0) * Expire in 2 ms for 1 (transfer 0x55cc25ec95c0) * Trying 10.8.0.253... * TCP_NODELAY set * Expire in 200 ms for 4 (transfer 0x55cc25ec95c0) * Connected to mysite.xyz (10.8.0.253) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * successfully set certificate verify locations: * CAfile: none CApath: /etc/ssl/certs * TLSv1.3 (OUT), TLS handshake, Client hello (1): * TLSv1.3 (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, Change cipher spec (1): * TLSv1.2 (OUT), TLS handshake, Finished (20): * TLSv1.2 (IN), TLS handshake, Finished (20): * SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384 * ALPN, server accepted to use h2 * Server certificate: * subject: C=US; postalCode=XXXX; ST=XX; L=XXXXX; street=XXXXXXXXXXXX; O=XXXXXX; OU=PremiumSSL Wildcard; CN=*.XXXXXXX * start date: Nov 20 00:00:00 2018 GMT * expire date: Feb 21 23:59:59 2021 GMT * subjectAltName: host "mysite.xyz" matched cert's "*.mysite.xyz" * issuer: C=GB; ST=Greater Manchester; L=Salford; O=COMODO CA Limited; CN=COMODO RSA Organization Validation Secure Server CA * SSL certificate verify ok. * Using HTTP2, server supports multi-use * Connection state changed (HTTP/2 confirmed) * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0 * Using Stream ID: 1 (easy handle 0x55cc25ec95c0) > GET / HTTP/2 > Host: mysite.xyz > User-Agent: curl/7.64.0 > Accept: */* > * Connection state changed (MAX_CONCURRENT_STREAMS == 100)! < HTTP/2 200 HTTP/2 200 < content-type: text/html content-type: text/html < last-modified: Mon, 01 Jul 2019 17:57:17 GMT last-modified: Mon, 01 Jul 2019 17:57:17 GMT < accept-ranges: bytes accept-ranges: bytes < etag: "c7c5406c3630d51:0" etag: "c7c5406c3630d51:0" < server: Microsoft-IIS/10.0 server: Microsoft-IIS/10.0 < date: Mon, 01 Jul 2019 19:45:53 GMT date: Mon, 01 Jul 2019 19:45:53 GMT < content-length: 51 content-length: 51 < <html> <head></head> </body>Hello</body> * Connection #0 to host mysite.xyz left intact </html>从上面的请求-响应日志中,我得到了以下内容:
From the above request-response log, I took the following:
GET / HTTP/2 Host: mysite.xyz User-Agent: curl/7.64.0 Accept: */*并创建了如下请求:
char* inputString = "GET / HTTP/2\r\nHost: mysite.xyz\r\nUser-Agent: curl/7.64.0\r\nAccept: */*\r\n\r\n"但是,这次我遇到了类似的错误:
But, this time I am getting error like:
Connected with ECDHE-RSA-AES256-GCM-SHA384 encryption Received: "HTTP/1.1 400 Bad Request Content-Type: text/html; charset=us-ascii Server: Microsoft-HTTPAPI/2.0 Date: Mon, 01 Jul 2019 20:28:48 GMT Connection: close Content-Length: 311 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""www.w3/TR/html4/strict.dtd"> <HTML><HEAD><TITLE>Bad Request</TITLE> <META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD> <BODY><h2>Bad Request</h2> <hr><p>HTTP Error 400. The request is badly formed.</p> </BODY></HTML>推荐答案
HTTP/2不是像HTTP/1这样的基于简单"文本的协议.这意味着您不能仅将HTTP请求作为文本发送到TCP套接字,而必须使用(相当复杂的)HTTP/2标准所定义的请求的二进制表示形式. curl在调试输出中显示的只是请求的文本解释,而不是线路上的实际表示.有关更多信息,请参见 RFC 7540 .请注意,除了二进制封装,您还需要将TLS中的ALPN扩展名设置为h2,以便向服务器宣布您将使用HTTP/2.
HTTP/2 is not a "simple" text based protocol like HTTP/1. This means that you cannot just send a HTTP request as text to the TCP socket but must instead use the binary representation of the request as defined by the (fairly complex) HTTP/2 standard. What curl shows in the debug output is just a text interpretation of the request but not the actual representation on the wire. For more see RFC 7540. Note that you additionally to the binary encapsulation need to set the ALPN extension in TLS to h2 in order to announce to the server that you will use HTTP/2.
在您的特定情况下,该请求以基于文本的方式发送(未设置ALPN h2且没有HTTP/2封装),但是基于文本的协议规范未知,即HTTP/2而不是HTTP/1.1或相似的.因此,服务器将请求正确视为无效.
In your specific case the request was send as text-based (no ALPN h2 set and no HTTP/2 encapsulation) but with an unknown protocol specification for text-based, i.e. HTTP/2 instead of HTTP/1.1 or similar. The server therefore correctly treated the request as invalid.
更多推荐
http2请求返回错误请求
发布评论