質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.02%

  • PHP

    17738questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • cURL

    126questions

    cURLはHTTP, FTPやTelnetなど複数のプロトコルを用いてデータを転送するライブラリとコマンドラインツールを提供します。

  • HTTP2

    10questions

    HTTP2は、Hypertext Transfer Protocolのバージョンの1つでWWWで用いられます。接続を多重化し複数のリクエスト処理でき、HTTP1.1との互換性を持たせています。

HTTPのバージョン違いによる ERR_SPDY_PROTOCOL_ERROR

受付中

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 418

crescens

score 0

 前提・実現したいこと

PHPのcURLでWeb APIを叩いて出力結果を表示したいのですが、
プログラムを実行するサーバ(以下A)とWeb API提供元(以下B)に
HTTPのバージョンの違いがあるのでGoogle Chrome で以下のエラーが発生します。

 発生している問題・エラーメッセージ

POST https://*** net::ERR_SPDY_PROTOCOL_ERROR


(A)がHTTP2導入済み、(B)がHTTP2未導入です。(A)のHTTP2をオフにすると、エラーは発生しません。
HTTP2をオフにする以外の対処法がありましたらご教授ください。

 ソースコード

<?php
    $url = "(B)のURL";
    $ch = curl_init(); 
    curl_setopt( $ch, CURLOPT_URL, $url ); 
    curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
    curl_setopt( $ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1 );
    $result = curl_exec( $ch ); 
    curl_close(); 
    echo $result;
?>

 (A)のサーバ環境

OS:CentOS 7.4
Webサーバ:nginx 1.13.8
SSL:OpenSSL 1.0.2k
他:PHP 7.2、cURL 7.57.8

1/29追記

 (A)のnginxの設定

■nginx.conf

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    resolver 127.0.0.1;

    keepalive_timeout  65;

    #gzip  on;
    brotli on;

    server_tokens off;
    add_header X-Frame-Options SAMEORIGIN;
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options nosniff;

    include /etc/nginx/conf.d/vhost.conf;
    #include /etc/nginx/conf.d/*.conf;
}

■conf.d/vhost.conf

server {
    listen       80 default_server;
    listen       [::]:80 default_server;
    server_name  example.com;
    root         /var/www/html;
    error_log    /var/log/nginx/error.log;
    access_log   /var/log/nginx/access.log  main;

    location / {
        index  index.html index.htm index.php;
    }

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
        fastcgi_pass   unix:/var/run/php-fpm/www.sock;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root/$fastcgi_script_name;
        include        fastcgi_params;
    }

    include ssl.conf;
}

■conf.d/ssl.conf

#
# conf.d/ssl.conf
#

#listen 443 ssl http2;
listen 443 ssl;
ssl_session_cache shared:le_nginx_SSL:1m;
ssl_session_timeout 1440m;
add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains' always;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;

ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-SHA ECDHE-ECDSA-AES256-SHA ECDHE-ECDSA-AES128-SHA256 ECDHE-ECDSA-AES256-SHA384 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES128-SHA ECDHE-RSA-AES128-SHA256 ECDHE-RSA-AES256-SHA384 DHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES128-SHA DHE-RSA-AES256-SHA DHE-RSA-AES128-SHA256 DHE-RSA-AES256-SHA256 EDH-RSA-DES-CBC3-SHA";

ssl_stapling on;
ssl_stapling_verify on;

if ($scheme != "https") {
    return 301 https://$host$request_uri;
}                                                                                                            
ssl_certificate /etc/pki/tls/certs/2017.crt;
ssl_certificate_key /etc/pki/tls/private/2017.key;
ssl_trusted_certificate /etc/pki/tls/certs/2017.intermediate;
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+2

(B)がHTTP2未導入です。

であれば、HTTP/2によるアクセスは不可能です。「HTTP2をオフにする以外の対処法」はありません。


ところで、「(A)がHTTP2導入済み」とはどういうことでしょうか。AのHTTPサーバがHTTP/2に対応していても、それはAからBに行うHTTP通信には全く関係しません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/26 16:42

    回答ありがとうございます。


    HTTP2のオフは、nginxのSSLのlisten設定を「listen 443 ssl;」のみにすることで対応しました。
    nginxのSSLのlisten設定を「listen 443 ssl http2;」にしたまま、Web APIをたたくときだけhttp1.1通信にしたいと考え、cURLで「curl_setopt( $ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1 );」とオプションを設定しましたがエラーのままでした。
    cURLのオプションを設定することによってhttp1.1アクセスが不可能でしたら諦めます。

    > ところで、「(A)がHTTP2導入済み」とはどういうことでしょうか。AのHTTPサーバがHTTP/2に対応していても、それはAからBに行うHTTP通信には全く関係しません。

    全く関係しないのであれば、nginxのhttp2をオフにしたときにエラーが発生せず、nginxのhttp2設定をオンにしたときに「ERR_SPDY_PROTOCOL_ERROR」が発生する理由は何でしょうか?

    キャンセル

+1

maisumakun さんへのコメントで理解しましたが、ものすごいミスリードですね^^;

現象は以下で正しいでしょうか?
・問題発生は A サーバに対してブラウザからの POST
・A の HTTP/2 をオンにするとエラーERR_SPDY_PROTOCOL_ERRORが発生する
オフにするとエラーは発生しない

A の HTTP/2 の通信が正しく行われていないのではないかと思います。
・そもそも、POST 以外のアクセスで、エラーが出ていないか?
を確認してみてください。

ちなみにですが、A で行っている処理(php による B へのアクセス)は本件に無関係です。
あくまで、ブラウザと A サーバとの HTTP/2 接続の中で問題が発生しています。

追記
nginx -V で built with OpenSSL が 1.0.2 になっているか確認してください。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/26 20:07

    回答ありがとうございます。ミスリード申し訳ないです。精進します!

    現象は、AサーバからBサーバへのPOSTです。Aサーバでは以下のサイトを参考にしてプログラムを作成しました。
    https://stella-design.biz/2016/03/10/001405.html

    AのHTTP2をオンにするとエラーが発生するのは、おっしゃる通りです。

    AからBへのPOST以外はHTTP2が利用できていることを、Google Chromeのデベロッパーツールで確認しています。AからBへのPOSTだけ失敗します。

    なお、nginx -Vの出力結果の一部は以下のとおりです。
    $ nginx -V
    nginx version: nginx/1.13.8
    built by gcc 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC)
    built with OpenSSL 1.0.2k-fips 26 Jan 2017

    キャンセル

  • 2018/01/26 21:04

    ERR_SPDY_PROTOCOL_ERROR が発生するのは、ブラウザとAの通信においてという理解で正しいですか?

    で、解消したい現象は、このエラーをなくしたい?

    それとも、A から B への通信を HTTP/2 にしたい?

    ちなみにですが、A から B への通信は、ブラウザの開発ツールでは確認することが出来ません。ブラウザの開発ツールで確認できるのは、ブラウザと A の通信です。

    キャンセル

  • 2018/01/29 09:21

    回答遅くなりまして申し訳ございません。

    > ERR_SPDY_PROTOCOL_ERROR が発生するのは、ブラウザとAの通信においてという理解で正しいですか?

    おっしゃる通りです。開発ツールで表示しているのはAからBへの通信だと勘違いしておりました。
    解消したい現象は、nginxの設定でHTTP/2をONにしたままこのエラーをなくしたいです。

    キャンセル

  • 2018/01/29 10:02

    使用している環境は、HTTP/2に対応してそうなので、nginx の conf に問題がある可能性があります。
    質問に追記すると、回答が得られるかもしれません。

    キャンセル

  • 2018/01/29 13:24

    承知しました。ご丁寧な対応ありがとうございます!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 91.02%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • PHP

    17738questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • cURL

    126questions

    cURLはHTTP, FTPやTelnetなど複数のプロトコルを用いてデータを転送するライブラリとコマンドラインツールを提供します。

  • HTTP2

    10questions

    HTTP2は、Hypertext Transfer Protocolのバージョンの1つでWWWで用いられます。接続を多重化し複数のリクエスト処理でき、HTTP1.1との互換性を持たせています。