From da0f60744560c81cddbddd6785b6241bc216bac4 Mon Sep 17 00:00:00 2001 From: Tyler Brock Date: Sun, 27 May 2018 11:52:58 -0700 Subject: [PATCH] Use http agents for hook requests --- src/Controllers/HooksController.js | 21 +++++++++++++++++---- src/Controllers/index.js | 6 +++--- src/Options/index.js | 2 ++ 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/Controllers/HooksController.js b/src/Controllers/HooksController.js index 70598bb125..8336ddeba4 100644 --- a/src/Controllers/HooksController.js +++ b/src/Controllers/HooksController.js @@ -6,18 +6,26 @@ import * as Parse from "parse/node"; // @flow-disable-next import * as request from "request"; import { logger } from '../logger'; +import http from 'http'; +import https from 'https'; const DefaultHooksCollectionName = "_Hooks"; +const HTTPAgents = { + http: new http.Agent({ keepAlive: true }), + https: new https.Agent({ keepAlive: true }), +} export class HooksController { _applicationId:string; _webhookKey:string; database: any; + keepAlive: boolean; - constructor(applicationId:string, databaseController, webhookKey) { + constructor(applicationId:string, databaseController, webhookKey, keepAlive) { this._applicationId = applicationId; this._webhookKey = webhookKey; this.database = databaseController; + this.keepAlive = keepAlive; } load() { @@ -85,7 +93,7 @@ export class HooksController { } addHookToTriggers(hook) { - var wrappedFunction = wrapToHTTPRequest(hook, this._webhookKey); + var wrappedFunction = wrapToHTTPRequest(hook, this._webhookKey, this.keepAlive); wrappedFunction.url = hook.url; if (hook.className) { triggers.addTrigger(hook.triggerName, hook.className, wrappedFunction, this._applicationId) @@ -159,7 +167,7 @@ export class HooksController { } } -function wrapToHTTPRequest(hook, key) { +function wrapToHTTPRequest(hook, key, keepAlive) { return (req, res) => { const jsonBody = {}; for (var i in req) { @@ -177,9 +185,14 @@ function wrapToHTTPRequest(hook, key) { headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(jsonBody) + body: JSON.stringify(jsonBody), }; + if (keepAlive) { + const agent = hook.url.startsWith('https') ? HTTPAgents['https'] : HTTPAgents['http']; + jsonRequest.agent = agent; + } + if (key) { jsonRequest.headers['X-Parse-Webhook-Key'] = key; } else { diff --git a/src/Controllers/index.js b/src/Controllers/index.js index 7f0288a481..19588c9b34 100644 --- a/src/Controllers/index.js +++ b/src/Controllers/index.js @@ -149,9 +149,10 @@ export function getDatabaseController(options: ParseServerOptions, cacheControll export function getHooksController(options: ParseServerOptions, databaseController: DatabaseController): HooksController { const { appId, - webhookKey + webhookKey, + hookKeepAlive, } = options; - return new HooksController(appId, databaseController, webhookKey); + return new HooksController(appId, databaseController, webhookKey, hookKeepAlive); } interface PushControlling { @@ -228,4 +229,3 @@ export function getDatabaseAdapter(databaseURI, collectionPrefix, databaseOption }); } } - diff --git a/src/Options/index.js b/src/Options/index.js index e4f6c24dfb..bcdb53c8a1 100644 --- a/src/Options/index.js +++ b/src/Options/index.js @@ -131,6 +131,8 @@ export interface ParseServerOptions { startLiveQueryServer: ?boolean; /* Live query server configuration options (will start the liveQuery server) */ liveQueryServerOptions: ?LiveQueryServerOptions; + /* Keep hook HTTP connections alive */ + hookKeepAlive: ?boolean; __indexBuildCompletionCallbackForTests: ?()=>void; }