PHP Curl - Received HTTP/0.9 when not allowed [duplicate]
Asked Answered
P

5

20

I stumbled over a weird behavior when I try to send a post HTTP/2.0 request to apples push service:

        $http2ch = curl_init();
        curl_setopt($http2ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
        curl_setopt($http2ch, CURLOPT_URL, 'https://api.push.apple.com/3/device/megauniquedevicetokendummy');
        curl_setopt($http2ch, CURLOPT_PORT, 443);
        curl_setopt($http2ch, CURLOPT_HTTPHEADER, $httpHeader);
        curl_setopt($http2ch, CURLOPT_POST, true);
        curl_setopt($http2ch, CURLOPT_POSTFIELDS, $body);
        curl_setopt($http2ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($http2ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($http2ch, CURLOPT_HEADER, 1);

       $result = curl_exec($http2ch);
       if ($result === false) {
           throw new \Exception("Curl failed: " . curl_error($http2ch) . " | " . curl_getinfo($http2ch, CURLINFO_HTTP_CODE));
       }

The exception is thrown with the Message: Curl failed: Received HTTP/0.9 when not allowed | 0

I explicitly told curl to use HTTP/2.0 on the second line of the code snipped above. Does anyone have any idea what that error message means and why curl uses such an old HTTP version?

I am on PHP 7.2 and curl version 7.66.0.

Premature answered 26/11, 2019 at 10:34 Comment(5)
have you tried HTTP/1.1 or HTTP/1.0?Slagle
@PavelLint, yes I tried it both, also just not using the options leads to the same error.Premature
Sounds like a potential bug, but I fail trying to reproduce that error using the curl command line against that URL...Osana
I think I probably found the issue. On the server where I send the request from, curl is compiled without "nghttp2". The server only accepts HTTP/2 connections which curl isn't capabl of when not compiled with "nghttp2". Using the --http2 flag curl responds with a curl: (1) Unsupported protocol. If I sent the very same request from my mac it works out of the box.Premature
I just ran into the similar error like "Received HTTP/0.9 when not allowed" when git push to a repo on gitlab server. it succeeded when i retried though.Indiaindiaman
P
9

I figured it out. Make sure that curl is compiled with nghttp2.

If you are unsure, you can check it on your terminal using curl --version

If you dont find nghttp2/{version} you need to compile curl again with nghttp2.

curl --version example where nghttp2 is missing:

curl 7.66.0 (amd64-portbld-freebsd12.0) libcurl/7.66.0 OpenSSL/1.1.1d zlib/1.2.11

curl --version example where nghttp2 is available:

curl 7.64.1 (x86_64-apple-darwin19.0) libcurl/7.64.1 (SecureTransport) LibreSSL/2.8.3 zlib/1.2.11 nghttp2/1.39.2
Premature answered 28/11, 2019 at 10:8 Comment(5)
I am suffering with the same issue. In my mac machine curl version 7.54, even i can't update version.Explant
@Explant The version of curl isn't that important, you have to check if you version of curl is compiled with nghttp2Premature
Found this answer after hours of searching. For anyone looking at how to compile curl with nghttp2, the instructions here worked for me: gist.github.com/jjpeleato/3327c2e38fc0fea7d6602401f9849809 If you already have a curl version installed, you'll need to point to the new one (/usr/local/bin/curl for me),Geologize
I have the issue even with a curl compiled with nghttp2.Upstairs
Same here. My curl (7.79.1) has nghttp2/1.45.1 and gives the HTTP/0.9 error. I'm running the latest nghttpd web server for testing.Eachelle
P
33

This can also happen when the server is a grpc server. When curl is run against a grpc server or other non-HTTP server that doesn't respond with a valid HTTP status line that curl expects, curl will print the "Received HTTP/0.9 when not allowed".

It might be better if curl printed something like "unknown protocol" rather than assuming it is 0.9 because hitting something like a grpc server these days is going to be far more common than an actual HTTP 0.9 server.

Pederast answered 9/3, 2021 at 23:42 Comment(5)
so, what's the solution for this? the others don't work for me.Monoicous
@Monoicous I believe that if you are hitting a grpc endpoint but are expecting an ordinary web server it's possible there is a misunderstanding. The software you think is running isn't but something else is and curl is not the tool you need to access the server. For grpc, normally you need a custom client for that service (you'll need the protobuf file or discovery via reflection), but it's possible a tool like grpcurl might work.Pederast
I confirm that this message is also displayed by curl http://<server_ip:139> run against the Samba/SMB (Windows) servers.Hydropic
@Monoicous The solution is to use --http2-prior-knowledge which forces curl to use a HTTP2 only connection instead of an HTTP1.1 upgradePalladic
I had this problem using python's http.server. The hint about it being possibly due to my response led me to reorder the send_response() / send_header() calls. I ended up finding that the send_response(200) needs to come first, then the send_header() calls, then the end_header(). To me send_response() and send_header() were just setting things in the object so it did not occur to me that the order between those two would make a difference.Broucek
P
9

I figured it out. Make sure that curl is compiled with nghttp2.

If you are unsure, you can check it on your terminal using curl --version

If you dont find nghttp2/{version} you need to compile curl again with nghttp2.

curl --version example where nghttp2 is missing:

curl 7.66.0 (amd64-portbld-freebsd12.0) libcurl/7.66.0 OpenSSL/1.1.1d zlib/1.2.11

curl --version example where nghttp2 is available:

curl 7.64.1 (x86_64-apple-darwin19.0) libcurl/7.64.1 (SecureTransport) LibreSSL/2.8.3 zlib/1.2.11 nghttp2/1.39.2
Premature answered 28/11, 2019 at 10:8 Comment(5)
I am suffering with the same issue. In my mac machine curl version 7.54, even i can't update version.Explant
@Explant The version of curl isn't that important, you have to check if you version of curl is compiled with nghttp2Premature
Found this answer after hours of searching. For anyone looking at how to compile curl with nghttp2, the instructions here worked for me: gist.github.com/jjpeleato/3327c2e38fc0fea7d6602401f9849809 If you already have a curl version installed, you'll need to point to the new one (/usr/local/bin/curl for me),Geologize
I have the issue even with a curl compiled with nghttp2.Upstairs
Same here. My curl (7.79.1) has nghttp2/1.45.1 and gives the HTTP/0.9 error. I'm running the latest nghttpd web server for testing.Eachelle
H
4

I do not believe it requires you to have a version of curl compiled differently, but rather set the option to allow http 0.9 as a response from your older server. PHP has some notes on "CURLOPT_HTTP09_ALLOWED" that may have differed when you posted your question via https://www.php.net/manual/en/function.curl-setopt.php

The option that overcame the error for me was:

curl_setopt($http2ch, CURLOPT_HTTP09_ALLOWED, true);
Hu answered 9/12, 2020 at 15:51 Comment(0)
H
0

just sharing my experience. I dockrized my php and elasticsearch. And mapped port 9300:9200 And got the above error I changed port mapping to 9200:9200 and it solved the problem.

Hitt answered 24/10, 2023 at 14:8 Comment(0)
M
0

I know this isn't a direct answer to the original question, however this is an answer for the title of the question, and is an example of the top voted answer:

curl: (1) Received HTTP/0.9 when not allowed

My particular issue was because the endpoint was expecting the url to be https and NOT http.

I was able to fix my issue by adding the -k flag ( or i could have installed the correct certs, etc ) and updating to https:

curl -k https://localhost:8082/topics

When using the http proxy for redpanda ( kafka alternative )

Microbe answered 5/4 at 18:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.