Home All Groups Group Topic Archive Search About

Response.Redirect via XMLHTTP causes new Session



Author
21 Sep 2006 2:05 PM
mike.biang
I have an ASP page that is using an XMLHTTP object to request various
pages from my server.  I   keep a single session throughout the XMLHTTP
requests by bassing the ASPSESSIONID cookie through the XMLHTTP object.

However, when the page requested through the XML object makes a
<%Response.Redirect()%>
call, a new session is created each time.

Is this a flaw in the XMLHTTP Object?  How can I force the session to
remain the same after a Response.Redirect call?

Author
21 Sep 2006 3:08 PM
Bob Barrows [MVP]
mike.bi***@gmail.com wrote:
> I have an ASP page that is using an XMLHTTP object to request various
> pages from my server.
Is this being done in client-side code? or are you really using the
XMLHTTPServer object?

> I  keep a single session throughout the
> XMLHTTP requests by bassing the ASPSESSIONID cookie through the
> XMLHTTP object.

If using XMLHTTP from client-side code, I do not believe this is
necessary.
>
> However, when the page requested through the XML object makes a
> <%Response.Redirect()%>

> call, a new session is created each time.
>
This test fails to duplicate your behavior:

xmlhttp_session.asp:
<%
session("test")="Z"
%>
<HTML>
<HEAD>
<script type="text/javascript">
function test()
{
  var oHTTP = new ActiveXObject("Microsoft.XMLHTTP");
  oHTTP.open("POST","getsessionval.asp", false);
  oHTTP.send();
  alert(oHTTP.responseText)
}
</script>
</HEAD>
<BODY>
<INPUT type="button" value="Button" id=button1 name=button1
onclick="test();">
</BODY>
</HTML>


getsessionval.asp:
<%response.redirect "getsessionval2.asp"%>

getsessionval2.asp:
<%response.write session("test")%>

Clicking the button results in "Z" being alerted.

Have I just wasted my time? Are you really using XMLHTTPServer in
server-side code?

--
Microsoft MVP -- ASP/ASP.NET
Please reply to the newsgroup. The email account listed in my From
header is my spam trap, so I don't check it very often. You will get a
quicker response by posting to the newsgroup.
Author
21 Sep 2006 3:32 PM
mike.biang
Bob Barrows [MVP] wrote:
Show quote
> mike.bi***@gmail.com wrote:
> > I have an ASP page that is using an XMLHTTP object to request various
> > pages from my server.
> Is this being done in client-side code? or are you really using the
> XMLHTTPServer object?
>
> > I  keep a single session throughout the
> > XMLHTTP requests by bassing the ASPSESSIONID cookie through the
> > XMLHTTP object.
>
> If using XMLHTTP from client-side code, I do not believe this is
> necessary.
> >
> > However, when the page requested through the XML object makes a
> > <%Response.Redirect()%>
>
> > call, a new session is created each time.
> >
> This test fails to duplicate your behavior:
>
> xmlhttp_session.asp:
> <%
> session("test")="Z"
> %>
> <HTML>
> <HEAD>
> <script type="text/javascript">
>  function test()
>  {
>   var oHTTP = new ActiveXObject("Microsoft.XMLHTTP");
>   oHTTP.open("POST","getsessionval.asp", false);
>   oHTTP.send();
>   alert(oHTTP.responseText)
>  }
> </script>
> </HEAD>
> <BODY>
> <INPUT type="button" value="Button" id=button1 name=button1
> onclick="test();">
> </BODY>
> </HTML>
>
>
> getsessionval.asp:
> <%response.redirect "getsessionval2.asp"%>
>
> getsessionval2.asp:
> <%response.write session("test")%>
>
> Clicking the button results in "Z" being alerted.
>
> Have I just wasted my time? Are you really using XMLHTTPServer in
> server-side code?
>
> --
> Microsoft MVP -- ASP/ASP.NET
> Please reply to the newsgroup. The email account listed in my From
> header is my spam trap, so I don't check it very often. You will get a
> quicker response by posting to the newsgroup.

Bob, I apologize for not making myself more clear.  I am indeed using
ServerXMLHTTP.

Setting up an example isn't necessarily simple, but I'll give it a
shot.

Page1.asp:
<%
<!--#include file="includes/classes/cookie.asp" -->
Function ProcessResponseHeaders(sHeaders)
    Set reCookies = New RegExp
    reCookies.IgnoreCase = true
    reCookies.Global = true
    reCookies.Pattern = "Set-Cookie: [^\n]*\n"
    Set oMatches = reCookies.Execute(sHeaders)
    for each oMatch in oMatches
        Set oCookie = New Cookie
        oCookie.ParseCookieHeader(oMatch.Value)
        if(oCookie.IsSessionCookie)then
            Session("CookieName") = oCookie.Name
            Session("CookieValue") = oCookie.Value
        else
            oCookie.WriteToResponse()
        end if
    next
End Function

sSessionCookie = Session("CookieName")
sSessionCookieValue = Session("CookieValue")

Set oHTTPpost = Server.CreateObject("Msxml2.ServerXMLHTTP")
oHTTPpost.open "GET", "http:/url.tld/testsession.asp" , false
oHTTPpost.SetRequestHeader "Cookie", sSessionCookie & "=" &
sSessionCookieValue
oHTTPpost.send(null)
sReturnValue = oHTTPpost.responseText
ProcessResponseHeaders(oHTTPPost.GetAllResponseHeaders)
Response.Write(sReturnValue)
%>

testsession.asp
<%
Response.Redirect("redirecttarget.asp")
Response.Write(Session.SessionID)
%>

redirecttarget.asp
<%
Response.Write(Session.SessionID)
%>

cookie.asp:
<%
Class Cookie
    Public Name
    Public Value
    Public Expires
    Public Path

    Private Sub Class_Initialize
        Me.Name = ""
        Me.Value = ""
        Me.Expires = ""
        Me.Path = ""
    End Sub

    Private Sub Class_Terminate

    End Sub

    Public Function ParseCookieHeader(sHeader)
        Set reCookie = New RegExp
        reCookie.IgnoreCase = true
        reCookie.Global = true
        reCookie.Pattern = "[^\s]*=[^\n;]*"
        Set oMatches = reCookie.Execute(sHeader)
        for each oMatch in oMatches
            a_sMatch = split(oMatch.value,"=")
            sName = a_sMatch(0)
            sValue = a_sMatch(1)
            select case lcase(sName)
                case "path": Me.Path =  URLDecode(sValue)
                case "expires": Me.Expires =  URLDecode(sValue)
                case else: Me.Name = URLDecode(sName)
                           Me.Value = URLDecode(sValue)
            end select
        next
    End Function

    Public Function WriteToResponse()
        if(Me.Name <> "")then
            Response.Cookies(Me.Name) = Me.Value
            if(Me.Path <> "")then
                Response.Cookies(Me.Name).Path = Me.Path
            end if
            if(Me.Expires <> "")then
                Response.Cookies(Me.Name).Expires = Me.Expires
            end if
        end if
    End Function

    Function URLDecode(sConvert)
        Dim aSplit
        Dim sOutput
        Dim I
        If IsNull(sConvert) Then
           URLDecode = ""
           Exit Function
        End If

        ' convert all pluses to spaces
        sOutput = REPLACE(sConvert, "+", " ")

        ' next convert %hexdigits to the character
        aSplit = Split(sOutput, "%")

        If IsArray(aSplit) Then
          sOutput = aSplit(0)
          For I = 0 to UBound(aSplit) - 1
            sOutput = sOutput & _
              Chr("&H" & Left(aSplit(i + 1), 2)) &_
              Right(aSplit(i + 1), Len(aSplit(i + 1)) - 2)
          Next
        End If

        URLDecode = sOutput
    End Function
End Class
%>

So, in this example, page1.asp requests testsession.asp via the
ServerXMLTTP object.  page1.asp maintains the ASP session ID by passing
the ASPSESSIONID cookie to through the ServerXMLHTTP object.
ProcessFunctionHeaders and the cookie class are responsible for this.
Once requested, testsession.asp writes a redirect header to the client
(in this case the ServerXMLHTTP object).  The client then redirects to
redirecttarget.asp, which prints the current session id.)  As you will
see, the value printed by page1.asp will increment with ever refresh of
page1.asp. Commenting the first line of testsession.asp (commenting out
the redirect) causes the sessionid to remain constant with every
refresh of page1.asp.

This leads me to believe that the ServerXMLHTTP object fails to pass
the cookies to the server if the server has responded with a 302
redirect header (issued by response.redirect).  Can anyone confirm or
deny this issue?

Many thanks.
Mike Biang
Software Developmer
Cramer Development
mike.bi***@gmail.com
Author
22 Sep 2006 8:51 AM
Anthony Jones
<mike.bi***@gmail.com> wrote in message
Show quote
news:1158852732.629403.287340@i42g2000cwa.googlegroups.com...
>
> Bob Barrows [MVP] wrote:
> > mike.bi***@gmail.com wrote:
> > > I have an ASP page that is using an XMLHTTP object to request various
> > > pages from my server.
> > Is this being done in client-side code? or are you really using the
> > XMLHTTPServer object?
> >
> > > I  keep a single session throughout the
> > > XMLHTTP requests by bassing the ASPSESSIONID cookie through the
> > > XMLHTTP object.
> >
> > If using XMLHTTP from client-side code, I do not believe this is
> > necessary.
> > >
> > > However, when the page requested through the XML object makes a
> > > <%Response.Redirect()%>
> >
> > > call, a new session is created each time.
> > >
> > This test fails to duplicate your behavior:
> >
> > xmlhttp_session.asp:
> > <%
> > session("test")="Z"
> > %>
> > <HTML>
> > <HEAD>
> > <script type="text/javascript">
> >  function test()
> >  {
> >   var oHTTP = new ActiveXObject("Microsoft.XMLHTTP");
> >   oHTTP.open("POST","getsessionval.asp", false);
> >   oHTTP.send();
> >   alert(oHTTP.responseText)
> >  }
> > </script>
> > </HEAD>
> > <BODY>
> > <INPUT type="button" value="Button" id=button1 name=button1
> > onclick="test();">
> > </BODY>
> > </HTML>
> >
> >
> > getsessionval.asp:
> > <%response.redirect "getsessionval2.asp"%>
> >
> > getsessionval2.asp:
> > <%response.write session("test")%>
> >
> > Clicking the button results in "Z" being alerted.
> >
> > Have I just wasted my time? Are you really using XMLHTTPServer in
> > server-side code?
> >
> > --
> > Microsoft MVP -- ASP/ASP.NET
> > Please reply to the newsgroup. The email account listed in my From
> > header is my spam trap, so I don't check it very often. You will get a
> > quicker response by posting to the newsgroup.
>
> Bob, I apologize for not making myself more clear.  I am indeed using
> ServerXMLHTTP.
>
> Setting up an example isn't necessarily simple, but I'll give it a
> shot.
>
> Page1.asp:
> <%
> <!--#include file="includes/classes/cookie.asp" -->
> Function ProcessResponseHeaders(sHeaders)
> Set reCookies = New RegExp
> reCookies.IgnoreCase = true
> reCookies.Global = true
> reCookies.Pattern = "Set-Cookie: [^\n]*\n"
> Set oMatches = reCookies.Execute(sHeaders)
> for each oMatch in oMatches
> Set oCookie = New Cookie
> oCookie.ParseCookieHeader(oMatch.Value)
> if(oCookie.IsSessionCookie)then
> Session("CookieName") = oCookie.Name
> Session("CookieValue") = oCookie.Value
> else
> oCookie.WriteToResponse()
> end if
> next
> End Function
>
> sSessionCookie = Session("CookieName")
> sSessionCookieValue = Session("CookieValue")
>
> Set oHTTPpost = Server.CreateObject("Msxml2.ServerXMLHTTP")
> oHTTPpost.open "GET", "http:/url.tld/testsession.asp" , false
> oHTTPpost.SetRequestHeader "Cookie", sSessionCookie & "=" &
> sSessionCookieValue
> oHTTPpost.send(null)
> sReturnValue = oHTTPpost.responseText
> ProcessResponseHeaders(oHTTPPost.GetAllResponseHeaders)
> Response.Write(sReturnValue)
> %>
>
> testsession.asp
> <%
> Response.Redirect("redirecttarget.asp")
> Response.Write(Session.SessionID)
> %>
>
> redirecttarget.asp
> <%
> Response.Write(Session.SessionID)
> %>
>
> cookie.asp:
> <%
> Class Cookie
> Public Name
> Public Value
> Public Expires
> Public Path
>
> Private Sub Class_Initialize
> Me.Name = ""
> Me.Value = ""
> Me.Expires = ""
> Me.Path = ""
> End Sub
>
> Private Sub Class_Terminate
>
> End Sub
>
> Public Function ParseCookieHeader(sHeader)
> Set reCookie = New RegExp
> reCookie.IgnoreCase = true
> reCookie.Global = true
> reCookie.Pattern = "[^\s]*=[^\n;]*"
> Set oMatches = reCookie.Execute(sHeader)
> for each oMatch in oMatches
> a_sMatch = split(oMatch.value,"=")
> sName = a_sMatch(0)
> sValue = a_sMatch(1)
> select case lcase(sName)
> case "path": Me.Path =  URLDecode(sValue)
> case "expires": Me.Expires =  URLDecode(sValue)
> case else: Me.Name = URLDecode(sName)
>    Me.Value = URLDecode(sValue)
> end select
> next
> End Function
>
> Public Function WriteToResponse()
> if(Me.Name <> "")then
> Response.Cookies(Me.Name) = Me.Value
> if(Me.Path <> "")then
> Response.Cookies(Me.Name).Path = Me.Path
> end if
> if(Me.Expires <> "")then
> Response.Cookies(Me.Name).Expires = Me.Expires
> end if
> end if
> End Function
>
> Function URLDecode(sConvert)
> Dim aSplit
> Dim sOutput
> Dim I
> If IsNull(sConvert) Then
>    URLDecode = ""
>    Exit Function
> End If
>
> ' convert all pluses to spaces
> sOutput = REPLACE(sConvert, "+", " ")
>
> ' next convert %hexdigits to the character
> aSplit = Split(sOutput, "%")
>
> If IsArray(aSplit) Then
>   sOutput = aSplit(0)
>   For I = 0 to UBound(aSplit) - 1
> sOutput = sOutput & _
>   Chr("&H" & Left(aSplit(i + 1), 2)) &_
>   Right(aSplit(i + 1), Len(aSplit(i + 1)) - 2)
>   Next
> End If
>
> URLDecode = sOutput
> End Function
> End Class
> %>
>
> So, in this example, page1.asp requests testsession.asp via the
> ServerXMLTTP object.  page1.asp maintains the ASP session ID by passing
> the ASPSESSIONID cookie to through the ServerXMLHTTP object.
> ProcessFunctionHeaders and the cookie class are responsible for this.
> Once requested, testsession.asp writes a redirect header to the client
> (in this case the ServerXMLHTTP object).  The client then redirects to
> redirecttarget.asp, which prints the current session id.)  As you will
> see, the value printed by page1.asp will increment with ever refresh of
> page1.asp. Commenting the first line of testsession.asp (commenting out
> the redirect) causes the sessionid to remain constant with every
> refresh of page1.asp.
>
> This leads me to believe that the ServerXMLHTTP object fails to pass
> the cookies to the server if the server has responded with a 302
> redirect header (issued by response.redirect).  Can anyone confirm or
> deny this issue?
>

Here is a simple test I've done:-

Test.asp:-
<%Response.Redirect("Test2.asp")%>

Test2.asp:-
Hello World

Test.vbs:-
Option Explicit

Dim oXH : Set oXH = CreateObject("MSXML2.ServerXMLHTTP")
oXH.Open "GET", "http://myserver/test/test.asp", False
oXH.Send

MsgBox oXH.responseText


Watching the http traffic I see that the 302 from the server carries the
Set-Cookie: ASPSESSIONxxxxxxxx=xxxxx; and the subsequent request to
test2.asp generated internally be WinHTTP carries this cookie in the
request.  So it would seem that ServerXMLHTTP does pass on cookies received
in these cases.

I used this unbelievably useful (and free) tool:-
http://www.fiddlertool.com/fiddler/version.asp

To monitor the http traffic.  Since this is in effect a proxy server so once
fired up you need to let WinHTTP know what the proxy settings are.  Use the
command line 'proxycfg -u' to make sure WinHTTP traffic runs through it.  Be
sure to use 'proxycfg -d' after you done to remove the settings.



Here are some questions:-

MSXML3 is installed in replace mode? Try using the specific version of the
prog ID  MSXML2.ServerXMLHTTP.3.0.

Have you got the latest version of msxml3?  There are some KBs refering to
older releases om msxml3 which may be relevant.
For example http://support.microsoft.com/kb/326847/EN-US/ not an exact match
but close.

If you install msxml6 and use 6 specific progIDs do you still get the
problem?

Show quote
> Many thanks.
> Mike Biang
> Software Developmer
> Cramer Development
> mike.bi***@gmail.com
>
Author
22 Sep 2006 12:21 PM
Bob Barrows [MVP]
Anthony Jones wrote:

Anthony, could you contact me offline?

--
Microsoft MVP -- ASP/ASP.NET
Please reply to the newsgroup. The email account listed in my From
header is my spam trap, so I don't check it very often. You will get a
quicker response by posting to the newsgroup.

AddThis Social Bookmark Button