From 06a0da09320340a988513285046b577b4a7518fd Mon Sep 17 00:00:00 2001 From: Fredrik Bonander Date: Thu, 23 Jan 2014 11:06:55 +0000 Subject: [PATCH] fix(web-server): strip scheme, host and port --- lib/middleware/karma.js | 2 +- lib/middleware/strip_host.js | 18 ++++++ lib/web-server.js | 2 + test/unit/middleware/karma.spec.coffee | 15 +++-- test/unit/middleware/strip_host.spec.coffee | 70 +++++++++++++++++++++ test/unit/web-server.spec.coffee | 5 ++ 6 files changed, 106 insertions(+), 6 deletions(-) create mode 100644 lib/middleware/strip_host.js create mode 100644 test/unit/middleware/strip_host.spec.coffee diff --git a/lib/middleware/karma.js b/lib/middleware/karma.js index 6836af577..4941b7034 100644 --- a/lib/middleware/karma.js +++ b/lib/middleware/karma.js @@ -37,7 +37,7 @@ var createKarmaMiddleware = function(filesPromise, serveStaticFile, /* config.basePath */ basePath, /* config.urlRoot */ urlRoot) { return function(request, response, next) { - var requestUrl = request.url.replace(/\?.*/, ''); + var requestUrl = request.normalizedUrl.replace(/\?.*/, ''); // redirect /__karma__ to /__karma__ (trailing slash) if (requestUrl === urlRoot.substr(0, urlRoot.length - 1)) { diff --git a/lib/middleware/strip_host.js b/lib/middleware/strip_host.js new file mode 100644 index 000000000..da4253f54 --- /dev/null +++ b/lib/middleware/strip_host.js @@ -0,0 +1,18 @@ +/** + * Strip host middleware is responsible for stripping hostname from request path + * This to handle requests that uses (normally over proxies) an absolutURI as request path + */ + +var createStripHostMiddleware = function() { + return function(request, response, next) { + function stripHostFromUrl(url) { + return url.replace(/^http[s]?:\/\/([a-z\-\.\:\d]+)\//, '/'); + } + + request.normalizedUrl = stripHostFromUrl(request.url) || request.url; + next(); + }; +}; + +// PUBLIC API +exports.create = createStripHostMiddleware; diff --git a/lib/web-server.js b/lib/web-server.js index 03d00ef85..c7b3be188 100644 --- a/lib/web-server.js +++ b/lib/web-server.js @@ -5,6 +5,7 @@ var connect = require('connect'); var common = require('./middleware/common'); var runnerMiddleware = require('./middleware/runner'); +var stripHostMiddleware = require('./middleware/strip_host'); var karmaMiddleware = require('./middleware/karma'); var sourceFilesMiddleware = require('./middleware/source_files'); var proxyMiddleware = require('./middleware/proxy'); @@ -46,6 +47,7 @@ var createWebServer = function(injector, emitter) { var handler = connect() .use(injector.invoke(runnerMiddleware.create)) + .use(injector.invoke(stripHostMiddleware.create)) .use(injector.invoke(karmaMiddleware.create)) .use(injector.invoke(sourceFilesMiddleware.create)) // TODO(vojta): extract the proxy into a plugin diff --git a/test/unit/middleware/karma.spec.coffee b/test/unit/middleware/karma.spec.coffee index f85554bf5..4b115154b 100644 --- a/test/unit/middleware/karma.spec.coffee +++ b/test/unit/middleware/karma.spec.coffee @@ -39,8 +39,13 @@ describe 'middleware.karma', -> servedFiles = (files) -> filesDeferred.resolve {included: [], served: files} + normalizedHttpRequest = (urlPath) -> + req = new HttpRequestMock(urlPath) + req.normalizedUrl = req.url + return req + callHandlerWith = (urlPath, next) -> - promise = handler new HttpRequestMock(urlPath), response, next or nextSpy + promise = handler normalizedHttpRequest(urlPath), response, next or nextSpy if promise and promise.done then promise.done() @@ -55,19 +60,19 @@ describe 'middleware.karma', -> it 'should not serve outside of urlRoot', -> - handler new HttpRequestMock('/'), null, nextSpy + handler normalizedHttpRequest('/'), null, nextSpy expect(nextSpy).to.have.been.called nextSpy.reset() - handler new HttpRequestMock('/client.html'), null, nextSpy + handler normalizedHttpRequest('/client.html'), null, nextSpy expect(nextSpy).to.have.been.called nextSpy.reset() - handler new HttpRequestMock('/debug.html'), null, nextSpy + handler normalizedHttpRequest('/debug.html'), null, nextSpy expect(nextSpy).to.have.been.called nextSpy.reset() - handler new HttpRequestMock('/context.html'), null, nextSpy + handler normalizedHttpRequest('/context.html'), null, nextSpy expect(nextSpy).to.have.been.called diff --git a/test/unit/middleware/strip_host.spec.coffee b/test/unit/middleware/strip_host.spec.coffee new file mode 100644 index 000000000..fe4eeefc0 --- /dev/null +++ b/test/unit/middleware/strip_host.spec.coffee @@ -0,0 +1,70 @@ +describe 'middleware.strip_host', -> + q = require 'q' + + mocks = require 'mocks' + HttpResponseMock = mocks.http.ServerResponse + HttpRequestMock = mocks.http.ServerRequest + + File = require('../../../lib/file_list').File + Url = require('../../../lib/file_list').Url + + fsMock = mocks.fs.create + base: + path: + 'a.js': mocks.fs.file(0, 'js-src-a') + 'index.html': mocks.fs.file(0, '') + src: + 'some.js': mocks.fs.file(0, 'js-source') + 'utf8ášč': + 'some.js': mocks.fs.file(0, 'utf8-file') + + + serveFile = require('../../../lib/middleware/common').createServeFile fsMock, null + createStripHostMiddleware = require('../../../lib/middleware/strip_host').create + + handler = filesDeferred = nextSpy = response = null + + beforeEach -> + nextSpy = sinon.spy() + request = null + handler = createStripHostMiddleware null, null, '/base/path' + + it 'should strip request with IP number', (done) -> + request = new HttpRequestMock('http://192.12.31.100/base/a.js?123345') + handler request, null, nextSpy + + expect(request.normalizedUrl).to.equal '/base/a.js?123345' + expect(nextSpy).to.have.been.called + done() + + it 'should strip request with absoluteURI', (done) -> + request = new HttpRequestMock('http://localhost/base/a.js?123345') + handler request, null, nextSpy + + expect(request.normalizedUrl).to.equal '/base/a.js?123345' + expect(nextSpy).to.have.been.called + done() + + it 'should strip request with absoluteURI and port', (done) -> + request = new HttpRequestMock('http://localhost:9876/base/a.js?123345') + handler request, null, nextSpy + + expect(request.normalizedUrl).to.equal '/base/a.js?123345' + expect(nextSpy).to.have.been.called + done() + + it 'should strip request with absoluteURI over HTTPS', (done) -> + request = new HttpRequestMock('https://karma-runner.github.io/base/a.js?123345') + handler request, null, nextSpy + + expect(request.normalizedUrl).to.equal '/base/a.js?123345' + expect(nextSpy).to.have.been.called + done() + + it 'should return same url as passed one', (done) -> + request = new HttpRequestMock('/base/b.js?123345') + handler request, null, nextSpy + + expect(request.normalizedUrl).to.equal '/base/b.js?123345' + expect(nextSpy).to.have.been.called + done() diff --git a/test/unit/web-server.spec.coffee b/test/unit/web-server.spec.coffee index 872bb7ab6..1699de81d 100644 --- a/test/unit/web-server.spec.coffee +++ b/test/unit/web-server.spec.coffee @@ -59,6 +59,11 @@ describe 'web-server', -> requestPath '/' + it 'should serve client.html with a absoluteURI request path ', (done) -> + response.once 'end', -> + expect(response).to.beServedAs 200, 'CLIENT HTML' + done() + requestPath 'http://localhost:9876/' it 'should serve source files', (done) -> response.once 'end', ->