STDINを使用しないと、カールエラーが発生する可能性があります。

STDINを使用しないと、カールエラーが発生する可能性があります。

Githubの受信後フックを設定しました。 Apache cgiスクリプトにPOSTリクエストを実行し、リポジトリへの変更をローカルに複製されたベアリポジトリにダウンロードします。追加するとスクリプトは正常に実行されますが、VARIABLE=$(cat -)発行要求を実行して次の行を削除しようとするとカールエラーが発生します。VARIABLE=

curl: (18) transfer closed with outstanding read data remaining

私のPOSTリクエストはカールによって生成されます(公開データはテスト用にのみ使用され、実際のスクリプトでは使用されません)。

curl -D - -H "Connection: close" -H "Content-Type: application/json"     -d '{  "repository": {    "name": "webhook-test",    "git_url": "git://github.com/bng44270/webhook-test.git",    "ssh_url": "[email protected]:bng44270/webhook-test.git",    "clone_url": "https://github.com/bng44270/webhook-test.git"  }}' http://10.0.0.2/cgi-bin/clone.cgi --verbose

私の仮想ホスト構成ファイル:

  ScriptAlias "/cgi-bin" "/opt/hooks/cgi-bin"
  DocumentRoot /opt/hooks/html
  <Directory /opt/hooks>
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted
  </Directory>
</VirtualHost>

私のスクリプトは次のように実行されます。

#!/bin/bash

/sbin/runuser -l gogsjail -c '/usr/bin/git --git-dir /home/gogsjail/gogs-repositories/admin/upstream.git fetch --prune >/dev/null 2>&1' >/dev/null 2>&1
# VARIABLE=$(cat -)
echo "Content-type: text/json"
echo ""
echo '{"result":"success"}'

最後に、カールの出力は次のようになります。

* Expire in 0 ms for 6 (transfer 0x563f98984f90)
*   Trying 10.0.0.2...
* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x563f98984f90)
* Connected to 10.0.0.2 (10.0.0.2) port 80 (#0)
> POST /cgi-bin/clone.cgi HTTP/1.1
> Host: 10.0.0.2
> User-Agent: curl/7.64.0
> Accept: */*
> Connection: close
> Content-Type: application/json
> Content-Length: 230
>
* upload completely sent off: 230 out of 230 bytes
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Date: Mon, 08 Feb 2021 12:55:42 GMT
Date: Mon, 08 Feb 2021 12:55:42 GMT
< Server: Apache/2.4.38 (Debian)
Server: Apache/2.4.38 (Debian)
< Connection: close
Connection: close
< Transfer-Encoding: chunked
Transfer-Encoding: chunked
< Content-Type: text/json
Content-Type: text/json

<
{"result":"success"}
* transfer closed with outstanding read data remaining
* Closing connection 0
curl: (18) transfer closed with outstanding read data remaining

VARIABLE=$(cat -)エココール前に実行すると

* Expire in 0 ms for 6 (transfer 0x55ea56355f90)
*   Trying 10.0.0.2...
* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x55ea56355f90)
* Connected to 10.0.0.2 (10.0.0.2) port 80 (#0)
> POST /cgi-bin/clone.cgi HTTP/1.1
> Host: 10.0.0.2
> User-Agent: curl/7.64.0
> Accept: */*
> Connection: close
> Content-Type: application/json
> Content-Length: 244
>
* upload completely sent off: 244 out of 244 bytes
< HTTP/1.1 200 OK
< Date: Mon, 08 Feb 2021 13:35:28 GMT
< Server: Apache/2.4.38 (Debian)
< Connection: close
< Transfer-Encoding: chunked
< Content-Type: text/json
<
{"result":"success"}
* Closing connection 0

誰かが私を正しい方向に押してもらえますか?

ベストアンサー1

私はApacheがPOSTデータを含むクライアントからすべての要求を読み込み、それをパイプを介してcgiプロセスに書き込むのと同等のことを想像しています。また、cgiの応答を読み、それをクライアントに送信します。select()これらの読み取りと書き込みを継続しながらループを実行します。

cgiがパイプを終了して閉じると、apacheのselect()は読み込み時に例外をスローし、eofによって書き込まれると例外をスローします。 cgiがapacheからPOSTデータを読み取らない場合、apacheは保留中の書き込みでioerrorを表示します。したがって、cgiが誤動作していると考え、追加のクリーンアップなしで単にクライアント接続を閉じることができます。

cgiはコンテンツ長ヘッダーを出力しないため、Apacheは応答長を決定できないため、ヘッダーを出力しますTransfer-Encoding: chunked。このプロトコルは、後続の書き込み長で構成されるミニヘッダーで、応答の各書き込みを囲みます。プロトコルは、0\r\n長さ0()の書き込みを送信してきちんと終了する必要があります。おそらく、プロトコルの最後の部分が欠落してカールが文句を言う理由です。

チャンキングプロトコルはカールを介して公開されませんが、または--rawを使用して表示できますstrace()

おすすめ記事