Chrome extension: webRequest.onBeforeSendHeaders behaves strange

Here's a working version that works in all instances (when referer header is already set or when it hasn't been set.)

var requestFilter = {
    urls: ["<all_urls>"]
},

extraInfoSpec = ['requestHeaders', 'blocking'],
handler = function(details) {

var isRefererSet = false;
var headers = details.requestHeaders,
    blockingResponse = {};

for (var i = 0, l = headers.length; i < l; ++i) {
    if (headers[i].name == 'Referer') {
        headers[i].value = "http://your-url.com/";
        isRefererSet = true;
        break;
    }
}

if (!isRefererSet) {
    headers.push({
        name: "Referer",
        value: "http://your-url.com/"
    });
}

blockingResponse.requestHeaders = headers;
return blockingResponse;
};

chrome.webRequest.onBeforeSendHeaders.addListener(handler, requestFilter, extraInfoSpec);

Don't forget to add all the following permissions to your manifest:

"permissions": [  "webRequest", "webRequestBlocking", "<all_urls>" ]

The reason you can't set the Referrer header when you don't have a blocking request is that the request has potentially already gone out - you are being notified asynchronously, and cannot change anything about the request.

To change headers, I use this code:

function mod_headers(header_array,p_name,p_value) {
     var did_set = false;                                                                                      
     for(var i in header_array) {                                                                                                   
         var header = header_array[i];                                                                                              
         var name = header.name;                                                                                                    
         var value = header.value;                                                                                                  

         // If the header is already present, change it:
         if(name == p_name) {
             header.value = p_value;
             did_set = true;
         }                                                                                                         
     }
     // if it is not, add it:
     if(!did_set) { header_array.push( { name : p_name , value : p_value } ); }                                                                                                                       
 }