diff --git a/package.json b/package.json index 0b27991dd..bf2e735cb 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,6 @@ "rison": "0.1.1", "source-map-support": "0.4.15", "spdy": "3.4.7", - "url-regex": "3.2.0", "uuid": "3.1.0" }, "peerDependencies": { diff --git a/src/plugins/index.js b/src/plugins/index.js index b7f67d868..61d29b795 100644 --- a/src/plugins/index.js +++ b/src/plugins/index.js @@ -96,7 +96,8 @@ export function getLogger( const onRequestError = (request, err) => { console.error( JSON.stringify({ - err, + err: err.stack, + req: pino.stdSerializers.req(request.raw.req), res: pino.stdSerializers.res(request.raw.res), message: `500 Internal server error: ${err.message}`, }) diff --git a/src/renderers/server-render.jsx b/src/renderers/server-render.jsx index 756ff8064..450309c26 100644 --- a/src/renderers/server-render.jsx +++ b/src/renderers/server-render.jsx @@ -220,11 +220,12 @@ const makeRenderer = ( } = request; const requestLanguage = request.getLanguage(); - // request protocol might be different from original request that hit proxy - // we want to use the proxy's protocol + // request protocol and host might be different from original request that hit proxy + // we want to use the proxy's protocol and host const requestProtocol = headers['x-forwarded-proto'] || connection.info.protocol; - const host = `${requestProtocol}://${info.host}`; + const domain = headers['x-forwarded-host'] || info.host; + const host = `${requestProtocol}://${domain}`; // create the store const initialState = {}; diff --git a/src/util/linkify.js b/src/util/linkify.js index c3837c744..de8d6527f 100644 --- a/src/util/linkify.js +++ b/src/util/linkify.js @@ -1,5 +1,9 @@ // @flow -import urlRegex from 'url-regex'; + +// Regex to match urls, copied from url-regex v3. Modified to not match closing parantheses ')' at the end of the url string +var urlRegex = new RegExp( + /(?:(?:(?:[a-z]+:)?\/\/)|www\.)(?:\S+(?::\S*)?@)?(?:localhost|(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:[/?#]([^\s"()]|[(][^\s"]*?[)])*)?/gi +); /** * Generates HTML link tag element with target @@ -31,6 +35,5 @@ export default function linkify(text: string, options?: Object = {}): string { if (!text) { return ''; } - - return text.replace(urlRegex(), createLink(options)); + return text.replace(urlRegex, createLink(options)); } diff --git a/src/util/linkify.test.js b/src/util/linkify.test.js index c608f8b58..7fc0ecfce 100644 --- a/src/util/linkify.test.js +++ b/src/util/linkify.test.js @@ -44,3 +44,115 @@ describe('linkify', () => { expect(linkify(plainBase)).toBe(expectedLink); }); }); +describe('url matching', () => { + // most of these test urls were copied from url-regex + const urlsShouldMatch = [ + 'http://foo.com/blah_blah', + 'http://foo.com/blah_blah/', + 'http://foo.com/blah_blah_(wikipedia)', + 'http://foo.com/blah_blah_(wikipedia)_(again)', + 'http://www.example.com/wpstyle/?p=364', + 'https://www.example.com/foo/?bar=baz&inga=42&quux', + 'http://a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.com', + 'http://mw1.google.com/mw-earth-vectordb/kml-samples/gp/seattle/gigapxl/$[level]/r$[y]_c$[x].jpg', + 'http://user:pass@example.com:123/one/two.three?q1=a1&q2=a2#body', + 'http://www.microsoft.xn--comindex-g03d.html.irongeek.com', + 'http://✪df.ws/123', + 'http://localhost/', + 'http://userid:password@example.com:8080', + 'http://userid:password@example.com:8080/', + 'http://userid@example.com', + 'http://userid@example.com/', + 'http://userid@example.com:8080', + 'http://userid@example.com:8080/', + 'http://userid:password@example.com', + 'http://userid:password@example.com/', + 'http://142.42.1.1/', + 'http://142.42.1.1:8080/', + 'http://➡.ws/䨹', + 'http://⌘.ws', + 'http://⌘.ws/', + 'http://foo.com/blah_(wikipedia)#cite-1', + 'http://foo.com/blah_(wikipedia)_blah#cite-1', + 'http://foo.com/unicode_(✪)_in_parens', + 'http://foo.com/(something)?after=parens', + 'http://☺.damowmow.com/', + 'http://code.google.com/events/#&product=browser', + 'http://j.mp', + 'ftp://foo.bar/baz', + 'http://foo.bar/?q=Test%20URL-encoded%20stuff', + 'http://مثال.إختبار', + 'http://例子.测试', + 'http://उदाहरण.परीक्षा', + "http://-.~_!$&'()*+';=:%40:80%2f::::::@example.com", + 'http://1337.net', + 'http://a.b-c.de', + 'http://223.255.255.254', + 'http://example.com?foo=bar', + 'http://example.com#foo', + 'ws://localhost:8080', + 'ws://foo.ws', + 'ws://a.b-c.de', + 'ws://223.255.255.254', + 'ws://userid:password@example.com', + 'ws://➡.ws/䨹', + '//localhost:8080', + '//foo.ws', + '//a.b-c.de', + '//223.255.255.254', + '//userid:password@example.com', + '//➡.ws/䨹', + 'http://www.restaurant.com/menu(1).pdf', + 'http://www.restaurant.com/menu(foo)(bar).pdf', + 'http://www.example.com/menu(wikipedia)', + 'http://m.com/menu(1)new(2).pdf', + 'http://foo.com/(something)?after=parenthe', + ]; + const urlsShouldNotMatch = [ + 'http://', + 'http://.', + 'http://..', + 'http://../', + 'http://?', + 'http://??', + 'http://??/', + 'http://#', + 'http://##', + 'http://##/', + '//', + '//a', + '///a', + '///', + 'http:///a', + 'foo.com', + 'rdar://1234', + 'h://test', + 'http:// shouldfail.com', + ':// should fail', + 'http://-error-.invalid/', + 'http://-a.b.co', + 'http://a.b-.co', + 'http://123.123.123', + 'http://3628126748', + 'http://go/ogle.com', + 'http://google\\.com', + 'http://www(google.com', + 'http://www=google.com', + 'rdar://1234', + '/foo.bar/', + ]; + + urlsShouldMatch.forEach(url => { + it(`should match ${url}`, () => { + const plainText = `Check out my meetup (${url}). It's awesome.`; + const expected = `Check out my meetup (${url}). It's awesome.`; + expect(linkify(plainText)).toBe(expected); + }); + }); + urlsShouldNotMatch.forEach(url => { + it(`should not match ${url}`, () => { + const plainText = `Check out my meetup (${url}). It's awesome.`; + expect(linkify(plainText)).toBe(plainText); + }); + }); +}); diff --git a/yarn.lock b/yarn.lock index faefaad92..e2d286589 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3702,10 +3702,6 @@ invert-kv@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" -ip-regex@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-1.0.3.tgz#dc589076f659f419c222039a33316f1c7387effd" - ip@^1.1.0: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" @@ -7423,12 +7419,6 @@ url-parse@^1.1.1, url-parse@^1.1.8: querystringify "~1.0.0" requires-port "1.0.x" -url-regex@3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/url-regex/-/url-regex-3.2.0.tgz#dbad1e0c9e29e105dd0b1f09f6862f7fdb482724" - dependencies: - ip-regex "^1.0.1" - url@^0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"