2

かなり大きなデータチャンク(リクエストごとに1.5MB、多くあります)をネイティブAndroidアプリケーションに提供するDelphiRESTサーバーを構築しています。この場合のデータサイズに問題があり、環境内で転送時間が長くなる(モバイルデータレートが制限される)ことを除いて、すべて正常に動作します。ZLibCompressionにフィルターを追加しようとしましDSHTTPWebDispatcherたが、応答は非圧縮のtext/htmlとしてのみ返されます。

ディスパッチ前にイベントとして追加されたフィルターをサーバーに強制的に使用させる方法はありますか?

サーバーはDelphiXE3を使用して構築されています。

4

1 に答える 1

2

DataSnap プロジェクトの圧縮と関連するヘッダーの変更を追加する場所を見つけることができました。

ここで重要なのは TWebModule クラスです。ウィザードを使用して新しいプロジェクトを作成すると、BeforeDispatch、AfterDispatch などのイベント プロパティを使用して、TWebModule クラスのデフォルトの実装が構築されます。そのため、BeforeDispatch はリクエストが到着したときに発生し、サーバー上で何らかの処理が行われ、AfterDispatch はレスポンスが発信者に返される直前にトリガーされます。

したがって、AfterDispatch は、構築された応答を事後に変更したい場合に使用する正しいイベントです。これには、コンテンツとヘッダーの両方への変更が含まれる場合があります。

AfterDispatch イベント:

procedure TWebModule1.WebModuleAfterDispatch(
  Sender: TObject;
  Request: TWebRequest; 
  Response: TWebResponse;
  var Handled: Boolean);
var

srcbuf, destbuf : TBytes;
str : string;

begin
  str := Response.Content;

  //prepare byte array
  srcbuf := BytesOf(str);

  //compress to buff (System.ZLib)
  ZCompress(srcbuf, destbuf, zcMax);

  //prepare responsestream and set content encoding and type
  Response.Content := '';
  Response.ContentStream := TMemoryStream.Create;
  Response.ContentEncoding := 'deflate';
  Response.ContentType := 'application/json';

  //current browser implementations incorrectly handles the first 2 bytes 
  //of a ZLib compressed stream, remove them
  Response.ContentStream.Write(@(destbuf[2]),length(destbuf)-2);
  Response.ContentLength := (length(destbuf))-2;
end;

あまり派手ではありませんが、送り返されたコンテンツに応じて圧縮を有効/無効にすることができますが、実装では単純に保ちました。

これは、デフレートを処理できる Fiddler およびブラウザーで 100% 機能します。

于 2013-02-28T08:06:27.193 に答える