Response.Redirect via XMLHTTP causes new Session

Discussion in 'ASP General' started by mike.biang@gmail.com, Sep 21, 2006.

  1. Guest

    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?
    , Sep 21, 2006
    #1
    1. Advertising

  2. 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 Barrows [MVP], Sep 21, 2006
    #2
    1. Advertising

  3. Guest

    Bob Barrows [MVP] wrote:
    > 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
    , Sep 21, 2006
    #3
  4. <> wrote in message
    news:...
    >
    > Bob Barrows [MVP] wrote:
    > > 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?

    > Many thanks.
    > Mike Biang
    > Software Developmer
    > Cramer Development
    >
    >
    Anthony Jones, Sep 22, 2006
    #4
  5. 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.
    Bob Barrows [MVP], Sep 22, 2006
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Anthony Williams
    Replies:
    9
    Views:
    3,623
  2. Waldy
    Replies:
    6
    Views:
    405
    Waldy
    Nov 15, 2007
  3. Sal
    Replies:
    1
    Views:
    413
  4. Ron Howard
    Replies:
    2
    Views:
    520
    Ron Howard
    Aug 11, 2004
  5. yawnmoth

    Msxml*.XMLHTTP vs. Microsoft.XMLHTTP

    yawnmoth, Nov 7, 2006, in forum: Javascript
    Replies:
    11
    Views:
    386
    Matt Kruse
    Nov 9, 2006
Loading...

Share This Page