XE2でgzip圧縮されたページを取得するには?


迷子猫  2012-06-27 05:32:08  No: 42541

Delphi2007で作成したプロジェクトをDelphi XE2に移植してみました。

通信量を減らす為にWebからのデータをgzip圧縮で受取っているのですが、XE2で実行すると「アドレスxxxxでアドレスxxxxxに対する読み取り違反が起きました。」というエラーが発生するようになってしまいました。

IdHTTP1.Compressorの行をコメントアウトすると、エラーが発生しなくなるので、TIdCompressorZLibでエラーが起きているようですが原因がわかりませんでした。
TIdZLibCompressorBase.DecompressGZipStreamにバグがあるみたいなことが書いてあった英文のサイトもありましたが、いつの記事なのかわかりませんでした。

サンプルプログラムを作ってみました。
procedure TForm1.Button1Click(Sender: TObject);
var
 SL : TStringList;
 MS : TMemoryStream;
 ENC : TEncoding;

begin
  IdHTTP1 := TIdHTTP.Create(Self);
  IdHTTP1.Compressor := IdCompressorZLib1;

  Memo1.Clear;
  Memo1.Lines.Add('Indy10 Version:' + IdHTTP1.Version);
  Memo1.Lines.Add('=======================');
  IdHTTP1.ReadTimeout := 50000;
  IdHTTP1.Request.Clear;

  MS := TMemoryStream.Create;
  SL := TStringList.Create;
  ENC := TEncoding.GetEncoding(65001);
  try
    MS.Clear;
    SL.Clear;
    IdHTTP1.Get('http://www.google.co.jp/', MS);
  finally
    MS.Position := 0;
    SL.LoadFromStream(MS, ENC);
    Memo1.Lines.Add('Response-Text:' + IdHTTP1.ResponseText);
    Memo1.Lines.Add('Content-Encoding:' + IdHTTP1.Response.ContentEncoding);
    Memo1.Lines.Add('Content-Type:' + IdHTTP1.Response.ContentType);
    Memo1.Lines.Add('Content-Length:' + IntToStr(IdHTTP1.Response.ContentLength));
    Memo1.Lines.Add('=======================');
    Memo1.Lines.Add(SL.Text);
    MS.Free;
    SL.Free;
  end;
end;

Content-Encodingを見るとgzip圧縮で結果が返ってきているようですが、IdHTTP1.Getの所で例外が発生します。

使用しているOSはWindows XPです。
Indyのバージョンは10.5.8.0です。


迷子猫  2012-06-28 00:19:56  No: 42542

プロジェクトにIndy10のソースを追加してデバッグを追跡していくと、IdZLib.pasのfunction LocalTryStreamType(AStreamType: TZStreamType): Boolean;のDCheck(inflateInitEx(strm, AStreamType));で例外が発生しているところまでわかりました。
inflateInitEx(strm, AStreamType)が存在しないアドレスを見にいっているようです。
zlibのdllかobjが存在していないか、パスが通っていないのでしょうか?


迷子猫  2012-07-20 03:59:00  No: 42543

さらにソースを追跡して、IdZLibHeaders.pasで指定されている、zlib関連と思われる、objファイルが見つからないことが判りました。
Delphi XE2のバージョンがUpdate1のままで、なぜか自動更新も聞かなかったので、Delphi XE2を再インストールしてみましたが、現象は変わらなくて、objファイルも見つかりませんでした。

zlib homeのサイトからソースをダウンロードして自分でコンパイルしないといけないのでしょうか?


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加