【问题标题】:How to receive binary data from a request in TIdHTTPWebBrokerBridge?如何从 TIdHTTPWebBrokerBridge 中的请求中接收二进制数据?
【发布时间】:2023-04-09 08:33:01
【问题描述】:

我正在使用 Indy 使用 HTTP 构建客户端和服务器应用程序。在客户端上,我使用TIdHTTP,在服务器上我使用TIdHTTPWebBrokerBridge 和一个Web 模块。我需要客户端能够通过流将任何类型的数据发布到服务器。这是通过我称为/set?Key=API_KEY&Name=FILE_NAME 的通用命令完成的,其中Key 是用于身份验证的API 密钥,Name 是要发布的文件的名称。

在客户端,我发布的数据是这样的:

function TInnoCloudClient.SetData(const Name: String; AStream: TStream): Bool;
var
  U: String;
begin
  U:= FServerURL; //Base URL of Server
  if Copy(U, Length(U)-1, 1) <> '/' then
    U:= U + '/';
  U:= U + 'get?Key='+Encode(FAPIKey);
  U:= U + '&Name='+Encode(Name);
  try
    FWeb.Post(U, AStream);
  except
    on e: exception do begin
      //Handle Exception
    end;
  end;
end;

这个函数应该把AStream里面的数据保存到服务器上一个文件名为Name的文件中。然而,在服务器端,在请求处理程序中,我在请求中没有看到相应的 TStream 属性,我可以从中读取它。

在服务器中,我如何获取作为TStream后代发送的数据?我不需要知道如何保存或处理请求,我只需要知道如何从请求(TWebRequest)中获取此 Stream?

【问题讨论】:

    标签: delphi delphi-xe2 indy indy10 httpserver


    【解决方案1】:

    使用TWebRequest.ReadClient()TWebClient.ReadString() 方法读取发布的二进制数据,或使用TWebRequest.RawContent 属性将发布的数据检索为AnsiString

    这样的事情应该可以工作:

    procedure TWebModule1.GetAllDataAsStream(ARequest: TWebRequest; AStream: TMemoryStream);
    var
      BytesRead, ContentLength: Integer;
      Buffer: array[0..1023] of Byte;
    begin
      AStream.Clear;
      ContentLength := ARequest.ContentLength;
      while ContentLength > 0 do begin
        BytesRead := ARequest.ReadClient(Buffer[0], Min(ContentLength, SizeOf(Buffer)));
        if BytesRead < 1 then Break;
        AStream.WriteBuffer(Buffer[0], BytesRead);
        Dec(ContentLength, BytesRead);
      end;
      AStream.Position:= 0;
    end;
    

    【讨论】:

    • 从我在 Delphi 文档中看到的以及我自己的测试似乎证明此代码会导致内容被截断 - 前 48k(?) 将丢失。在调用ReadClient 之前必须读取content,它只检索content 的前48k 之后的缓冲区的其余部分
    • 我不使用网上经纪服务,所以我不能说这是否属实。我所知道的是TIdHTTPWebBrokerBridge 在内部使用TIdHTTPServer 并将其功能公开给WebBroker。如果客户端发布数据,则各种TWebRequest.Read...() 方法直接从Indy 的TIdHTTPRequestInfo.PostStream 对象读取,否则它从包含来自TIdHTTPRequestInfo.FormParamsTIdHTTPRequestInfo.UnparsedParams 的数据的TStringStream 读取。因此,如果以我上面显示的方式读取数据丢失,则很可能在运行此代码之前已读取数据。
    • WebBroker 的Content 值从同一个流中读取,对于客户端发布的流,ContentPostStream 查找到开头,读取整个流,然后查找它回到原来的位置,而 Read...() 方法从当前位置开始读取。
    • @RemyLebeau - 可能在运行此代码之前已经阅读过它 - 我明白,但我的代码似乎证明并非如此。一位同事也以同样的方式向我发送了此链接:Re: Reading with IDThhp.Post sended data in ISAPI-DLL: data get messed up - Hello Remy, sorry for the inconvenience but your code doesn't work:
    • 我从未使用过 DataSnap/WebBroker,所以我无法评论它的实际工作原理。我只能评论我在TIdHTTPWebBrokerBridge源代码中看到的内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多