3

DelphiとIndy9/10を使用して特定のWebサーバーからfavicon.icoを受信する際に問題が発生しました。他のサーバーは正常に動作します。wgetコマンドラインユーティリティがファイルを正しく取得するため、このWebサーバーには問題はありません。

これがwgetからの出力です:

c:\a>wget http://perforce.eigenbase.org:8080/favicon.ico
SYSTEM_WGETRC = c:/progra~1/wget/etc/wgetrc
syswgetrc = c:/progra~1/wget/etc/wgetrc
--2013-01-27 00:12:39--  http://perforce.eigenbase.org:8080/favicon.ico
Resolving perforce.eigenbase.org... 72.14.190.177
Connecting to perforce.eigenbase.org|72.14.190.177|:8080... connected.
HTTP request sent, awaiting response... 200 No headers, assuming HTTP/0.9
Length: unspecified
Saving to: `favicon.ico'

    [ <=>                                   ] 2.862       --.-K/s   in 0s

2013-01-27 00:12:40 (143 MB/s) - `favicon.ico' saved [2862]

これが私のDelphiIndy9/10サンプルコードです。「ConnectionClosedGracefully」例外が生成され、結果は空の文字列になります。

procedure TForm1.Button1Click(Sender: TObject);
var s: string;
begin
  s := '';
  try
    s := IdHTTP1.Get('http://perforce.eigenbase.org:8080/favicon.ico');
  except
     on E: Exception do
     begin
          {$IFDEF DEBUG}ShowMessage('get error:'+E.Message){$ENDIF};
     end;
  end;
  ShowMessage(IntToStr(Length(s)));
end;

別のサーバーで同じコードを試してみると、たとえば次のようになります。

s := IdHTTP1.Get('http://www.google.com/favicon.ico');

すべてが正常に機能します。

サーバーからIdHTTP1.Getを使用してhttp://perforce.eigenbase.org:8080/favicon.icoファイルを取得するための回避策はありますか?

4

1 に答える 1

7

失敗する理由TIdHTTPは、wgetが報告しているこの重要な情報のためです。

HTTP / 0.9を想定した場合、ヘッダーはありません

HTTP 0.9応答では、HTTPステータス行とヘッダーはまったく存在せず、生ファイルデータ自体のみが存在し、切断によって終了します。wgetはそれをサポートしていますが、サポートしていTIdHTTPません(公式のHTTP1.0およびHTTP1.1の仕様では、HTTP 0.9応答の認識をサポートする必要があります)。 TIdHTTPHTTP 1.0および1.1形式のメッセージのみをサポートし、HTTPステータス行とヘッダーを使用する必要があります。何らかの理由で、この特定のサーバーはIndyに対してHTTP 0.9応答を送信することをUserAgent選択していますが、代わりにInternetExplorerUserAgentに対してHTTP1.0応答を送信することを選択しています。奇数。

短期的な解決策は、@TLamaが言ったことを実行することです。TIdHTTP.Request.UserAgentInternet Explorerを模倣するようにプロパティを設定すると、TIdHTTP.Get()正しく機能します。

procedure TForm1.Button1Click(Sender: TObject);
var
  icon: TMemoryStream;
begin
  icon := TMemoryStream.Create;
  try
    try
      IdHTTP1.Request.UserAgent := 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1';
      IdHTTP1.Get('http://perforce.eigenbase.org:8080/favicon.ico', icon);
    except
      on E: Exception do
      begin
        {$IFDEF DEBUG}ShowMessage('get error:'+E.Message){$ENDIF};
      end;
    end;
    ShowMessage(IntToStr(icon.Size));
  finally
    icon.Free;
  end;
end;

長期的な解決策はTIdHTTP、HTTP 0.9応答をサポートするように更新することですが、今日ではそれらに遭遇することは非常にまれです。そのために、IndyのIssueTrackerでチケットを開きました。

于 2013-01-28T06:51:25.153 に答える