How do I set the开发者_C百科 HTTPOnly flag? the TCookie does not have any method or property to specify the HTTPOnly flag.
If you talking about TCookie in HttpApp.pas then there is no built in property to support HttpOnly.
You can look at httpApp.pas at the TCookie.GetHeaderValue: string;
implementation to verify.
However a Cookie is just something set in the Header and TWebResponse has a CustomHeaders
property. Where you could Call Response.CustomHeaders.Add(MyCookieValue);
The following class is a modified version of TCookie to support HttpOnly that you can use to generate the cookie correctly.
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.
Please note that original TCookie.GetHeaderValue() method in HTTPApp.pas may generate an incorrect header when expires > -1 and the system/application time separator is other than the colon sign ":". TCookie.GetHeaderValue() method uses the constant sDateFormat for formatting "Expires" field. Turns out that sDateFormat constant is wrongly defined as:
const
sDateFormat = '"%s", dd "%s" yyyy hh:nn:ss';
If the user changes the application TimeSeparator variable to something other than the colon sign ":", then the expires time will be formated using another character, and not ":" as specified in RFC 1123 (format “Wdy, DD Mon YYYY HH:MM:SS GMT”). Google Chrome 25+ rejects cookies with time separator other than the colon sign, causing complete failure of web applications using it. So the correct GetHeaderValue() method should be:
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;
I've submited QC #113139 about this.
精彩评论