2010-05-19 252 views

回答

4

如果你在HttpApp.pas中談論TCookie,那麼就沒有內置屬性來支持HttpOnly。

你可以看看httpApp.pas在TCookie.GetHeaderValue: string;執行驗證。

但是,Cookie只是在標題中設置的,TWebResponse具有CustomHeaders 屬性。您可以撥打Response.CustomHeaders.Add(MyCookieValue);

以下類是TCookie的修改版本,用於支持HttpOnly,您可以使用它來正確生成cookie。

unit CookieGen; 

interface 
uses 
Sysutils,Classes,HttpApp; 
type 
    TCookieGenerator = class(TObject) 
    private 
    FName: string; 
    FValue: string; 
    FPath: string; 
    FDomain: string; 
    FExpires: TDateTime; 
    FSecure: Boolean; 
    FHttpOnly: Boolean; 
    protected 
    function GetHeaderValue: string; 
    public 
    property Name: string read FName write FName; 
    property Value: string read FValue write FValue; 
    property Domain: string read FDomain write FDomain; 
    property Path: string read FPath write FPath; 
    property Expires: TDateTime read FExpires write FExpires; 
    property Secure: Boolean read FSecure write FSecure; 
    property HttpOnly : Boolean read FHttpOnly write FHttpOnly; 
    property HeaderValue: string read GetHeaderValue; 
    end; 

implementation 

{ TCookieGenerator } 

function TCookieGenerator.GetHeaderValue: string; 
begin 
    Result := Format('%s=%s; ', [HTTPEncode(FName), HTTPEncode(FValue)]); 
    if Domain <> '' then 
    Result := Result + Format('domain=%s; ', [Domain]); { do not localize } 
    if Path <> '' then 
    Result := Result + Format('path=%s; ', [Path]);  { do not localize } 
    if Expires > -1 then 
    Result := Result + 
     Format(FormatDateTime('"expires="' + sDateFormat + ' "GMT; "', Expires), { do not localize } 
     [DayOfWeekStr(Expires), MonthStr(Expires)]); 
    if Secure then Result := Result + 'secure; '; { do not localize } 
    if HttpOnly then Result := Result + 'HttpOnly'; { do not localize } 
    if Copy(Result, Length(Result) - 1, MaxInt) = '; ' then 
    SetLength(Result, Length(Result) - 2); 

end; 

end. 
0

到期時>請注意在HTTPApp.pas該原始TCookie.GetHeaderValue()方法可產生一個不正確的報頭-1和系統/應用時間分離器比結腸其他符號「:」。 TCookie.GetHeaderValue()方法使用常量sDateFormat格式化「Expires」字段。原來,sDateFormat常數被錯誤地定義爲:

const 
    sDateFormat = '"%s", dd "%s" yyyy hh:nn:ss'; 

如果用戶改變該應用程序TimeSeparator中可變比結腸符號以外的東西「:」,則到期時間將使用另一個字符格式化,而不是「 :「按照RFC 1123(格式」Wdy,DD Mon YYYH HH:MM:SS GMT「)的規定。 Google Chrome 25+拒絕使用除冒號以外的時間分隔符的Cookie,導致使用它的網絡應用程序完全失敗。所以正確的GetHeaderValue()方法應該是:

function TCookieGenerator.GetHeaderValue: string; 
const 
    _DateFormat = '"%s", dd "%s" yyyy hh":"nn":"ss'; // this is the correct constant. HTTPApp.pas wrongly declares it as sDateFormat = '"%s", dd "%s" yyyy hh:nn:ss'; 
begin 
    Result := Format('%s=%s; ', [HTTPEncode(FName), HTTPEncode(FValue)]); 
    if Domain <> '' then 
    Result := Result + Format('domain=%s; ', [Domain]); { do not localize } 
    if Path <> '' then 
    Result := Result + Format('path=%s; ', [Path]);  { do not localize } 
    if Expires > -1 then 
    Result := Result + 
     Format(FormatDateTime('"expires="' + _DateFormat + ' "GMT; "', Expires), { do not localize } 
     [DayOfWeekStr(Expires), MonthStr(Expires)]); 
    if Secure then Result := Result + 'secure; '; { do not localize } 
    if HttpOnly then Result := Result + 'HttpOnly'; { do not localize } 
    if Copy(Result, Length(Result) - 1, MaxInt) = '; ' then 
    SetLength(Result, Length(Result) - 2); 
end; 

我已經提交了關於此的QC#113139。

相關問題