title: IE 10 pending XMLHttpRequest for 6 minutes and then answers the request (CRSF implementation with AngularJS)
body: <p><strong>Task description</strong></p>
  
  <p>I implemented CRSF protection for my angular application. The server checks if the crsf token is placed in the header 'X-CSRF-TOKEN' of the request. If not it sends a http response 403.</p>
  
  <p>Ïn my client I intercept all requests and check if a http response 403 is returned. In this case I send a HEAD request in order to get the crsf token from the server which is returned in the header 'X-CSRF-TOKEN' of the response. </p>
  
  <p>After getting the token from the server, I resend the original request with the given crsf token in the header 'X-CSRF-TOKEN'.</p>
  
  <p><strong>Problem description</strong></p>
  
  <p>This works fine with all browsers except with internet explorer (tried IE 9 and 10). Locally (without proxy and firewall) it also works with internet explorer. But in our production environment the head request is <strong>pending for 360s, but then returns the expected response</strong>.</p>
  
  <p>I'm not sure what is happening. Why does it work on localhost but not in the production environment? Could it be a problem of the proxy? But why it works with all other browsers (chrome, firefox, ...)? And even after 6 minutes the IE is getting a correct answer and proceeds as expected. For me it does not look like a proxy problem. So, is it a problem with the IE? But why is it working on localhost?</p>
  
  <p>The only difference in the request of IE and other browser is the referer in the header:
   - in IE the referer looks like <a href="http://url/context-root/#/login" rel="nofollow">http://url/context-root/#/login</a>
   - in other browsers the referer looks like <a href="http://url/context-root/" rel="nofollow">http://url/context-root/</a></p>
  
  <p>The difference between local environment and production environment is, that the proxy intercepts the requests and does some context-rewriting and opens a https tunnel. The server actually uses http, the proxy is then tunneling the requests.</p>
  
  <p>Has anyone an idea what the problem could be?</p>
  
  <p>Here is my angular module which registers the http-interceptor:</p>
  
  <pre><code>'use strict';
  (function () {
       angular.module('csrf-token-interceptor', [])
           .config(function ($httpProvider) {
               var csrfToken = { headerName: 'X-CSRF-TOKEN', token: null };
               var getCsrfToken = function () {
                   var xhr = new XMLHttpRequest();
                   xhr.open('head', '/context-root/index.html?id=' + new Date().toString(), false);
                   xhr.send();
                   return { headerName: 'X-CSRF-TOKEN', token: xhr.getResponseHeader('X-CSRF-TOKEN') };
               };
               var numRetries = 0;
               var MAX_RETRIES = 1;
               $httpProvider.interceptors.push(function ($q, $injector) {
                   return {
                       request: function (config) {
                           config.headers[csrfToken.headerName] = csrfToken.token;
                           return config || $q.when(config);
                       },
                       responseError: function (response) {
                           if (response.status === 403 &amp;&amp; numRetries &lt; MAX_RETRIES) {
                               csrfToken = getCsrfToken();
                               var $http = $injector.get('$http');
                               ++numRetries;
                               return $http(response.config);
                           }
                           return $q.reject(response);
                       },
                       response: function(response) {
                           numRetries = 0;
                           var newToken = response.headers(csrfToken.headerName);
                           if (newToken !== null) {
                               csrfToken.token = newToken;
                           }
                           return response;
                       }
                   };
               });
           });
   })();
  </code></pre>
  
  <p>The requests looks at follows: </p>
  
  <ul>
  <li>POST <a href="http://url/context-root/#/login" rel="nofollow">http://url/context-root/#/login</a>, Time: <strong>53ms</strong>,  Status: <strong>403</strong></li>
  <li>HEAD <a href="http://url/context-root/index.html?id=" rel="nofollow">http://url/context-root/index.html?id=</a>..., Time: <strong>360,2s</strong>, Status: <strong>200</strong></li>
  <li>POST <a href="http://url/context-root/#/login" rel="nofollow">http://url/context-root/#/login</a>, Time: <strong>49ms</strong>, Status: <strong>200</strong></li>
  </ul>