• home
  • forum
  • my
  • kt
  • download
  • Sessions

    Author: 2007-06-25 10:57:28 From:

    This chapter describes:

    • How ASP server uses cookies to pass an ID with the browser to link multiple HTTP requests together.
    • How ASP server offers the session object to ASP pages to share information between multiple requests or pages.
    • Different ways to pass information between requests or pages.
    • How Perl tools can be used to help debug ASP applications at the HTTP communication level.

    What Is a Session?

    session: A concept to represent a series of HTTP requests and responses exchanged between a specific Web browser and a specific Web server, see the following diagram:

               Server                Browser
    ID created  | <-- Request #1  --< |
                | >-- Response #1 --> | ID kept as cookie
                | <-- Request #2  --< | ID send back to server
                | >-- Response #2 --> |
                |     ......          |
    

    The session concept is managed by the server. When the first request comes from a browser on a new host, the server makes the beginning a new session, and assigns a new session ID. The session ID will be then send to the browser as cookie. The browser will remember this ID, and send the ID back to the server in the subsequent requests. When the server receives a request with session ID in them, it knows this is a continuation of an existing session.

    When the server receives a request from a browser on a new host (request without a session ID), the server not only creates a new session ID, it also creates a new session object associated with the session ID. See the next section for details.

    If there is no subsequent request coming back for a long time for a particular session ID, that session will be timed out. After the session has been timed out, if the browser comes back again with the associated session ID, the server will give an invalid session error.

    You will also get an invalid session error, if the browser send a request with a session ID associated with a session which has been terminated by a ASP page with session.Abandon() method.

    The "session" Object

    session: An object provided by the server to hold information and methods common to all ASP pages running under one session.

    • Contents: A collection object acting as a cache for different ASP pages to share information. Since "Contents" is the default collection, we write 'session.Contents("myVar")' as 'session("myVar")'.
    • Abandon(): A method to destroy the current session.
    • SessionID: A read only property to return the id of the current session.
    • TimeOut: A property to set timeout period on this session.
    • OnStart(): An event handler to be called when the first HTTP request comes from a new user.
    • OnEnd(): An event handler to be called the session is abandoned or timed out.

    Passing Values between Pages

    There are many ways to pass values from one pages to the next pages:

    • Putting values into session.Contents.
    • Putting values into application.Contents.
    • Putting values at the end of the redirect URL.

    In the following example, I have two ASP pages working together as a registration process. Here is the fist ASP page, reg_form.asp:

    <script language="vbscript" runat="server">
    '  reg_form.asp
    '  Copyright (c) 2002 by Dr. Herong Yang
    '  This ASP page presents a registration form, and collects the input
    '  data.
    '
       response.write("<html><body>")
       submit = request.QueryString.Item("submit")
       if submit = "Submit" then
          ' Collecting the input data
          session.Contents("url") = request.QueryString("url")
          session("email") = request.QueryString("email")
          application("first_name") = request.QueryString("first_name")
          response.Redirect("reg_done.asp?last_name=" & _
             request.QueryString("last_name"))
       else
          ' Presenting the registration form 
          response.write("<b>Registration Form</b>:<br/>")
          response.write("<form action=reg_form.asp method=get>")
          response.write("Firt Name:")
          response.write("<input type=text size=16 name=first_name><br/>")
          response.write("Last Name:")
          response.write("<input type=text size=16 name=last_name><br/>")
          response.write("Email:")
          response.write("<input type=text size=32 name=email><br/>")
          response.write("URL:")
          response.write("<input type=text size=32 name=url><br/>")
          response.write("<input type=submit name=submit value=Submit></br>")
          response.write("</form>")
          response.write("Your session ID is " & session.SessionID & "<br/>")
       end if
       response.write("</body></html>")
    </script>
    

    Here is the second ASP page, reg_done.asp:

    <script language="vbscript" runat="server">
    '  reg_done.asp
    '  Copyright (c) 2002 by Dr. Herong Yang
    '  This ASP page confirms a registration.
    '
       response.write("<html><body>")
       ' Save the data here
       response.write("<b>Thank you registrating with us</b>:<br/>")
       response.write("Firt Name:")
       response.write(application("first_name") & "<br/>" & vbNewLine)
       response.write("Last Name:")
       response.write(request.QueryString("last_name") & "<br/>" &vbNewLine)
       response.write("Email:")
       response.write(session("email") & "<br/>" & vbNewLine)
       response.write("URL:")
       response.write(session("url") & "<br/>" & vbNewLine)
       response.write("Your session ID is " & session.SessionID & "<br/>")
       response.write("</body></html>")
    </script>
    

    Request reg_form.asp with IE, and fill in the form with:

    Firt Name: Bill
    Last Name: Smith
    Email: bill@smith.com
    URL: www.smith.com
    

    Then click the Submit button, you will get the output of reg_done.asp:

    Thank you registrating with us:
    Firt Name:Bill
    Last Name:Smith
    Email:bill@smith.com
    URL:www.smith.com
    Your session ID is 42285894
    

    A couple of interesting notes:

    • reg_form.asp page is designed to serve two functions: presenting the form and collecting data from the submitted form.
    • When reg_form.asp is requested for the first time, there will be no "submit" in the QueryString. So the ASP script will continue with presenting-form section.
    • When the user finishes filling in the form, and clicks the Submit button, the browser will request reg_form.asp again and attach all the data in the form as QueryString. This behavior is specified by the <form> tag.
    • When reg_form.asp is requested by the Submit button, "submit" will have "Submit" as its value. So the ASP script will continue with the collecting-data section.
    • In the collecting-data section, I wanted to pass the collected data to another ASP page. Here I intentionally used three approaches to pass the data to reg-done.asp.
    • "url" and "email" are passed through the session.Contents collection. This is probably the best approach to pass data from one ASP page another.
    • "first_name" is passed through the application.Contents collection. This is not a safe approach to pass values on multi user server, because if there is another user filling this registration at this registration form as you, you could picked value saved by the other user.
    • "last_name" is passed as part of the redirect URL. This is a safe approach. But "last_name" is exposed to the user in the browser's URL area. So you should not use this approach to pass sensitive information from one ASP page to another.

    HTTP Communication Level Debugging

    If you have a problem with your ASP application at the HTTP communication level, one good debugging tool is the Perl LWP package. It can be used as a Web browser to talk to your ASP application, and to log everything at the HTTP communication level.

    Here is my sample Perl program, reg_client.pl, designed to work with my previous ASP registration application:

    #- reg_client.pl
    #- Copyright (c) 2002 by Dr. Herong Yang
      use LWP::Debug qw(+);
      use LWP::UserAgent;
      use HTTP::Cookies;
      ($url) = @ARGV;
      $url =  'http://localhost' unless $url;
      $ua = new LWP::UserAgent;
      $cookie_jar = HTTP::Cookies->new;
      &getForm();
      &submitForm();
      exit;
    sub getForm {
      $u =  $url.'/reg_form.asp';
      my $req = new HTTP::Request GET => $u;
      my $res = $ua->request($req);
      $req = $res->request();
      $cookie_jar->extract_cookies($res);
      &dump($req,$res);
    }
    sub submitForm {
      $u =  $url.'/reg_form.asp?first_name=Herong&submit=Submit';
      my $req = new HTTP::Request GET => $u;
      $cookie_jar->add_cookie_header($req);
      my $res = $ua->request($req);
      $req = $res->request();
      $cookie_jar->extract_cookies($res);
      &dump($req,$res);
    }
    sub dump {
       local ($req,$res) = @_;
       print "\nREQUEST-HEADERS\n";
       print $req->headers_as_string();
       print "\nREQUEST-CONTENT\n";
       print $req->content;
       if ($res->is_success) {
          print "\nRESPONSE-HEADERS\n";
          print $res->headers_as_string();
          print "\nRESPONSE-CONTENT\n";
          print $res->content;
       } else {
          print "\nRESPONSE-ERROR\n";
          print $res->error_as_HTML();
       }
    }
    

    A couple of notes to help you to understand this program:

    • "use LWP::Debug qw(+);" turns on the debugging at the highest level.
    • A "LWP::UserAgent" object is used to send a HTTP request to the HTTP server.
    • "HTTP:Request" objects are used to compose HTTP requests.
    • "$cookie_jar->extract_cookies($res);" is used to extract cookies from the response. This is very important, because ASP server is sending the session ID as a cookie to the client and expecting the client to send it back in the next request.
    • "$cookie_jar->add_cookie_header($req);" is used to add the cookies received from the previous response to the current request. One of the cookies is the session id, which is important for the ASP server to recognize the current request is a continuation of the previous request.

    If you run it with "reg_client.pl > client.out" in a command window, you will get the following in the window:

    LWP::UserAgent::new: ()
    LWP::UserAgent::request: ()
    LWP::UserAgent::simple_request: GET http://localhost/reg_form.asp
    LWP::UserAgent::_need_proxy: Not proxied
    LWP::Protocol::http::request: ()
    LWP::Protocol::http::request: GET /reg_form.asp HTTP/1.0
    Host: localhost
    User-Agent: libwww-perl/5.51
    
    LWP::Protocol::http::request: reading response
    LWP::Protocol::http::request: HTTP/1.1 200 OK
    Server: Microsoft-IIS/5.0
    Date: Sat, 28 Dec 2002 22:06:20 GMT
    Connection: Keep-Alive
    Content-Length: 383
    Content-Type: text/html
    Set-Cookie: ASPSESSIONIDQQGQQMCC=EFFFLMGAADIKNCGPKJDNHMCC; path=/
    Cache-control: private
    
    <html><body><b>Registration Form</b>:<br/><form action=reg_form.asp me
    thod=get>Firt Name:<input type=text size=16 name=first_name><br/>Last 
    Name:<input type=text size=16 name=last_name><br/>Email:<input type=te
    xt size=32 name=email><br/>URL:<input type=text size=32 name=url><br/>
    <input type=submit name=submit value=Submit></br></form>Your session I
    D is 113988957<br/></body></html>
    LWP::Protocol::http::request: HTTP/1.1 200 OK
    LWP::Protocol::collect: read 383 bytes
    LWP::UserAgent::request: Simple response: OK
    HTTP::Cookies::extract_cookies: Set cookie ASPSESSIONIDQQGQQMCC => EFF
    FLMGAADIKNCGPKJDNHMCC
    HTTP::Cookies::add_cookie_header: Checking localhost.local for cookies
    HTTP::Cookies::add_cookie_header: - checking cookie path=/
    HTTP::Cookies::add_cookie_header:  - checking cookie ASPSESSIONIDQQGQQ
    MCC=EFFFLMGAADIKNCGPKJDNHMCC
    HTTP::Cookies::add_cookie_header:    it's a match
    HTTP::Cookies::add_cookie_header: Checking .local for cookies
    LWP::UserAgent::request: ()
    LWP::UserAgent::simple_request: GET http://localhost/reg_form.asp?firs
    t_name=Herong&submit=Submit
    LWP::UserAgent::_need_proxy: Not proxied
    LWP::Protocol::http::request: ()
    LWP::Protocol::http::request: GET /reg_form.asp?first_name=Herong&
    submit=Submit HTTP/1.0
    Host: localhost
    User-Agent: libwww-perl/5.51
    Cookie: ASPSESSIONIDQQGQQMCC=EFFFLMGAADIKNCGPKJDNHMCC
    Cookie2: $Version=1
    
    LWP::Protocol::http::request: reading response
    LWP::Protocol::http::request: HTTP/1.1 302 Object moved
    Server: Microsoft-IIS/5.0
    Date: Sat, 28 Dec 2002 22:06:20 GMT
    Location: reg_done.asp?last_name=
    Connection: Keep-Alive
    Content-Length: 144
    Content-Type: text/html
    Cache-control: private
    
    <head><title>Object moved</title></head>
    <body><h1>Object Moved</h1>This object may be found <a HREF="reg_done.
    asp?last_name=">here</a>.</body>
    LWP::Protocol::http::request: HTTP/1.1 302 Object moved
    LWP::Protocol::collect: read 144 bytes
    LWP::UserAgent::request: Simple response: Found
    LWP::UserAgent::request: ()
    LWP::UserAgent::simple_request: GET http://localhost/reg_done.asp?
    last_name=
    
    LWP::UserAgent::_need_proxy: Not proxied
    LWP::Protocol::http::request: ()
    LWP::Protocol::http::request: GET /reg_done.asp?last_name= HTTP/1.0
    Host: localhost
    User-Agent: libwww-perl/5.51
    Cookie: ASPSESSIONIDQQGQQMCC=EFFFLMGAADIKNCGPKJDNHMCC
    Cookie2: $Version=1
    
    LWP::Protocol::http::request: reading response
    LWP::Protocol::http::request: HTTP/1.1 200 OK
    Server: Microsoft-IIS/5.0
    Date: Sat, 28 Dec 2002 22:06:20 GMT
    Connection: Keep-Alive
    Content-Length: 166
    Content-Type: text/html
    Cache-control: private
    
    <html><body><b>Thank you registrating with us</b>:<br/>Firt Name:Heron
    g<br/>Last Name:<br/>
    Email:<br/>
    URL:<br/>
    Your session ID is 113988957<br/></body></html>
    LWP::Protocol::http::request: HTTP/1.1 200 OK
    LWP::Protocol::collect: read 166 bytes
    LWP::UserAgent::request: Simple response: OK
    

    We have a lot of information here. Let's analyze it quickly.

    • My first request was sent as "GET /reg_form.asp HTTP/1.0".
    • The first response came back with a cookie as: "ASPSESSIONIDQQGQQMCC=EFFFLMGAADIKNCGPKJDNHMCC". Apparently, this is the session ID, but encrypted. In the response content, session ID is reported as: 113988957.
    • My second request was sent as "GET /reg_form.asp?first_name=Herong&submit=Submit HTTP/1.0", with two cookies. The first cookie was the ASP server session ID. The second cookie came from nowhere.
    • The second response was interesting. It had code of "302 Object moved", and a "Location" header line indicating the new URL. Obviously, this reponse was generated by the "redirect" command in my ASP page, reg_form.asp.
    • The LWP::UserAgent object is smart. It recognized the "Object moved" code, and automatically send another request with new URL location.
    • With no surprises, the second response came correctly. The ASP did recognize my session ID in my second and third request, because the session ID reported in the third response is the same: 113988957.
    • It is interesting to see that there was no cookie in the second response and third response. My guess is that ASP server saw the session ID in the seconde request and third request, so there was no need to put the session ID as cookie in the responses.

    discuss this topic to forum

    relation tutorial

    No relevant information

    New

    Hot