|
1 | 1 | import * as http from "http"; |
2 | | -import { EventResponse, Incident } from "../transport/events"; |
3 | | -import { |
4 | | - TraceoIncomingMessage, |
5 | | - RequestOptions, |
6 | | - HTTP_ENDPOINT, |
7 | | -} from "../transport/http"; |
8 | | -import { TraceoLog } from "../transport/logger"; |
9 | | -import { Metrics } from "../transport/metrics"; |
| 2 | +import * as https from "https"; |
| 3 | +import { Client } from "../node/client"; |
10 | 4 | import { RequestType } from "../transport/types"; |
11 | | -import { getGlobalClientData } from "./global"; |
12 | | -import { TRACEO_SDK_VERSION } from "./version"; |
13 | 5 |
|
14 | | -const createHttpOptions = ( |
15 | | - path: string, |
16 | | - method: RequestType = "POST" |
17 | | -): http.RequestOptions => { |
18 | | - const client = getGlobalClientData(); |
19 | | - |
20 | | - const { host, port } = client.connection; |
21 | | - const baseOptions: RequestOptions = { |
22 | | - hostname: host, |
23 | | - port, |
24 | | - method, |
25 | | - headers: { |
26 | | - "Content-Type": "application/json", |
27 | | - }, |
28 | | - }; |
29 | | - |
30 | | - return { |
31 | | - path, |
32 | | - ...baseOptions, |
33 | | - }; |
34 | | -}; |
35 | | - |
36 | | -const sendLog = async (log: TraceoLog) => { |
37 | | - const httpOptions = createHttpOptions(HTTP_ENDPOINT.LOG); |
38 | | - await sendEvent(log, httpOptions); |
39 | | -}; |
40 | | - |
41 | | -const sendRuntimeMetrics = async (data: {}) => { |
42 | | - const httpOptions = createHttpOptions(HTTP_ENDPOINT.RUNTIME); |
43 | | - await sendEvent(data, httpOptions); |
| 6 | +type HttpRequestOptions = { |
| 7 | + callback?: (stream: http.IncomingMessage) => void; |
| 8 | + onError?: (error: Error) => void; |
44 | 9 | }; |
| 10 | +export class HttpModule { |
| 11 | + host: string; |
| 12 | + url: URL; |
| 13 | + body: string; |
| 14 | + method: RequestType; |
| 15 | + |
| 16 | + constructor(url: string, body?: {}, method: RequestType = "POST") { |
| 17 | + this.host = Client.config.url; |
| 18 | + |
| 19 | + this.url = new URL(url, this.host); |
| 20 | + this.body = JSON.stringify(body); |
| 21 | + this.method = method; |
| 22 | + } |
45 | 23 |
|
46 | | -const sendMetrics = async (data: Metrics) => { |
47 | | - const httpOptions = createHttpOptions(HTTP_ENDPOINT.METRICS); |
48 | | - await sendEvent(data, httpOptions); |
49 | | -}; |
| 24 | + // TODO: implement callbacks from options later |
| 25 | + public request(_options?: HttpRequestOptions) { |
| 26 | + const requestOptions = { |
| 27 | + ...this.requestHeaders(), |
| 28 | + ...this.requestOptions(), |
| 29 | + }; |
50 | 30 |
|
51 | | -const sendIncident = async (incident: Incident) => { |
52 | | - const version = TRACEO_SDK_VERSION; |
53 | | - const baseData = { version }; |
| 31 | + const httpModule = this.requestModule(); |
54 | 32 |
|
55 | | - const payload = Object.assign(incident, baseData); |
| 33 | + const request = httpModule.request(requestOptions); |
| 34 | + request.on("error", () => {}); |
56 | 35 |
|
57 | | - const httpOptions = createHttpOptions(HTTP_ENDPOINT.INCIDENT); |
58 | | - await sendEvent(payload, httpOptions); |
59 | | -}; |
| 36 | + this.requestWriteBody(request); |
60 | 37 |
|
61 | | -const sendEvent = async ( |
62 | | - payload: any, |
63 | | - httpOptions: http.RequestOptions |
64 | | -): Promise<EventResponse | void> => { |
65 | | - const { connection, appId } = getGlobalClientData(); |
| 38 | + request.end(); |
| 39 | + } |
66 | 40 |
|
67 | | - if (!connection || !appId) { |
68 | | - return; |
| 41 | + private requestWriteBody(request: http.ClientRequest) { |
| 42 | + if (this.method === "POST") { |
| 43 | + request.write(this.body); |
| 44 | + } |
69 | 45 | } |
70 | 46 |
|
71 | | - return new Promise<EventResponse>((_, reject) => { |
72 | | - const options: http.RequestOptions = { |
73 | | - ...httpOptions, |
74 | | - path: `${httpOptions.path}/${appId}`, |
75 | | - }; |
| 47 | + private requestModule(): typeof http | typeof https { |
| 48 | + return this.clientURL.protocol == "http:" ? http : https; |
| 49 | + } |
76 | 50 |
|
77 | | - const request = http.request(options, (res: TraceoIncomingMessage) => { |
78 | | - res.setEncoding("utf8"); |
79 | | - res.on("error", reject); |
80 | | - }); |
| 51 | + private get clientURL(): URL { |
| 52 | + return new URL(this.host); |
| 53 | + } |
81 | 54 |
|
82 | | - request.on("error", () => {}); |
| 55 | + private requestOptions(): http.RequestOptions { |
| 56 | + const reqUrl = this.clientURL; |
83 | 57 |
|
84 | | - request.on("timeout", () => { |
85 | | - request.destroy(); |
86 | | - reject({ |
87 | | - statusCode: 400, |
88 | | - statusMessage: |
89 | | - "[Traceo] Error during sending event to Traceo. Connection timeout.", |
90 | | - }); |
91 | | - }); |
| 58 | + return { |
| 59 | + protocol: reqUrl.protocol, |
| 60 | + port: reqUrl.port, |
| 61 | + host: reqUrl.hostname, |
| 62 | + method: this.method, |
| 63 | + path: this.path, |
| 64 | + }; |
| 65 | + } |
92 | 66 |
|
93 | | - request.write(JSON.stringify(payload)); |
94 | | - request.end(); |
95 | | - }); |
96 | | -}; |
| 67 | + private get path() { |
| 68 | + return `${this.url.pathname}/${Client.config.appId}`; |
| 69 | + } |
97 | 70 |
|
98 | | -export const httpService = { |
99 | | - sendLog, |
100 | | - sendIncident, |
101 | | - sendRuntimeMetrics, |
102 | | - sendMetrics, |
103 | | -}; |
| 71 | + private requestHeaders() { |
| 72 | + if (this.method != "POST") return {}; |
| 73 | + return { |
| 74 | + headers: { |
| 75 | + "Content-Type": "application/json", |
| 76 | + "Content-Length": this.body.length, |
| 77 | + }, |
| 78 | + }; |
| 79 | + } |
| 80 | +} |
0 commit comments