From aa8831d51847ec8cef0c7bda4a63675c455cbc20 Mon Sep 17 00:00:00 2001 From: Jackie Jimenez Date: Tue, 15 Aug 2017 14:24:39 -0400 Subject: [PATCH 1/5] update regex (copied from url-regex, modified to not select closing parentheses); remove url-regex package --- package.json | 1 - src/util/linkify.js | 7 ++++--- src/util/linkify.test.js | 9 +++++++++ yarn.lock | 10 ---------- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index af2826a1b..4ef270712 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/util/linkify.js b/src/util/linkify.js index c3837c744..4f730637e 100644 --- a/src/util/linkify.js +++ b/src/util/linkify.js @@ -1,5 +1,7 @@ // @flow -import urlRegex from 'url-regex'; +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)"]*)?/gi +); /** * Generates HTML link tag element with target @@ -31,6 +33,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..2503c7e07 100644 --- a/src/util/linkify.test.js +++ b/src/util/linkify.test.js @@ -43,4 +43,13 @@ describe('linkify', () => { 'www.meetup.com'; expect(linkify(plainBase)).toBe(expectedLink); }); + it('should select and create a link around only the url', () => { + const plainText = + 'Check out my Meetup (http://www.meetup.com/hq-faff), it is awesome.'; + const expectedHTML = + 'Check out my Meetup (' + + '' + + 'http://www.meetup.com/hq-faff), it is awesome.'; + expect(linkify(plainText)).toBe(expectedHTML); + }); }); diff --git a/yarn.lock b/yarn.lock index dc3cff2d4..56efaeac6 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" From 47c5cfe6d6ba7a51dc7622cb96e1807bc55b051b Mon Sep 17 00:00:00 2001 From: Jackie Jimenez Date: Tue, 15 Aug 2017 15:43:48 -0400 Subject: [PATCH 2/5] add comment to show where the regex came from --- src/util/linkify.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/util/linkify.js b/src/util/linkify.js index 4f730637e..9511d8f7c 100644 --- a/src/util/linkify.js +++ b/src/util/linkify.js @@ -1,4 +1,6 @@ // @flow + +// 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)"]*)?/gi ); From f5ca4fc588ef7ce195ba6636985e7041b2a6f9d7 Mon Sep 17 00:00:00 2001 From: Jackie Jimenez Date: Wed, 16 Aug 2017 12:32:43 -0400 Subject: [PATCH 3/5] fix regex to continue to match parentheses within the actual url but not at the end, and copy test urls from url-regex --- src/util/linkify.js | 2 +- src/util/linkify.test.js | 119 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 112 insertions(+), 9 deletions(-) diff --git a/src/util/linkify.js b/src/util/linkify.js index 9511d8f7c..de8d6527f 100644 --- a/src/util/linkify.js +++ b/src/util/linkify.js @@ -2,7 +2,7 @@ // 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)"]*)?/gi + /(?:(?:(?:[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 ); /** diff --git a/src/util/linkify.test.js b/src/util/linkify.test.js index 2503c7e07..7fc0ecfce 100644 --- a/src/util/linkify.test.js +++ b/src/util/linkify.test.js @@ -43,13 +43,116 @@ describe('linkify', () => { 'www.meetup.com'; expect(linkify(plainBase)).toBe(expectedLink); }); - it('should select and create a link around only the url', () => { - const plainText = - 'Check out my Meetup (http://www.meetup.com/hq-faff), it is awesome.'; - const expectedHTML = - 'Check out my Meetup (' + - '' + - 'http://www.meetup.com/hq-faff), it is awesome.'; - expect(linkify(plainText)).toBe(expectedHTML); +}); +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); + }); }); }); From 085bdc10f9019da695d2ce3ff81974ef3a0616a0 Mon Sep 17 00:00:00 2001 From: will h Date: Thu, 17 Aug 2017 15:36:16 -0400 Subject: [PATCH 4/5] Use x-forwarded-host when available to set baseUrl. --- src/renderers/server-render.jsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/renderers/server-render.jsx b/src/renderers/server-render.jsx index 0fcb5bf25..1663a2098 100644 --- a/src/renderers/server-render.jsx +++ b/src/renderers/server-render.jsx @@ -213,11 +213,12 @@ const makeRenderer = ( raw: { req }, } = request; - // 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}`; const apiUrl = '/mu_api'; // create the store From b3c0e5a9888a1cad1f3d27f6d0e99305d421bfc4 Mon Sep 17 00:00:00 2001 From: Michael McGahan Date: Fri, 18 Aug 2017 07:58:58 +1200 Subject: [PATCH 5/5] more error log info --- src/plugins.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins.js b/src/plugins.js index 9590bb310..5262aac28 100644 --- a/src/plugins.js +++ b/src/plugins.js @@ -86,7 +86,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}`, })