Skip to content

Instantly share code, notes, and snippets.

@ndmanvar
Last active November 26, 2018 19:20
Show Gist options
  • Save ndmanvar/7ae7b4db7bf1cda30545c1480fde77fe to your computer and use it in GitHub Desktop.
Save ndmanvar/7ae7b4db7bf1cda30545c1480fde77fe to your computer and use it in GitHub Desktop.
'use strict';
var request = require('request');
function HTTPSProxyTransport() {}
HTTPSProxyTransport.prototype.send = function (client, message, headers, eventId, cb) {
var options = {
url: 'https://' + client.dsn.host + client.dsn.path + 'api/' + client.dsn.project_id + '/store/',
headers: headers,
method: 'POST',
ca: client.ca,
body: message
};
request(options, function (error, response, body) {
if (!error && response.statusCode == 200 && response.statusCode < 300) {
client.emit('logged', eventId);
cb && cb(null, eventId);
} else {
var reason = response.headers['x-sentry-error'];
var e = new Error('HTTP Error (' + response.statusCode + '): ' + reason);
e.response = response;
e.statusCode = response.statusCode;
e.reason = reason;
e.sendMessage = message;
e.requestHeaders = headers;
e.eventId = eventId;
client.emit('error', e);
cb && cb(e);
}
});
};
module.exports.HTTPSProxyTransport = HTTPSProxyTransport;
@ndmanvar
Copy link
Author

ndmanvar commented Oct 2, 2017

Script to test / use (customtransort_test.js):

var Raven = require('raven');
var CustomTransport = require('./CustomTransport.js');

Raven.config('https://{PUBLIC_KEY}:{PRIVATE_KEY}@sentry.io/{PROJECT_ID}', {
    transport: new CustomTransport.HTTPSProxyTransport()
}).install();

var x = {};
x.something();

To run:
$ HTTP_PROXY=http://localhost:8080 node customtransport_test.js
Be sure to replace localhost:8080 with proxy address/port.

@datoml
Copy link

datoml commented Jun 19, 2018

Thanks for this gist. I made some tweeks to the customTransport.js in case someone needs it.

What I did:

  • Changed the name from HTTPSProxyTransport to ProxyTransport
  • URL now uses protocol and port from client.dsn aswell
  • Added error check for response.

Its an es6 class

import request from 'request';

export class ProxyTransport {
  constructor() {
    this.send = function (client, message, headers, eventId, cb) {
      var options = {
        url: `${client.dsn.protocol}://${client.dsn.host}:${client.dsn.port}${client.dsn.path}api/${client.dsn.project_id}/store/`,
        headers: headers,
        method: 'POST',
        ca: client.ca,
        body: message
      };
          
      request(options, function (error, response) {
        if ((!error && response && response.statusCode == 200 && response.statusCode < 300)|| !response) {
          client.emit('logged', eventId);
          cb && cb(null, eventId);
        } else {
          var reason = response.headers['x-sentry-error'];
          var e = new Error('HTTP Error (' + response.statusCode + '): ' + reason);
          e.response = response;
          e.statusCode = response.statusCode;
          e.reason = reason;
          e.sendMessage = message;
          e.requestHeaders = headers;
          e.eventId = eventId;
          client.emit('error', e);
          cb && cb(e);
        }
      });
    };
  }
}

@LaurentGoderre
Copy link

Since this is the best way to do proxied request with Raven, can this be madfe into an npm module?

@LaurentGoderre
Copy link

LaurentGoderre commented Aug 2, 2018

Using this syntax

let request = require('request');

class RavenHTTPSProxyTransport {
	send(client, message, headers, eventId, cb) {
		let options = {
			url: `https://${client.dsn.host}${client.dsn.path}api/${client.dsn.project_id}/store/`,
			method: 'POST',
			ca: client.ca,
			body: message,
			headers
		};

		request(options, (error, response, body) => {
			if (!error && response.statusCode == 200 && response.statusCode < 300) {
				client.emit('logged', eventId);
				cb && cb(null, eventId);
			} else {
				let reason = response.headers['x-sentry-error'];
				let e = new Error(`HTTP Error (${response.statusCode}): ${reason}`);
				e.response = response;
				e.statusCode = response.statusCode;
				e.reason = reason;
				e.sendMessage = message;
				e.requestHeaders = headers;
				e.eventId = eventId;
				client.emit('error', e);
				cb && cb(e);
			}
		});
	}
}

module.exports = RavenHTTPSProxyTransport;

You can do:

Raven.config(process.env.SENTRY_DSN, {
	transport: new (require('RavenHTTPSProxyTransport'))()
}).install();

or

const {RavenHTTPSProxyTransport} = require('RavenHTTPSProxyTransport');
Raven.config(process.env.SENTRY_DSN, {
	transport: new RavenHTTPSProxyTransport()
}).install();

@tyiu
Copy link

tyiu commented Aug 8, 2018

Thanks for sharing this code!

I think there's a minor bug in the if statement:
https://gist.github.com/ndmanvar/7ae7b4db7bf1cda30545c1480fde77fe#file-customtransport-js-L16

It should be:
if (!error && response.statusCode >= 200 && response.statusCode < 300) {

@LaurentGoderre
Copy link

Yeah, you're right!!

@ndmanvar
Copy link
Author

Hi Laurent!

We are in progress of rewriting our SDKs. I will surface this request/ask to our dev team and see what the answer/reply is here.
New upcoming JS SDK (in case you want to keep track / dig in): https://github.com/getsentry/sentry-javascript

Also, thank @tyiu for finding the bug and suggesting the fix!
-Neil

@timwaddell
Copy link

@ndmanvar @LaurentGoderre

Is there a similar solution to LaurentGoderre fix for the latest JS SDK? Where is transport config modified now @ndmanvar ?

@ndmanvar
Copy link
Author

@timwaddell
Copy link

Thanks @ndmanvar
I can see it's in the docs but can't see any implementation on the latest master? Can you point me to whereabouts if so?

@kamilogorek
Copy link

@timwaddell we missed it, my bad. Here's a PR for it - getsentry/sentry-javascript#1761
Coming in the next release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment