2013-10-16 150 views
1

如何使用OIBindInfoIWinInetHttpInfo獲取所有請求標題?我在Start中使用這個,但變量HeadersRequestHeaders總是空的?如何獲取所有請求標頭?

方法使用OIBindInfo:使用IWinInetHttpInfo

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; 

方法:

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; 

無論是工作!

+0

嘗試使用POleStr而不是POleStrArray。 – whosrdaddy

回答

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 saysBINDSTRING_HEADERS是「目前不支持」。

+0

爲什麼在'GetBindString'甚至被調用之前分配'Headers'?你真的測試過這個代碼嗎?因爲這不適用於任何國旗。請更新您的代碼。 –

+0

'Headers'是一個指針數組。 'GetBindString()'不分配一個新的數組,它只是填充給定的現有數組,這就是爲什麼你必須傳遞數組長度的原因。我不知道是否有可能查詢有多少標題,因此可以動態調整數組大小。不,我沒有嘗試過這些代碼,它是基於我發現的其他例子。 –

+0

'GetBindString'甚至被稱爲它充滿奇怪的字符。 –