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

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

新規登録して質問してみよう
ただいま回答率
85.48%
HTTP

HTTP(Hypertext Transfer Protocol)とはweb上でHTML等のコンテンツを交換するために使われるアプリケーション層の通信プロトコルです。

Apache

Apacheは、Apache HTTP Serverの略で、最も人気の高いWebサーバソフトウェアの一つです。安定性が高いオープンソースソフトウェアとして商用サイトから自宅サーバまで、多くのプラットフォーム向けに開発・配布されています。サーバーソフトウェアの不具合(NCSA httpd)を修正するパッチ(a patch)を集積、一つ独立したソフトウェアとして開発されました。

Q&A

0回答

2637閲覧

Apache/CGIで"Transfer-Encoding: Chunked"なデータのサイズが受信できない

sayhorn

総合スコア12

HTTP

HTTP(Hypertext Transfer Protocol)とはweb上でHTML等のコンテンツを交換するために使われるアプリケーション層の通信プロトコルです。

Apache

Apacheは、Apache HTTP Serverの略で、最も人気の高いWebサーバソフトウェアの一つです。安定性が高いオープンソースソフトウェアとして商用サイトから自宅サーバまで、多くのプラットフォーム向けに開発・配布されています。サーバーソフトウェアの不具合(NCSA httpd)を修正するパッチ(a patch)を集積、一つ独立したソフトウェアとして開発されました。

0グッド

0クリップ

投稿2016/04/20 12:58

編集2016/04/20 12:59

###前提・実現したいこと
Apache経由でTransfer-Encoding: Chunkedのデータを受け取れるCGIを作成したいです。

  • WebServer側

OS: Linux version 2.6.32-573.18.1.el6.i686 (gcc version 4.4.7 20120313 (Red Hat 4.4.7-16) (GCC) )
Apache: 2.2.31
CGI: C言語で作成し、/var/www/cgi-bin/で動作するよう設定済み

  • WebClient側

OS: Linux version 2.6.18-406.el5xen (gcc version 4.1.2 20080704 (REd Hat 4.1.2-55))
Bash: 3.2.25(1)-release-(i386-redhat-linux-gnu)
curl: 7.15.5 (i386-redhat-linux-gnu) libcurl/7.5.15 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5

###発生している問題・エラーメッセージ
Server側で標準入力を読み出した時、一つ目のfgetsでサイズではなくデータが読み出せてしまいました。
つまり、データサイズがCGIに渡されず、データ部分しか渡されていないように見えるということです。
これではCGIで読み出すべきサイズがわからないので正しくデータが読み出せたかどうかがわかりません。
CGIでRFC2616で定義されるTransfer-Encoding: Chunkedのデータを正しく受信したいのですが、解決策はあるでしょうか?
CGIにデータが渡された時点でfreadすればその時に受信すべきデータが必ず全て受信できるような保証があるのならそれでも問題ないとは思うのですが、Transfer-Encoding: Chunkedに関する仕様上からは、そのような情報は読み取れませんでした。

尚、RFC2616を読むとHTTPボディ部は以下のように定義されていました。ただし、奇数・偶数というのはここでの便宜上そのように記載したのであって、仕様上そのように定められているものではありません。

  • (1行目)空行
  • (偶数行目)サイズを意味する16進数文字列+CRLF
  • (奇数行目)サイズ分の長さを持った任意のビット列+CRLF

###該当のソースコード
Client側からcurlで次のコマンドを発行しました。

curl -S -X POST --data-binary @data.txt -H 'User-Agent: UAName' --header 'Content-Type: application/octet-stream' --header 'Transfer-Encoding: Chunked' --header 'Expect: 100-continue' --progress-bar ${ACCESS_URL}

※data.txtはテキストデータが100MB書き込まれたファイル名を意味します
※data.txtの中身は"hogehoge\r\nfugafuga\r\n"の繰り返しです。
※ACCESS_URLは実際にアクセスした際のURLを意味します

また、Server側では以下のようなコードで標準入力を読み出しました。

C

1int main(void) 2{ 3 char caLine[8192] = { 0, }; 4 fgets(caLine, sizeof(caLine), stdin); 5 dbg_print("size:%s\n", caLine); 6 7 memset(caLine, 0, sizeof(caLine)); 8 fread(caLine, 1, 8192>sizeof(caLine)?sizoef(caLine):8192, stdin); 9 dbg_print("body-chunked:%s\n", caLine); 10 11 return 0; 12}

※Cソース中、dbg_print()はデバッグのため、syslogにprintf形式でメッセージを出力するユーザー定義関数です。

###試したこと
curlのオプションで '-T data.txt'としてみたり、'--limit-rate-4K'などとしてみましたが、いずれも同じ結果になり、サイズが読み出せませんでした。

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問