#1 2015-05-12 04:47:16

profh
Member
Registered: 2010-07-02
Posts: 159

about mutiply cookies

hi,ab

  i need to set more than one cookie key/value, but just the last one will be sent to the client. the code is as follow:

Ctxt.OutCustomHeaders := Ctxt.OutCustomHeaders + #13#10+ 
              'Set-Cookie: a=1111111111' + #13#10 + 'Set-Cookie: b=22222222';

  in the client response header, just get 'Set-Cookie: b=22222222'' string, and 'Set-Cookie: a=1111111111' is missing.

thanks!

Last edited by profh (2015-05-12 05:13:26)

Offline

#2 2015-05-12 06:49:20

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,183
Website

Re: about mutiply cookies

Such multiple cookie headers are not standard.
http://stackoverflow.com/a/16307353/458259
But they may appear, in the wild.

In fact, http.sys itself only allow a single cookie header!
So http.sys is just ignoring the 1st cookie, only transmitting the last one.
This is not a mORMot limitation, but a http.sys limitation, common to WCF/.Net.
See http://stackoverflow.com/q/2444022/458259

You should try to set both cookies on the same HTTP header:

Ctxt.OutCustomHeaders := Ctxt.OutCustomHeaders + #13#10+ 
              'Set-Cookie: a=1111111111; b=22222222';

Offline

#3 2015-05-12 11:52:57

profh
Member
Registered: 2010-07-02
Posts: 159

Re: about mutiply cookies

ab wrote:

Ctxt.OutCustomHeaders := Ctxt.OutCustomHeaders + #13#10+ 'Set-Cookie: a=1111111111; b=22222222';

with this code, just get the first one, 'b=22222222' is still missing.

Offline

#4 2015-05-12 12:50:51

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,183
Website

Re: about mutiply cookies

Try to add a ; as proposed by http://stackoverflow.com/q/2444022/458259

Ctxt.OutCustomHeaders := Ctxt.OutCustomHeaders + #13#10+ 
              'Set-Cookie: a=1111111111; b=22222222;';

Offline

#5 2015-05-12 14:46:23

profh
Member
Registered: 2010-07-02
Posts: 159

Re: about mutiply cookies

just get one cookie at the same time, the first one or the second one,  using each of the following code:

Ctxt.OutCustomHeaders := Ctxt.OutCustomHeaders + #13#10+ 'Set-Cookie: a=1111111111; b=22222222';
Ctxt.OutCustomHeaders := Ctxt.OutCustomHeaders + #13#10+ 'Set-Cookie: a=1111111111, b=22222222';
Ctxt.OutCustomHeaders := Ctxt.OutCustomHeaders + #13#10+ 'Set-Cookie: a=1111111111; b=22222222;';
Ctxt.OutCustomHeaders := Ctxt.OutCustomHeaders + #13#10+ 'Set-Cookie: a=1111111111;, b=22222222;';

Offline

#6 2015-05-12 14:47:56

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,183
Website

Re: about mutiply cookies

So I do not know how to circumvent the issue, which sounds to be related to http.sys and not mORMot itself.
Try to find how C#/.Net circumvent the problem on their side.

You could use the socket-based server instead, which allow full customization of the output headers.
But perhaps setting the cookies in several steps may be better.

Offline

#7 2015-05-12 23:53:12

profh
Member
Registered: 2010-07-02
Posts: 159

Re: about mutiply cookies

i got it, and i will use "Set-Cookie: myCookie=1111111,22222222" instead.

BTW, i have accomplished dws within mORMot, see http://synopse.info/forum/viewtopic.php?id=947.
thanks ab and Eric, you are really so great!

Offline

#8 2015-05-13 05:53:28

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,183
Website

Re: about mutiply cookies

Good!

Have you some code to share?

Offline

#9 2015-05-13 10:01:36

profh
Member
Registered: 2010-07-02
Posts: 159

Re: about mutiply cookies

function TMyW3Server.process(Ctxt: THttpServerRequest): cardinal;
var
  dwsfat:TFileAccessType;
  pathFileName : String;
  params : String;
  infoCache : TFileAccessInfoCache;
  request : THttpSysWebRequest;
  response : THttpSysWebResponse;
  fileAttribs : Cardinal;
...
begin
...
      if Pos('\.', pathFileName)>0 then
        // Directories or files beginning with a '.' are invisible
        fileAttribs:=INVALID_FILE_ATTRIBUTES
      else if not StrBeginsWith(pathFileName, FPath) then
      begin
        // request is outside base path
        Ctxt.OutContent:='<h1>Not authorized</h1>';
        Ctxt.OutContentType:=cHTMTL_UTF8_CONTENT_TYPE;
        Result:=401;
        Exit;
      end
      else
      begin
        {$WARN SYMBOL_PLATFORM OFF}
        fileAttribs:=GetFileAttributes(Pointer(pathFileName));
        if fileAttribs<>INVALID_FILE_ATTRIBUTES then begin
           if (fileAttribs and faHidden)<>0 then
              fileAttribs:=INVALID_FILE_ATTRIBUTES;
        end;
        {$WARN SYMBOL_PLATFORM ON}

      end;

      if fileAttribs=INVALID_FILE_ATTRIBUTES then
      begin
        Ctxt.OutContent:='<h1>Not found</h1>';
        Ctxt.OutContentType:=cHTMTL_UTF8_CONTENT_TYPE;
        Result:=404;
        Exit;
      end else if StrEndsWith(pathFileName, '.dws') then
      begin
        request := THttpSysWebRequest.Create;
        response := THttpSysWebResponse.Create;
        try
          request.ResetCookies;
          request.ResetQueryFields;
          request.ResetContentFields;
          request.ResetFields;
          request.PathInfo := rtntext;
          request.InURL := Ctxt.URL;
          request.InHeaders := Ctxt.InHeaders;
          request.InMethord := Ctxt.Method;
          request.QueryString := query;
          request.InContent := Ctxt.InContent;
          request.InContentType := Ctxt.InContentType;
          request.InRemoteIP := remoteip;
          request.InUserAgent := agent;
          request.InSecurity := 'No Security';
//           case Ctxt.AuthenticationStatus of
//              hrsSSL : request.Security:=Format('SSL, %d bits', [Ctxt.SecurityBytes*8]);
//           else
//              request.Security:='';
//           end;

           response.StatusCode:=200;
           response.ContentType:=cHTMTL_UTF8_CONTENT_TYPE;
             infoCache:=TFileAccessInfoCache(request.Custom);
          if infoCache=nil then begin
            infoCache:=TFileAccessInfoCache.Create(FileAccessInfoCacheSize);
            request.Custom:=infoCache;
            infoCache.CacheCounter:=FCacheCounter;
          end else if infoCache.CacheCounter<>FCacheCounter then begin
            infoCache.Flush;
            infoCache.CacheCounter:=FCacheCounter;
          end;

           FDWS.HandleDWS(pathFileName,dwsfat, request, response,[]);

           Ctxt.OutContent:=response.ContentData;
           Ctxt.OutContentType:=response.ContentType;
           Ctxt.OutCustomHeaders := Ctxt.OutCustomHeaders + #13#10 + nocacheheaderstr;

           if response.HasHeaders then
              Ctxt.OutCustomHeaders:=Ctxt.OutCustomHeaders + #13#10+
                                                       response.CompiledHeaders;
           Result:=response.StatusCode;
        finally
           request.Free;
           request := nil;
           response.Free;
           response := nil;
        end;
      end;
...
end;

Offline

Board footer

Powered by FluxBB