如何获取所有请求标头?

时间:2013-10-16 20:42:49

标签: delphi com twebbrowser

如何通过OIBindInfoIWinInetHttpInfo获取所有请求标头?我在Start中使用此内容,但变量HeadersRequestHeaders始终为空?

使用OIBindInfo的方法:

function THandler.Start(szUrl: PWideChar; OIProtSink:
IInternetProtocolSink; OIBindInfo: IInternetBindInfo; grfPI, dwReserved:
DWORD): HResult; stdcall;
var
    dwSize: ULONG;
    pszHeaders: POleStr;
    Headers: String;
begin
    OIBindInfo.GetBindString(BINDSTRING_HEADERS, @pszHeaders, 1, dwsize)
    Headers := PWideChar(pszHeaders); // weird result of Headers = ჸ
    CoTaskMemFree(pszHeaders);
    pszHeaders := nil;
    Result := INET_E_USE_DEFAULT_PROTOCOLHANDLER;
end;

使用IWinInetHttpInfo的方法:

type
  THandler = class(TComObject, IInternetProtocol, IWinInetHttpInfo)
    private
      ServiceProvider: IServiceProvider;
      WinInetHttpInfo: IWinInetHttpInfo;
      URL: String;
      RequestHeaders: String;
      function QueryInfoEx(dwOption: DWORD; var Info: string): Boolean;
    protected
      function Start(szUrl: PWideChar; OIProtSink: IInternetProtocolSink;
        OIBindInfo: IInternetBindInfo; grfPI, dwReserved: DWORD): HResult; stdcall;
      function Continue(const ProtocolData: TProtocolData): HResult; stdcall;
      function Abort(hrReason: HResult; dwOptions: DWORD): HResult; stdcall;
      function Terminate(dwOptions: DWORD): HResult; stdcall;
      function Suspend: HResult; stdcall;
      function Resume: HResult; stdcall;
      function Read(pv: Pointer; cb: ULONG; out cbRead: ULONG): HResult; stdcall;
      function Seek(dlibMove: LARGE_INTEGER; dwOrigin: DWORD;
        out libNewPosition: ULARGE_INTEGER): HResult; stdcall;
      function LockRequest(dwOptions: DWORD): HResult; stdcall;
      function UnlockRequest: HResult; stdcall;
      function QueryInfo(dwOption: DWORD; Buffer: Pointer; var cbBuf, dwFlags, dwReserved: DWORD): HResult; stdcall;
      function QueryOption(dwOption: DWORD; Buffer: Pointer; var cbBuf: DWORD): HResult; stdcall;
  end;

function THandler.QueryInfoEx(dwOption: DWORD; var Info: string): Boolean;
var
  Buf: array[0..INTERNET_MAX_PATH_LENGTH] of AnsiChar;
  BufLength, dwReserved, dwFlags: Cardinal;
begin
    dwReserved := 0;
    dwFlags := 0;
    BufLength := INTERNET_MAX_PATH_LENGTH + 1;
    Result := not Boolean(WinInetHttpInfo.QueryInfo(dwOption, @Buf, BufLength, dwFlags, dwReserved));
    if Result then 
    Info := string(Buf);
end;

function THandler.Start(szUrl: PWideChar; OIProtSink:
IInternetProtocolSink; OIBindInfo: IInternetBindInfo; grfPI, dwReserved:
DWORD): HResult; stdcall;
begin
  OIProtSink.QueryInterface(IServiceProvider, ServiceProvider);
  OIProtSink.QueryInterface(IWinInetHttpInfo, WinInetHttpInfo);
  QueryInfoEx(HTTP_QUERY_RAW_HEADERS, RequestHeaders); // empty RequestHeaders
  Result := INET_E_USE_DEFAULT_PROTOCOLHANDLER;
end;

两者都没有工作!

1 个答案:

答案 0 :(得分:1)

您没有查看GetBindString()的返回值,以确保它输出任何数据。

如果要检索特定标头,则使用单个POleStr即可,例如:

function THandler.Start(szUrl: PWideChar; OIProtSink: IInternetProtocolSink; OIBindInfo: IInternetBindInfo; grfPI, dwReserved: DWORD): HResult; stdcall;
var
  MimeType: POleStr;
  Fetched: ULONG;
begin
  if Succeeded(OIBindInfo.GetBindString(BINDSTRING_POST_DATA_MIME, @MimeType, 1, Fetched)) then
  begin
    // use MimeType as needed...
    CoTaskMemFree(MimeType);
  end;
  Result := INET_E_USE_DEFAULT_PROTOCOLHANDLER;
end;

但是,您正在尝试检索多个标头,因此您需要使用数组:

function THandler.Start(szUrl: PWideChar; OIProtSink: IInternetProtocolSink; OIBindInfo: IInternetBindInfo; grfPI, dwReserved: DWORD): HResult; stdcall;
var
  Headers: array[0..255] of POleStr;
  Fetched, I: ULONG;
begin
  Fetched := 0;
  if Succeeded(OIBindInfo.GetBindString(BINDSTRING_HEADERS, @Headers[0], Length(Headers), Fetched)) then
  begin
    if Fetched > 0 then
    begin
      for I := 0 to Fetched-1 do
      begin
        // use Headers[I] as needed...
        CoTaskMemFree(Headers[I]);
      end;
    end;
  end;
  Result := INET_E_USE_DEFAULT_PROTOCOLHANDLER;
end;

话虽如此,MSDN says BINDSTRING_HEADERS是“当前不支持”。