Skip to content

Commit

Permalink
Correctly transform the "Origin" header (close #284)
Browse files Browse the repository at this point in the history
  • Loading branch information
LavrovArtem committed Nov 30, 2015
1 parent 2f24a41 commit a894f2e
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 12 deletions.
7 changes: 2 additions & 5 deletions src/client/sandbox/code-instrumentation/location/wrapper.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import createPropertyDesc from '../../../utils/create-property-desc';
import { get as getDestLocation, getParsed as getParsedDestLocation } from '../../../utils/destination-location';
import { IFRAME, getProxyUrl, changeDestUrlPart } from '../../../utils/url';
import { getDomain } from '../../../../utils/url';

export default class LocationWrapper {
constructor (window) {
Expand All @@ -27,11 +28,7 @@ export default class LocationWrapper {
}));

Object.defineProperty(this, 'origin', createPropertyDesc({
get: () => {
var parsedDestLocation = getParsedDestLocation();

return parsedDestLocation.protocol + '//' + parsedDestLocation.host;
},
get: () => getDomain(getParsedDestLocation()),
set: origin => origin
}));

Expand Down
3 changes: 3 additions & 0 deletions src/client/sandbox/xhr/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import XMLHttpRequestWrapper from './xml-http-request-wrapper';
import nativeMethods from '../native-methods';
import { getProxyUrl } from '../../utils/url';
import XHR_HEADERS from '../../../request-pipeline/xhr/headers';
import { getOrigin } from '../../utils/destination-location';

export default class XhrSandbox extends SandboxBase {
constructor (sandbox) {
Expand Down Expand Up @@ -90,6 +91,8 @@ export default class XhrSandbox extends SandboxBase {
// Access-Control_Allow_Origin flag and skip "preflight" requests.
xhr.setRequestHeader(XHR_HEADERS.requestMarker, 'true');

xhr.setRequestHeader(XHR_HEADERS.origin, getOrigin());

if (xhrSandbox.corsSupported)
xhr.setRequestHeader(XHR_HEADERS.corsSupported, 'true');

Expand Down
3 changes: 3 additions & 0 deletions src/client/utils/destination-location.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,6 @@ export function getParsed () {
};
}

export function getOrigin () {
return sharedUrlUtils.getDomain(getParsed());
}
2 changes: 2 additions & 0 deletions src/request-pipeline/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ export default class RequestPipelineContext {
this.dest.referer = parsedReferer.dest.url;
this.dest.reqOrigin = urlUtils.getDomain(parsedReferer.dest);
}
else if (this.req.headers[XHR_HEADERS.origin])
this.dest.reqOrigin = this.req.headers[XHR_HEADERS.origin];

this._initRequestNatureInfo();

Expand Down
7 changes: 4 additions & 3 deletions src/request-pipeline/xhr/headers.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
// -------------------------------------------------------------

export default {
requestMarker: 'hammerhead|xhr|request-marker-header',
corsSupported: 'hammerhead|xhr|cors-supported-header',
withCredentials: 'hammerhead|xhr|with-credentials-header'
requestMarker: 'x-hammerhead|xhr|request-marker-header',
corsSupported: 'x-hammerhead|xhr|cors-supported-header',
withCredentials: 'x-hammerhead|xhr|with-credentials-header',
origin: 'x-hammerhead|xhr|origin'
};
4 changes: 4 additions & 0 deletions test/client/config-qunit-server-app.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,8 @@ module.exports = function (app) {
res.send(req.originalUrl || req.url);
}, delay);
});

app.post('/xhr-origin-header-test/', function (req, res) {
res.send(req.headers['x-hammerhead|xhr|origin']);
});
};
49 changes: 48 additions & 1 deletion test/client/fixtures/sandbox/xhr-test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
var sharedUrlUtils = hammerhead.get('../utils/url');

var xhrSandbox = hammerhead.sandbox.xhr;
var xhrSandbox = hammerhead.sandbox.xhr;
var iframeSandbox = hammerhead.sandbox.iframe;
var browserUtils = hammerhead.utils.browser;

QUnit.testStart(function () {
iframeSandbox.on(iframeSandbox.IFRAME_READY_TO_INIT_EVENT, initIframeTestHandler);
iframeSandbox.off(iframeSandbox.IFRAME_READY_TO_INIT_EVENT, iframeSandbox.iframeReadyToInitHandler);
});

QUnit.testDone(function () {
iframeSandbox.off(iframeSandbox.IFRAME_READY_TO_INIT_EVENT, initIframeTestHandler);
});

test('redirect requests to proxy', function () {
jQuery.ajaxSetup({ async: false });
Expand Down Expand Up @@ -82,3 +93,39 @@ asyncTest('parameters must pass correctly in xhr event handlers (T239198)', func
request.open('GET', '/xhr-large-response', true);
request.send(null);
});

if (!browserUtils.isIE9) {
asyncTest('send the origin header correctly (GH-284)', function () {
var xhrTestFunc = function () {
var xhr = new XMLHttpRequest();

xhr.open('POST', '/xhr-origin-header-test/', false);
xhr.send();

window.response = xhr.responseText;
};

xhrTestFunc();
strictEqual(window.response, 'https://example.com', 'top window');

var iframe = document.createElement('iframe');

iframe.id = 'test';
iframe.addEventListener('load', function () {
var script = document.createElement('script');

script.innerHTML = '(' + xhrTestFunc.toString() + ')()';

iframe.contentDocument.body.appendChild(script);

strictEqual(iframe.contentWindow.response, 'https://example.com', 'iframe');

document.body.removeChild(iframe);

expect(2);
start();
});

document.body.appendChild(iframe);
});
}
2 changes: 1 addition & 1 deletion test/client/fixtures/transport-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ else {
var callbackCount = 0;
var value = 'testValue';

ok(!window.localStorage.getItem(settings.sessionId));
ok(!window.localStorage.getItem(settings.get().sessionId));

var onAjaxSend = function (xhr) {
xhr.abort();
Expand Down
21 changes: 19 additions & 2 deletions test/server/proxy-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ describe('Proxy', function () {
res.end();
});

app.get('/B234325/reply-with-origin', function (req, res) {
app.get('/B234325,GH-284/reply-with-origin', function (req, res) {
res.set('access-control-allow-origin', 'http://example.com');
res.end(req.headers['origin']);
});
Expand Down Expand Up @@ -589,7 +589,7 @@ describe('Proxy', function () {
describe('Regression', function () {
it('Should force "Origin" header for the same-domain requests (B234325)', function (done) {
var options = {
url: proxy.openSession('http://127.0.0.1:2000/B234325/reply-with-origin', session),
url: proxy.openSession('http://127.0.0.1:2000/B234325,GH-284/reply-with-origin', session),
headers: {
referer: proxy.openSession('http://example.com', session)
}
Expand Down Expand Up @@ -665,5 +665,22 @@ describe('Proxy', function () {
done();
});
});

it('Should transform the "Origin" header for requests without the "Referer" header correctly (GH-284)', function (done) {
var options = {
url: proxy.openSession('http://127.0.0.1:2000/B234325,GH-284/reply-with-origin', session),
headers: { origin: 'http://127.0.0.1:1836' }
};

options.headers[XHR_HEADERS.origin] = 'http://example.com';
options.headers[XHR_HEADERS.requestMarker] = 'true';
options.headers[XHR_HEADERS.corsSupported] = 'true';

request(options, function (err, res, body) {
expect(body).eql('http://example.com');

done();
});
});
});
});

0 comments on commit a894f2e

Please sign in to comment.