NOtherDev
NOtherDev

Reputation: 9672

Displaying content of 302 Redirect - or HTTP-compliant waiting screen

I'd like to have a waiting screen in HTML drawn before user enters the site because of some long-running auth processes that are out of my control. I'd like that screen to be fully HTTP-compliant, i.e.:

The only "third way" I can see is to rely on standard 302 redirections. But I'll need the actual content of the request that resulted in 302 response to be rendered to the user for the time of waiting for the second request (with "please wait" info or something). In most (all?) cases, browsers do not draw the content of those requests, just go and wait for the data from redirection.

The questions are:

  1. in what cases the content of 302 Redirect request is rendered? is it possible to force browsers to render it before redirecting?
  2. is there another way to approach the problem without breaking the HTTP protocol? or is 200 OK status for the page without any content initially not breaking the protocol?

Upvotes: 2

Views: 3943

Answers (2)

rluta
rluta

Reputation: 6897

The easiest solution would be to use a multipart/x-mixed-replace content type response with the first part served being the temporary waiting page and the secondary part the actual final content. This content can be correctly served with a 200 OK.

The initial response should look like this and should be flushed as soon as possible to the user while keeping the HTTP connection open

HTTP/1.1 200 OK
Content-Type: multipart/x-mixed-replace;boundary=MYBOUNDARYSTRING

--MYBOUNDARYSTRING
Content-Type: text/html

<html><body><!-- your waiting page content here --></body></html>
--MYBOUNDARYSTRING

when your final page is ready, you just have to serve a second HTML part that will be displayed instead of the first one

Content-Type: text/html

<html><body><!-- your final page here --></body></html>
--MYBOUNDARYSTRING
--

The final '--' indicates to the browser that the content is complete and that there are no additional parts.

Most modern browsers will correctly replace the first content part with the second when it's available but this is user agent specific and older versions of Internet Explorer are known not to handle this MIME type correctly

Alternate solution

You can implement the same technique of chunked response with a single HTML document and rely on Javascript and/or CSS to visually substitute content for the user.

For example:

The initial response is flushed immediately:

HTTP/1.1 200 OK
Content-Type: text/html
Transfer-Encoding: chunked

6E
<html><head><!-- load my CSS and JS files --></head><body>
<div id="waiting"><!-- my waiting content --></div>

when your final content is ready, send a new chunk:

3E
<div id="final"><!-- my final content --></div></body></html>
0

To ensure that your #final div is displayed instead of #waiting, you can either:

  • add something like <script>$("#waiting").hide();</script> just before your closing </body> tag
  • or use CSS positioning to ensure that #final is displayed above #waiting, something like

    <style> 
    body { position: relative; margin: 0; padding: 0 }
    body > div { position: absolute; top: 0; left: 0; width: 100% }
    #waiting { z-index: 0 }
    #final { z-index: 1 }
    </style>
    

Upvotes: 2

Jan Vlcinsky
Jan Vlcinsky

Reputation: 44112

Short answer to your question might be "not practically possible".

But you might be lucky.

Displaying content of 302 - not possible

Specification requires that client immediately goes to the new url, specified in the 302 response. No way to wait, now notion of a response to be rendered.

Someone must be waiting - server side option

You are expecting that some process shall wait until the lengthy authentication process is finished.

Such a process must be able to

1) initiate the authentication process

2) render some "waiting" page

3) check result of the authentication process

4) after the authentication succeeds, redirect you there

Step 1 - initiating the authentication process from server side can be real problem as you will not have access to cookies and other authentication resources for target site. You are serving another domain, so you will not have a chance to read this security related stuff, which only your browser knows. But I will assume, you will manage somehow (asking your user to tell you this sort of information earlier).

Then your web server would start authentication process for your client. This is rather strange, but you might try to do so by initiating an http request to the target site from your server. This must be done asynchronously as we need to do also some other things like providing your user something to render.

Step 2 - rendering some "waiting page. To render something on browser side, you may return a page with 200 status code. I do not think, this is breaking http. You would return some nice "wait a moment" content plus add "Refresh" header to initiate page refresh within short time (like in 2 seconds or so).

Step 3 - check status of authentication process: your server will get another request resulting from Refresh form previous step. Your server must know context of this activity , probably by session id. In this context, it will find, that there is a process of authentication running. If authentication is not yet completed, repeat Step 2.

Step 4 - (still being on your server) If authentication is complete, gather needed information needed for your client to connect as authenticated user to target server, and return 302 with a link leading to target server. This assumes, the link allows to connect in "authenticated" manner.

This approach is likely to fail in steps 1 and/or 4. But there might be situations it would work (depends on target server).

Waiting process running within your client browser

Another option for the process waiting for complete authentication is within your browser. Using AJAX process is not breaking HTTP, it is just another process running in parallel.

You could render some "waiting" content and then try to connect by AJAX to the target server.

However, here you are trying to do sort of cross-site scripting, so unless the target server does not allow you to make such a request (search for CORS, your web browser is running in context of another domain), web browser will reject such a request.

Assuming you succeed, your AJAX process will try to connect, and as soon as it succeeds, it will manage redirecting the page to the target one.

Your server in role of proxy

You might modify the first proposed solution - "server side option", by taking over all the communication with target server and providing similar content to to your client.

Conclusions

Clarify roles of browser, your server and target server

It would be great, if you draw Sequence diagram with lifelines "Browser", "MyServer", "TargetServer".

All the proposed solutions are dangerous

The biggest problem is, that if you want to get authenticated for other domain, than the one you serve, you are asking your user to share with you very private information. Browsers will do their best to prevent such a behaviour, your user might be willing to share such information with your app, but such behaviour is very tricky.

Trying to solve a problem out of your reach is very tricky

To me it sounds, you are trying somehow resolving a slow authentication process on a domain, you do not have control of. This often leads to very desperate situation "I do not have enough power to do it, but I have to". Good arguments for rejecting such a requirement could be "It would require breaking few security related standards."

Upvotes: 5

Related Questions