1

私はcarddavクライアントに取り組んでいます。サーバーとして、davicalv。0.9.9.6を使用します。httpヘッダーに正しい値が含まれていると、無効なコンテンツタイプエラーが発生する理由がわかりません。ソースコードを調べたところ、次の状態が見つかりました。

if ( isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['CONTENT_LENGTH'] > 7) {...

少し調べてみたところ$_SERVER['CONTENT_LENGTH']、POSTメソッドとアップロードファイルのみで設定されたphpが見つかりました。常に設定するようにphpを構成する方法はあります$_SERVER['CONTENT_LENGTH']か?この場合だけでなく、一般的に質問しています...

//編集(php curlを使用して)davicalサーバーにHTTPPUTリクエストを実行しています。

PUT /caldav.php/testuser/contacts/newc.vcf HTTP/1.1
Host: davical  
Content-Type: text/vcard;

BEGIN:VCARD
VERSION:3.0
FN:ME
...

davical側には、設定されていないCONTENT_LENGTHの条件テストがあります。それで、それは大胆なバグですか?

//編集2

最後に私はそれを理解します!calback readfuncを使用したPUTリクエストでは、curl_setopt(...)を介してINFILE_SIZEを設定する必要があります。自動値はなく、Content-Lengthフィールドを手動でヘッダーに配置することも間違っています。例(不正解):

// PUT REQUEST
curl_setopt($ch,CURLOPT_HTTPHEADER,"Content-Length: $length");  //mistake
curl_setopt($ch,CURLOPT_PUT,true);
curl_setopt($ch,CURLOPT_READFUNCTION,array($this,'readfunc'));
....
--------------------------------------------------------------
// WIRESHARK TCP STREAM DUMP
PUT /caldav.php/testuser/contacts/novy.vcf HTTP/1.1
Authorization: Basic xxxxxxxxxxxxxxx
Host: davical
Accept: */*
Content-Type: text/vcard
Content-Length: xxx
Expect: 100-continue

HTTP/1.1 100 Continue

155
BEGIN:VCARD
VERSION:3.0
...
END:VCARD

0

HTTP/1.1 200 OK
----------------------------------------------------------------
// On server side
isset($_SERVER['CONTENT_LENGTH'])==false

2番目の(正しい)例

// PUT REQUEST
curl_setopt($ch,CURLOPT_INFILESIZE,$length);
curl_setopt($ch,CURLOPT_PUT,true);
curl_setopt($ch,CURLOPT_READFUNCTION,array($this,'readfunc'));
....
--------------------------------------------------------------
// WIRESHARK TCP STREAM DUMP
PUT /caldav.php/testuser/contacts/novy.vcf HTTP/1.1
Authorization: Basic xxxxxxxxxxxxxxx
Host: davical
Accept: */*
Content-Type: text/vcard
Content-Length: xxx
Expect: 100-continue

HTTP/1.1 100 Continue

BEGIN:VCARD
VERSION:3.0
...
END:VCARD
HTTP/1.1 200 OK
----------------------------------------------------------------
// On server side
isset($_SERVER['CONTENT_LENGTH'])==true
4

3 に答える 3

1

CONTENT_LENGHT を使用したことはありませんが、これがおそらく起こっている理由を説明できます。

リクエストでは、Content-Lenght ヘッダーを設定する必要はありません...必須ではありません。特定の状況を除いて。POSTed コンテンツのタイプが「multipart/form-data」の場合、各パーツは境界で区切られ、各パーツには独自のヘッダーがあるため、各パーツに content-length を使用する必要があります...

例えば:

Content-Type: MultiPart/Form-Data
Boundary: @FGJ4823024562DGGRT3455

MyData=1&Username=Blabla&Password=Blue


@FGJ4823024562DGGRT3455==
Content-Type: image/jpef:base64
Content-Lenght: 256

HNSIFRTGNOHVDFNSIAH$5346twSADVni56hntgsIGHFNR$Iasdf==

これは、マルチパート リクエストの動作の大まかな例です。2 番目のパートには content-length があることがわかります。これが、別の境界を見つけて正しいデータを抽出する前に X バイトを読み取る必要があるため、content-length が設定される場合と設定されない場合がある理由です。

他の場合にサーバーが送信しないという意味ではありませんが、私の 2 セントは今の場合です。これは、POST ではなく、他のモードにいるためです。

于 2011-10-01T11:00:42.170 に答える
1

リクエストボディを持つリクエストのみがコンテンツ長のリクエストヘッダーを持っているため(または少なくともそれが意味をなす場合のみ)、$_SERVER変数が設定されます。

常に設定する必要がある場合(これは偽物だと思います)、スクリプトの最初で自分でこれを行うことができます:

isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['CONTENT_LENGTH'] = 0;

設定されていない場合、長さはゼロであると仮定します。PHP での HTTP リクエストの処理の改善も参照してください。

于 2011-10-01T11:00:48.537 に答える
0

おそらく自分で設定することができます。なぜこの値を設定する必要があるのですか?そして、彼らは何に設定する必要がありますか?

たぶん、私がしたように、$ _SERVER['CONTENT_TYPE']または$_SERVER['CONTENT_LENGTH']に関する情報が不足しています。POSTリクエストでは、上記のリストに加えてこれらを利用できます。

-> http://www.php.net/manual/en/reserved.variables.server.php#86495

于 2011-10-01T10:57:14.603 に答える