diff --git a/docs/config.rst b/docs/config.rst index ceb0d61f88dd..d5e4ed89e44f 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -205,6 +205,12 @@ Those configuration options are documented below: By default, Raven does not truncate messages. If you need to truncate characters for whatever reason, you may set this to limit the length. +.. describe:: maxUrlLength + + By default, Raven will truncate URLs as they appear in breadcrumbs and other meta + interfaces to 250 characters in order to minimize bytes over the wire. This does *not* + affect URLs in stack traces. + .. describe:: autoBreadcrumbs Enables/disables automatic collection of breadcrumbs. Possible values are: diff --git a/src/raven.js b/src/raven.js index b1608a29a5a7..48d81c6d4a57 100644 --- a/src/raven.js +++ b/src/raven.js @@ -50,6 +50,9 @@ function Raven() { crossOrigin: 'anonymous', collectWindowErrors: true, maxMessageLength: 0, + + // By default, truncates URL values to 250 chars + maxUrlLength: 250, stackTraceLimit: 50, autoBreadcrumbs: true, sampleRate: 1 @@ -1320,9 +1323,46 @@ Raven.prototype = { exception.value = truncate(exception.value, max); } + var request = data.request; + if (request) { + if (request.url) { + request.url = truncate(request.url, this._globalOptions.maxUrlLength); + } + if (request.Referer) { + request.Referer = truncate(request.Referer, this._globalOptions.maxUrlLength); + } + } + + if (data.breadcrumbs && data.breadcrumbs.values) + this._trimBreadcrumbs(data.breadcrumbs); + return data; }, + /** + * Truncate breadcrumb values (right now just URLs) + */ + _trimBreadcrumbs: function (breadcrumbs) { + // known breadcrumb properties with urls + // TODO: also consider arbitrary prop values that start with (https?)?:// + var urlprops = {to: 1, from: 1, url: 1}, + crumb, + data; + + for (var i = 0; i < breadcrumbs.values.length; i++) { + crumb = breadcrumbs.values[i]; + if (!crumb.hasOwnProperty('data')) + continue; + + data = crumb.data; + for (var prop in urlprops) { + if (data.hasOwnProperty(prop)) { + data[prop] = truncate(data[prop], this._globalOptions.maxUrlLength); + } + } + } + }, + _getHttpData: function() { if (!this._hasNavigator && !this._hasDocument) return; var httpData = {}; diff --git a/test/raven.test.js b/test/raven.test.js index bc57bb3bc0e9..24a053cba9e2 100644 --- a/test/raven.test.js +++ b/test/raven.test.js @@ -88,6 +88,7 @@ describe('globals', function() { describe('trimPacket', function() { it('should work as advertised', function() { + // message/excepion value (maxMessageLength) Raven._globalOptions.maxMessageLength = 3; assert.deepEqual( Raven._trimPacket({message: 'lol'}), @@ -105,6 +106,51 @@ describe('globals', function() { Raven._trimPacket({message: 'lolol', exception: {values: [{value: 'lolol'}]}}), {message: 'lol\u2026', exception: {values: [{value: 'lol\u2026'}]}} ); + + // request URLs (maxUrlLength) + Raven._globalOptions.maxUrlLength = 20; + assert.deepEqual( + Raven._trimPacket({request: {url: 'http://example.com/foo/bar/baz.js', Referer: 'http://example.com/f\u2026'}}), + {request: {url: 'http://example.com/f\u2026', Referer: 'http://example.com/f\u2026'}} + ) + }); + }); + + describe('_trimBreadcrumbs', function() { + it('should work as expected', function() { + Raven._globalOptions.maxUrlLength = 20; + + var breadcrumbs = { + values: [{ + data: { + donttouch: 'this-is-not-a-url-field-and-should-not-be-touched', + to: 'http://example.com/foo/bar/baz.js', + from: 'http://example.com/foo/bar/baz.js' + } + }, { + data: { + donttouch: 'this-is-not-a-url-field-and-should-not-be-touched', + url: 'http://example.com/foo/bar/baz.js' + } + }] + }; + + // NOTE: _trimBreadcrumbs mutates data in-place + Raven._trimBreadcrumbs(breadcrumbs); + assert.deepEqual(breadcrumbs, { + values: [{ + data: { + donttouch: 'this-is-not-a-url-field-and-should-not-be-touched', + to: 'http://example.com/f\u2026', // 20 chars + from: 'http://example.com/f\u2026' + } + }, { + data: { + donttouch: 'this-is-not-a-url-field-and-should-not-be-touched', + url: 'http://example.com/f\u2026' + } + }] + }); }); }); diff --git a/typescript/raven.d.ts b/typescript/raven.d.ts index 312a85e78e13..2f887613a700 100644 --- a/typescript/raven.d.ts +++ b/typescript/raven.d.ts @@ -56,6 +56,9 @@ interface RavenOptions { /** By default, Raven does not truncate messages. If you need to truncate characters for whatever reason, you may set this to limit the length. */ maxMessageLength?: number; + /** By default, Raven will truncate URLs as they appear in breadcrumbs and other meta interfaces to 250 characters in order to minimize bytes over the wire. This does *not* affect URLs in stack traces. */ + maxUrlLength?: number; + /** Override the default HTTP data transport handler. */ transport?: (options: RavenTransportOptions) => void; }