1 | 'use strict';
|
2 |
|
3 | var events = require('events');
|
4 | var util = require('util');
|
5 | var timeoutReq = require('timed-out');
|
6 |
|
7 | var http = require('http');
|
8 | var https = require('https');
|
9 |
|
10 | var agentOptions = {keepAlive: true, maxSockets: 100};
|
11 | var httpAgent = new http.Agent(agentOptions);
|
12 | var httpsAgent = new https.Agent(agentOptions);
|
13 |
|
14 | function Transport() {}
|
15 | util.inherits(Transport, events.EventEmitter);
|
16 |
|
17 | function HTTPTransport(options) {
|
18 | this.defaultPort = 80;
|
19 | this.transport = http;
|
20 | this.options = options || {};
|
21 | this.agent = httpAgent;
|
22 | }
|
23 | util.inherits(HTTPTransport, Transport);
|
24 | HTTPTransport.prototype.send = function(client, message, headers, eventId, cb) {
|
25 | var options = {
|
26 | hostname: client.dsn.host,
|
27 | path: client.dsn.path + 'api/' + client.dsn.project_id + '/store/',
|
28 | headers: headers,
|
29 | method: 'POST',
|
30 | port: client.dsn.port || this.defaultPort,
|
31 | ca: client.ca,
|
32 | agent: this.agent
|
33 | };
|
34 | for (var key in this.options) {
|
35 | if (this.options.hasOwnProperty(key)) {
|
36 | options[key] = this.options[key];
|
37 | }
|
38 | }
|
39 |
|
40 |
|
41 | var _name = this.agent.getName({host: client.dsn.host, port: client.dsn.port});
|
42 | var _requests = this.agent.requests[_name];
|
43 | if (_requests && Object.keys(_requests).length > client.maxReqQueueCount) {
|
44 |
|
45 | client.emit('error', new Error('client req queue is full..'));
|
46 | return;
|
47 | }
|
48 |
|
49 | var req = this.transport.request(options, function(res) {
|
50 | res.setEncoding('utf8');
|
51 | if (res.statusCode >= 200 && res.statusCode < 300) {
|
52 | client.emit('logged', eventId);
|
53 | cb && cb(null, eventId);
|
54 | } else {
|
55 | var reason = res.headers['x-sentry-error'];
|
56 | var e = new Error('HTTP Error (' + res.statusCode + '): ' + reason);
|
57 | e.response = res;
|
58 | e.statusCode = res.statusCode;
|
59 | e.reason = reason;
|
60 | e.sendMessage = message;
|
61 | e.requestHeaders = headers;
|
62 | e.eventId = eventId;
|
63 | client.emit('error', e);
|
64 | cb && cb(e);
|
65 | }
|
66 |
|
67 |
|
68 | var noop = function() {};
|
69 | res.on('data', noop);
|
70 | res.on('end', noop);
|
71 | });
|
72 |
|
73 | timeoutReq(req, client.sendTimeout * 1000);
|
74 |
|
75 | var cbFired = false;
|
76 | req.on('error', function(e) {
|
77 | client.emit('error', e);
|
78 | if (!cbFired) {
|
79 | cb && cb(e);
|
80 | cbFired = true;
|
81 | }
|
82 | });
|
83 | req.end(message);
|
84 | };
|
85 |
|
86 | function HTTPSTransport(options) {
|
87 | this.defaultPort = 443;
|
88 | this.transport = https;
|
89 | this.options = options || {};
|
90 | this.agent = httpsAgent;
|
91 | }
|
92 | util.inherits(HTTPSTransport, HTTPTransport);
|
93 |
|
94 | module.exports.http = new HTTPTransport();
|
95 | module.exports.https = new HTTPSTransport();
|
96 | module.exports.Transport = Transport;
|
97 | module.exports.HTTPTransport = HTTPTransport;
|
98 | module.exports.HTTPSTransport = HTTPSTransport;
|