libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

sessions.inc (3336B)


      1 This chapter discusses how one should manage sessions, that is, share state between multiple
      2 HTTP requests from the same user.  We use a simple example where the user submits multiple
      3 forms and the server is supposed to accumulate state from all of these forms.  Naturally, as
      4 this is a network protocol, our session mechanism must support having many users with
      5 many concurrent sessions at the same time.
      6 
      7 In order to track users, we use a simple session cookie.  A session cookie expires when the
      8 user closes the browser.  Changing from session cookies to persistent cookies only requires
      9 adding an expiration time to the cookie.  The server creates a fresh session cookie whenever
     10 a request without a cookie is received, or if the supplied session cookie is not known to
     11 the server.
     12 
     13 @heading Looking up the cookie
     14 
     15 Since MHD parses the HTTP cookie header for us, looking up an existing cookie
     16 is straightforward:
     17 
     18 @verbatim
     19 const char *value;
     20 
     21 value = MHD_lookup_connection_value (connection,
     22                                      MHD_COOKIE_KIND,
     23                                      "KEY");
     24 @end verbatim
     25 
     26 Here, "KEY" is the name we chose for our session cookie.
     27 
     28 
     29 @heading Setting the cookie header
     30 
     31 MHD requires the user to provide the full cookie format string in order to set
     32 cookies.  In order to generate a unique cookie, our example creates a random
     33 64-character text string to be used as the value of the cookie:
     34 
     35 @verbatim
     36 char value[128];
     37 char raw_value[65];
     38 
     39 for (unsigned int i=0;i<sizeof (raw_value);i++)
     40   raw_value = 'A' + (rand () % 26); /* bad PRNG! */
     41 raw_value[64] = '\0';
     42 snprintf (value, sizeof (value),
     43           "%s=%s",
     44           "KEY",
     45           raw_value);
     46 @end verbatim
     47 
     48 Given this cookie value, we can then set the cookie header in our HTTP response
     49 as follows:
     50 
     51 @verbatim
     52 assert (MHD_YES ==
     53         MHD_set_connection_value (connection,
     54                                   MHD_HEADER_KIND,
     55                                   MHD_HTTP_HEADER_SET_COOKIE,
     56                                   value));
     57 @end verbatim
     58 
     59 
     60 @heading Remark: Session expiration
     61 
     62 It is of course possible that clients stop their interaction with the
     63 server at any time.  In order to avoid using too much storage, the
     64 server must thus discard inactive sessions at some point.  Our example
     65 implements this by discarding inactive sessions after a certain amount
     66 of time.  Alternatively, the implementation may limit the total number
     67 of active sessions.  Which bounds are used for idle sessions or the
     68 total number of sessions obviously depends largely on the type of
     69 the application and available server resources.
     70 
     71 @heading Example code
     72 
     73 A sample application implementing a website with multiple
     74 forms (which are dynamically created using values from previous
     75 POST requests from the same session) is available
     76 as the example @code{sessions.c}.
     77 
     78 Note that the example uses a simple, $O(n)$ linked list traversal to
     79 look up sessions and to expire old sessions.  Using a hash table and a
     80 heap would be more appropriate if a large number of concurrent
     81 sessions is expected.
     82 
     83 @heading Remarks
     84 
     85 Naturally, it is quite conceivable to store session data in a database
     86 instead of in memory.  Still, having mechanisms to expire data
     87 associated with long-time idle sessions (where the business process
     88 has still not finished) is likely a good idea.