Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions js/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,15 @@ function checkRedirects(details) {
var result = r.getMatch(details.url);

if (result.isMatch) {
// If this redirect has error codes specified, store it for later checking
if (r.errorCodes && r.errorCodes.trim() !== '') {
pendingRedirects[details.url] = {
redirectTo: result.redirectTo,
errorCodes: r.errorCodes
};
log('Storing redirect for error code checking: ' + details.url + ' with error codes: ' + r.errorCodes);
return {}; // Don't redirect immediately, wait for response
}

//Check if we're stuck in a loop where we keep redirecting this, in that
//case ignore!
Expand Down Expand Up @@ -111,6 +120,43 @@ function checkRedirects(details) {
return {};
}

// Store pending redirects that need error code verification
var pendingRedirects = {};

// Function to check redirects on HTTP response (for error code checking)
function checkRedirectsOnResponse(details) {
var url = details.url;
var statusCode = details.statusCode;

if (pendingRedirects[url]) {
var redirect = pendingRedirects[url];
delete pendingRedirects[url];

// Check if this redirect should be applied based on the error code
var shouldApply = true;
if (redirect.errorCodes && redirect.errorCodes.trim() !== '') {
var codes = redirect.errorCodes.split(',').map(function(code) {
return code.trim();
});
shouldApply = codes.indexOf(statusCode.toString()) !== -1;
}

if (shouldApply) {
log('Redirecting on error ' + statusCode + ': ' + url + ' ===> ' + redirect.redirectTo);
ignoreNextRequest[redirect.redirectTo] = new Date().getTime();

// Update the tab with the redirect URL
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
if (tabs[0]) {
chrome.tabs.update(tabs[0].id, {url: redirect.redirectTo});
}
});
} else {
log('Not redirecting ' + url + ' because status code ' + statusCode + ' does not match error codes: ' + redirect.errorCodes);
}
}
}

//Monitor changes in data, and setup everything again.
//This could probably be optimized to not do everything on every change
//but why bother?
Expand Down Expand Up @@ -190,6 +236,7 @@ function createPartitionedRedirects(redirects) {
function setUpRedirectListener() {

chrome.webRequest.onBeforeRequest.removeListener(checkRedirects); //Unsubscribe first, in case there are changes...
chrome.webRequest.onCompleted.removeListener(checkRedirectsOnResponse);
chrome.webNavigation.onHistoryStateUpdated.removeListener(checkHistoryStateRedirects);

storageArea.get({redirects:[]}, function(obj) {
Expand All @@ -204,6 +251,9 @@ function setUpRedirectListener() {

log('Setting filter for listener: ' + JSON.stringify(filter));
chrome.webRequest.onBeforeRequest.addListener(checkRedirects, filter, ["blocking"]);

// Add response listener for error code checking
chrome.webRequest.onCompleted.addListener(checkRedirectsOnResponse, filter);

if (partitionedRedirects.history) {
log('Adding HistoryState Listener');
Expand Down
1 change: 1 addition & 0 deletions js/editredirect.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ function editFormChange() {

activeRedirect.processMatches = el('#process-matches option:checked').value;
activeRedirect.patternType = el('[name="patterntype"]:checked').value;
activeRedirect.errorCodes = el('input[data-bind="errorCodes"]').value;

activeRedirect.updateExampleResult();

Expand Down
17 changes: 17 additions & 0 deletions js/redirect.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ Redirect.prototype = {
processMatches : 'noProcessing',
disabled : false,
grouped: false,
errorCodes : '', // Comma-separated list of HTTP error codes (e.g., "404,500")

compile : function() {

Expand All @@ -67,6 +68,7 @@ Redirect.prototype = {
&& this.redirectUrl == redirect.redirectUrl
&& this.patternType == redirect.patternType
&& this.processMatches == redirect.processMatches
&& this.errorCodes == redirect.errorCodes
&& this.appliesTo.toString() == redirect.appliesTo.toString();
},

Expand All @@ -84,6 +86,7 @@ Redirect.prototype = {
processMatches : this.processMatches,
disabled : this.disabled,
grouped: this.grouped,
errorCodes : this.errorCodes,
appliesTo : this.appliesTo.slice(0)
};
},
Expand Down Expand Up @@ -237,6 +240,7 @@ Redirect.prototype = {
}

this.disabled = !!o.disabled;
this.errorCodes = o.errorCodes || '';
if (o.appliesTo && o.appliesTo.length) {
this.appliesTo = o.appliesTo.slice(0);
} else {
Expand Down Expand Up @@ -300,5 +304,18 @@ Redirect.prototype = {
var shouldExclude = this._rxExclude.test(url);
this._rxExclude.lastIndex = 0;
return shouldExclude;
},

// Check if this redirect should be applied based on HTTP status code
shouldApplyOnErrorCode : function(statusCode) {
if (!this.errorCodes || this.errorCodes.trim() === '') {
return true; // No error codes specified, apply always
}

var codes = this.errorCodes.split(',').map(function(code) {
return code.trim();
});

return codes.indexOf(statusCode.toString()) !== -1;
}
};
7 changes: 7 additions & 0 deletions redirector.html
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ <h3>Create Redirect</h3>
<label>Pattern Description:</label>
<div class="input-cell"><input type="text" data-bind="patternDesc" placeholder="Describe your pattern" /></div>
</div>
<div>
<label>Error Codes (optional):</label>
<div class="input-cell"><input type="text" data-bind="errorCodes" placeholder="e.g., 404,500 (leave empty to redirect always)" /></div>
</div>
<div>
<label>Example result:</label>
<div class="input-cell"><span class="error example-result-error" data-show="error" data-bind="error"></span><span class="example-result" data-show="exampleResult" data-bind="exampleResult"></span></div>
Expand Down Expand Up @@ -168,6 +172,9 @@ <h4><span class="disabled-marker" data-show="disabled">[Disabled] </span><span d
<div data-show="excludePattern">
<label>excluding:</label><p data-bind="excludePattern"></p>
</div>
<div data-show="errorCodes">
<label>Error codes:</label><p data-bind="errorCodes"></p>
</div>
<div data-show="patternDesc">
<label>Hint:</label><p data-bind="patternDesc"></p>
</div>
Expand Down