0

This is in the context of my bismon program (GPLv3+, on github, still unreleased, alpha-stage), which is mostly a single-page web application (with a garbage collected DSL in it) which uses the libonion HTTP server library (so bismon is a specialized web server). Most of the HTML + Javascript + C code of bismon is (or will be and should be) generated (it is a reflexive and bootstrapped DSL). BTW, I am writing a preliminary technical report on it (an early draft of which, very incomplete, is here in fall 2018), on which feedback by email to me would be appreciated.

A web server can manage sessions with cookies. So it would create cookie for each session (after some HTML login form has been presented and successfully filled). On the server side, each cookie is associated with session-specific data.

However, the same session can be visible in several tabs (of e.g. a Firefox browser). Just because the end-user would (for example) "Open Link in New Tab" (with the right-button mouse click) on a given existing hyperlink. My web server would then receive new HTTP requests (probably some GET one), but I don't understand well enough all the details of HTTP to understand what (probably which HTTP request header field) is carrying that information.

What motivates my question is garbage collection (distributed GC of my application, viewed as a multi-tiered, continuation-based, application like ocsigen is, so running both on the web server side and in the browser). Conceptually all of the data both in server and in the browser has to be garbage collected by bismon and lives together (of course I know that the web is about distributed & client/server processing). With a single tab it is just keeping appropriate references (to what is displayed by the browser) in the session data (server side). But with additional tabs for the same session things are more complex. Queinnec's work on Continuations and web servers, and the Modeling Web Interactions paper by Graunke et al., are insightful.

To rephrase my question: what distinguish, in HTTP requests providing from the same browser instance (e.g. the same Firefox process on my Linux desktop) with the same cookie, the various tabs shown by it (to the same web server)?

3

As cookies or session data are shared between all tabs of the same site, they cannot be used to identify tabs.

The easiest way to distinguish separate “sessions” with the same cookies is to encode session state in the URLs. For every response that your server sends, any links in that response contain a token that allows the resulting request to be correlated with that previous response. Instead of abstract tokens, the URL might also encode the complete UI state.

This approach was used in some old Java web applications before client-side UI with JavaScript became viable. As the whole HTML was rendered server-side, the server needed to know the exact UI state, e.g. which tabs are currently selected or which nodes are expanded in a tree view.

An example using abstract tokens:

  • Client tab 1: GET /foo HTTP/1.1

  • Server responds with a document where all links contain a token:

    HTTP/1.1 200 OK
    Content-Type: text/html
    
    <a href="/foo?token=123abc"> reload </a>
    <a href="/bar?token=123abc"> different page </a>
    
  • Client opens reload-link in a new tab: GET /foo?token=123abc HTTP/1.1

  • Server responds with a new token:

    HTTP/1.1 200 OK
    Content-Type: text/html
    
    <a href="/foo?token=234bcd"> reload </a>
    <a href="/bar?token=234bcd"> different page </a>
    

The browser now has two sets of tokens, and the server will be able to tell from which page a request has been made. This could be visualized as a tree of histories:

              /foo
                |
        /foo?token=123abc
          /            \
/foo?token=23bcd    /foo?token=345cde
          |
/bar?token=456def

(Similar techniques are used to enforce that a request was made from a particular page, e.g. to defend against CSRF. Anti-CSRF tokens are nonces, so any branching history would be an error.)

This approach still has a couple of restrictions. For example, it makes any caching impossible. More notably, it is not possible for the server to see a difference between making two request from the same tab which opens another tab, versus making a request, then going back in the browser history to the previous page and making another request.

The conceptual problem is that a distributed system such as the internet is very ill-suited for maintaining shared state across nodes. HTTP in particular is a completely stateless protocol which has no concept of an active connection. (Modern HTTP actually features stateful transport protocols, but each application-level request–response pair is still very much stateless.)

What HTTP is able to do instead is to transfer state between the server and the client, which is the insight that was later formalized as the RESTful style. I.e. the complete relevant state of the client must be encoded in the request URL, headers (incl. cookies), or request payload.

The server should maintain zero per-connection state because there are no connections, and because it should receive relevant state from the client. Therefore, the topic of garbage collection is also circumvented. In a RESTful design the client may cause the server to store or modify resources that can be accessed later, but there is no way for the server to tell whether these resources are referenced externally. Instead, you would just delete transient resources after some time span has elapsed without access.

The unsatisfactory result is that it's really hard to build multi-tab web applications that work as expected. Most web apps will either not account for this case and simply break when session state is modified from multiple tabs, or are so thoroughly client side that there is no session state/cookies besides a cookie indicating whether the user is logged in. In the latter case, the client itself may be stateful, and any communication with the server would happen through Ajax requests which now don't have to encode the complete client state. I.e. there would be no ordinary hyperlinks for the user to follow themselves.

  • Thanks. I think it could answer my question. Very insightful. – Basile Starynkevitch Sep 16 '18 at 9:56
  • BTW, if you know any academic paper that I could cite explaining all that, I would be happy – Basile Starynkevitch Sep 16 '18 at 10:13
  • I'm waiting a few days for other answers, but it is likely that I would accept this one! – Basile Starynkevitch Sep 16 '18 at 10:14
  • 1
    @BasileStarynkevitch I'm not aware of the current research in that area, but Roy Fielding's work on REST is highly relevant. E.g. in Principled Design of the Modern Web Architecure (2002): “We next add a constraint to the client-server interaction: communication must be stateless in nature, […] such that each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. Session state is therefore kept entirely on the client.” This is motivated by scalability, e.g. caching and load balancing. – amon Sep 16 '18 at 11:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.