File max_header_size.patch of Package nodejs4

Ported from:

From 59f83d689641d5030743ee4f3e453e754843e188 Mon Sep 17 00:00:00 2001
From: cjihrig <cjihrig@gmail.com>
Date: Thu, 29 Nov 2018 17:29:53 -0500
Subject: [PATCH] deps: cherry-pick http_parser_set_max_header_size
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This commit adds http_parser_set_max_header_size() to the
http-parser for overriding the compile time maximum HTTP
header size.

Backport-PR-URL: https://github.com/nodejs/node/pull/25173
PR-URL: https://github.com/nodejs/node/pull/24811
Fixes: https://github.com/nodejs/node/issues/24692
Refs: https://github.com/nodejs/http-parser/pull/453
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>



From c0c4de71f0fb7b55804a9d2110dded0493fc7c3e Mon Sep 17 00:00:00 2001
From: cjihrig <cjihrig@gmail.com>
Date: Wed, 5 Dec 2018 19:59:12 -0500
Subject: [PATCH] http: add maxHeaderSize property

This commit exposes the value of --max-http-header-size
as a property of the http module.

Backport-PR-URL: https://github.com/nodejs/node/pull/25218
PR-URL: https://github.com/nodejs/node/pull/24860
Reviewed-By: Richard Lau <riclau@uk.ibm.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Reviewed-By: Shelley Vohr <codebytere@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>


From f233b160c9b8d5126b4e4845d1661c718d14d39f Mon Sep 17 00:00:00 2001
From: cjihrig <cjihrig@gmail.com>
Date: Mon, 3 Dec 2018 12:27:46 -0500
Subject: [PATCH] cli: add --max-http-header-size flag
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Allow the maximum size of HTTP headers to be overridden from
the command line.

Backport-PR-URL: https://github.com/nodejs/node/pull/25173
co-authored-by: Matteo Collina <hello@matteocollina.com>
PR-URL: https://github.com/nodejs/node/pull/24811
Fixes: https://github.com/nodejs/node/issues/24692
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>



From 8a3e0c069747cb6a7e1889de92304856224fee72 Mon Sep 17 00:00:00 2001
From: Matteo Collina <hello@matteocollina.com>
Date: Fri, 14 Dec 2018 12:30:01 +0100
Subject: [PATCH] http: fix regression of binary upgrade response body

See: https://github.com/nodejs/node/issues/24958

PR-URL: https://github.com/nodejs/node/pull/25036
Reviewed-By: Myles Borins <myles.borins@gmail.com>

Index: node-v4.9.1/deps/http_parser/http_parser.c
===================================================================
--- node-v4.9.1.orig/deps/http_parser/http_parser.c
+++ node-v4.9.1/deps/http_parser/http_parser.c
@@ -25,6 +25,8 @@
 #include <string.h>
 #include <limits.h>
 
+static uint32_t max_header_size = HTTP_MAX_HEADER_SIZE;
+
 #ifndef ULLONG_MAX
 # define ULLONG_MAX ((uint64_t) -1) /* 2^64-1 */
 #endif
@@ -137,20 +139,20 @@ do {
 } while (0)
 
 /* Don't allow the total size of the HTTP headers (including the status
- * line) to exceed HTTP_MAX_HEADER_SIZE.  This check is here to protect
+ * line) to exceed max_header_size.  This check is here to protect
  * embedders against denial-of-service attacks where the attacker feeds
  * us a never-ending header that the embedder keeps buffering.
  *
  * This check is arguably the responsibility of embedders but we're doing
  * it on the embedder's behalf because most won't bother and this way we
- * make the web a little safer.  HTTP_MAX_HEADER_SIZE is still far bigger
+ * make the web a little safer.  max_header_size is still far bigger
  * than any reasonable request or response so this should never affect
  * day-to-day operation.
  */
 #define COUNT_HEADER_SIZE(V)                                         \
 do {                                                                 \
   parser->nread += (V);                                              \
-  if (UNLIKELY(parser->nread > (HTTP_MAX_HEADER_SIZE))) {            \
+  if (UNLIKELY(parser->nread > max_header_size)) {                   \
     SET_ERRNO(HPE_HEADER_OVERFLOW);                                  \
     goto error;                                                      \
   }                                                                  \
@@ -1471,7 +1473,7 @@ reexecute:
               const char* p_lf;
               size_t limit = data + len - p;
 
-              limit = MIN(limit, HTTP_MAX_HEADER_SIZE);
+              limit = MIN(limit, max_header_size);
 
               p_cr = (const char*) memchr(p, CR, limit);
               p_lf = (const char*) memchr(p, LF, limit);
@@ -2438,3 +2440,8 @@ http_parser_version(void) {
          HTTP_PARSER_VERSION_MINOR * 0x00100 |
          HTTP_PARSER_VERSION_PATCH * 0x00001;
 }
+
+void
+http_parser_set_max_header_size(uint32_t size) {
+  max_header_size = size;
+}
Index: node-v4.9.1/deps/http_parser/http_parser.h
===================================================================
--- node-v4.9.1.orig/deps/http_parser/http_parser.h
+++ node-v4.9.1/deps/http_parser/http_parser.h
@@ -427,6 +427,9 @@ void http_parser_pause(http_parser *pars
 /* Checks if this is the final chunk of the body. */
 int http_body_is_final(const http_parser *parser);
 
+/* Change the maximum header size provided at compile time. */
+void http_parser_set_max_header_size(uint32_t size);
+
 #ifdef __cplusplus
 }
 #endif
Index: node-v4.9.1/doc/api/http.md
===================================================================
--- node-v4.9.1.orig/doc/api/http.md
+++ node-v4.9.1/doc/api/http.md
@@ -1330,6 +1330,16 @@ added: v0.5.9
 Global instance of Agent which is used as the default for all http client
 requests.
 
+## http.maxHeaderSize
+<!-- YAML
+added: REPLACEME
+-->
+
+* {number}
+
+Read-only property specifying the maximum allowed size of HTTP headers in bytes.
+Defaults to 8KB. Configurable using the [`--max-http-header-size`][] CLI option.
+
 ## http.request(options[, callback])
 <!-- YAML
 added: v0.3.6
@@ -1439,6 +1449,7 @@ There are a few special headers that sho
 * Sending an Authorization header will override using the `auth` option
   to compute basic authentication.
 
+[`--max-http-header-size`]: cli.html#cli_max_http_header_size_size
 [`'checkContinue'`]: #http_event_checkcontinue
 [`'listening'`]: net.html#net_event_listening
 [`'response'`]: #http_event_response
Index: node-v4.9.1/lib/http.js
===================================================================
--- node-v4.9.1.orig/lib/http.js
+++ node-v4.9.1/lib/http.js
@@ -19,6 +19,8 @@ const server = require('_http_server');
 exports.ServerResponse = server.ServerResponse;
 exports.STATUS_CODES = server.STATUS_CODES;
 
+let maxHeaderSize;
+
 
 const agent = require('_http_agent');
 const Agent = exports.Agent = agent.Agent;
@@ -92,8 +94,21 @@ Client.prototype.request = function(meth
   return c;
 };
 
+
 exports.Client = internalUtil.deprecate(Client, 'http.Client is deprecated.');
 
 exports.createClient = internalUtil.deprecate(function(port, host) {
   return new Client(port, host);
 }, 'http.createClient is deprecated. Use http.request instead.');
+
+Object.defineProperty(module.exports, 'maxHeaderSize', {
+  configurable: true,
+  enumerable: true,
+  get() {
+    if (maxHeaderSize === undefined) {
+      maxHeaderSize = process.binding('config').maxHTTPHeaderSize;
+    }
+
+    return maxHeaderSize;
+  }
+});
Index: node-v4.9.1/test/parallel/test-http-max-header-size.js
===================================================================
--- /dev/null
+++ node-v4.9.1/test/parallel/test-http-max-header-size.js
@@ -0,0 +1,11 @@
+'use strict';
+
+require('../common');
+const assert = require('assert');
+const spawnSync = require('child_process').spawnSync;
+const http = require('http');
+
+assert.strictEqual(http.maxHeaderSize, 8 * 1024);
+const child = spawnSync(process.execPath, ['--max-http-header-size=10', '-p',
+                                           'require("http").maxHeaderSize']);
+assert.strictEqual(+child.stdout.toString().trim(), 10);
Index: node-v4.9.1/doc/api/cli.md
===================================================================
--- node-v4.9.1.orig/doc/api/cli.md
+++ node-v4.9.1/doc/api/cli.md
@@ -177,6 +177,12 @@ added: v0.11.15
 
 Specify ICU data load path. (overrides `NODE_ICU_DATA`)
 
+### `--max-http-header-size=size`
+<!-- YAML
+added: REPLACEME
+-->
+
+Specify the maximum size, in bytes, of HTTP headers. Defaults to 8KB.
 
 ## Environment Variables
 
Index: node-v4.9.1/doc/node.1
===================================================================
--- node-v4.9.1.orig/doc/node.1
+++ node-v4.9.1/doc/node.1
@@ -92,6 +92,10 @@ Preload the specified module at startup.
 rules. \fImodule\fR may be either a path to a file, or a node module name.
 
 .TP
+.BR \-\-max\-http\-header-size \fI=size\fR
+Specify the maximum size of HTTP headers in bytes. Defaults to 8KB.
+
+.TP
 .BR \-\-no\-deprecation
 Silence deprecation warnings.
 
Index: node-v4.9.1/src/node_config.cc
===================================================================
--- node-v4.9.1.orig/src/node_config.cc
+++ node-v4.9.1/src/node_config.cc
@@ -9,6 +9,7 @@ namespace node {
 
 using v8::Context;
 using v8::Local;
+using v8::Number;
 using v8::Object;
 using v8::Value;
 using v8::ReadOnly;
@@ -25,13 +26,25 @@ using v8::ReadOnly;
                               True(env->isolate()), ReadOnly).FromJust();     \
   } while (0)
 
+#define READONLY_PROPERTY(obj, name, value)                                   \
+  do {                                                                        \
+    obj->DefineOwnProperty(env->context(),                                    \
+                           FIXED_ONE_BYTE_STRING(env->isolate(), name),       \
+                           value, ReadOnly).FromJust();                       \
+  } while (0)
+
 void InitConfig(Local<Object> target,
                 Local<Value> unused,
                 Local<Context> context) {
-#ifdef NODE_FIPS_MODE
   Environment* env = Environment::GetCurrent(context);
+#ifdef NODE_FIPS_MODE
   READONLY_BOOLEAN_PROPERTY("fipsMode");
 #endif
+
+  READONLY_PROPERTY(target,
+                    "maxHTTPHeaderSize",
+                    Number::New(env->isolate(), max_http_header_size));
+
 }
 
 }  // namespace node
Index: node-v4.9.1/src/node_http_parser.cc
===================================================================
--- node-v4.9.1.orig/src/node_http_parser.cc
+++ node-v4.9.1/src/node_http_parser.cc
@@ -611,8 +611,6 @@ class Parser : public AsyncWrap {
     size_t nparsed =
       http_parser_execute(&parser_, &settings, data, len);
 
-    enum http_errno err = HTTP_PARSER_ERRNO(&parser_);
-
     Save();
 
     // Unassign the 'buffer_' variable
@@ -627,7 +625,9 @@ class Parser : public AsyncWrap {
     Local<Integer> nparsed_obj = Integer::New(env()->isolate(), nparsed);
     // If there was a parse error in one of the callbacks
     // TODO(bnoordhuis) What if there is an error on EOF?
-    if ((!parser_.upgrade && nparsed != len) || err != HPE_OK) {
+    if (!parser_.upgrade && nparsed != len) {
+      enum http_errno err = HTTP_PARSER_ERRNO(&parser_);
+
       Local<Value> e = Exception::Error(env()->parse_error_string());
       Local<Object> obj = e->ToObject(env()->isolate());
       obj->Set(env()->bytes_parsed_string(), nparsed_obj);
@@ -723,6 +723,9 @@ const struct http_parser_settings Parser
   nullptr   // on_chunk_complete
 };
 
+void InitMaxHttpHeaderSizeOnce() {
+  http_parser_set_max_header_size(max_http_header_size);
+}
 
 void InitHttpParser(Local<Object> target,
                     Local<Value> unused,
@@ -767,6 +770,8 @@ void InitHttpParser(Local<Object> target
 
   target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "HTTPParser"),
               t->GetFunction());
+  static uv_once_t init_once = UV_ONCE_INIT;
+  uv_once(&init_once, InitMaxHttpHeaderSizeOnce);
 }
 
 }  // namespace node
Index: node-v4.9.1/test/sequential/test-http-max-http-headers.js
===================================================================
--- node-v4.9.1.orig/test/sequential/test-http-max-http-headers.js
+++ node-v4.9.1/test/sequential/test-http-max-http-headers.js
@@ -1,10 +1,17 @@
 'use strict';
+// Flags: --expose_internals
 
 const assert = require('assert');
 const common = require('../common');
 const http = require('http');
 const net = require('net');
-const MAX = 8 * 1024; // 8KB
+const MAX = +(process.argv[2] || 8 * 1024); // Command line option, or 8KB.
+
+assert(process.binding('config').maxHTTPHeaderSize,
+       'The option should exist on process.binding(\'config\')');
+
+console.log('pid is', process.pid);
+console.log('max header size is', process.binding('config').maxHTTPHeaderSize);
 
 // Verify that we cannot receive more than 8KB of headers.
 
@@ -28,19 +35,15 @@ function fillHeaders(headers, currentSiz
   headers += 'a'.repeat(MAX - headers.length - 3);
   // Generate valid headers
   if (valid) {
-    // TODO(mcollina): understand why -9 is needed instead of -1
-    headers = headers.slice(0, -9);
+    // TODO(mcollina): understand why -32 is needed instead of -1
+    headers = headers.slice(0, -32);
   }
   return headers + '\r\n\r\n';
 }
 
-const timeout = common.platformTimeout(10);
-
 function writeHeaders(socket, headers) {
   const array = [];
-
-  // this is off from 1024 so that \r\n does not get split
-  const chunkSize = 1000;
+  const chunkSize = 100;
   let last = 0;
 
   for (let i = 0; i < headers.length / chunkSize; i++) {
@@ -55,19 +58,25 @@ function writeHeaders(socket, headers) {
   next();
 
   function next() {
-    if (socket.write(array.shift())) {
-      if (array.length === 0) {
-        socket.end();
-      } else {
-        setTimeout(next, timeout);
-      }
+    if (socket.destroyed) {
+      console.log('socket was destroyed early, data left to write:',
+                  array.join('').length);
+      return;
+    }
+
+    const chunk = array.shift();
+
+    if (chunk) {
+      console.log('writing chunk of size', chunk.length);
+      socket.write(chunk, next);
     } else {
-      socket.once('drain', next);
+      socket.end();
     }
   }
 }
 
 function test1() {
+  console.log('test1');
   let headers =
     'HTTP/1.1 200 OK\r\n' +
     'Content-Length: 0\r\n' +
@@ -82,6 +91,9 @@ function test1() {
       writeHeaders(sock, headers);
       sock.resume();
     });
+
+    // The socket might error but that's ok
+    sock.on('error', () => {});
   });
 
   server.listen(0, common.mustCall(() => {
@@ -90,17 +102,17 @@ function test1() {
 
     client.on('error', common.mustCall((err) => {
       assert.strictEqual(err.code, 'HPE_HEADER_OVERFLOW');
-      server.close();
-      setImmediate(test2);
+      server.close(test2);
     }));
   }));
 }
 
 const test2 = common.mustCall(() => {
+  console.log('test2');
   let headers =
     'GET / HTTP/1.1\r\n' +
     'Host: localhost\r\n' +
-    'Agent: node\r\n' +
+    'Agent: nod2\r\n' +
     'X-CRASH: ';
 
   // /, Host, localhost, Agent, node, X-CRASH, a...
@@ -109,7 +121,7 @@ const test2 = common.mustCall(() => {
 
   const server = http.createServer(common.mustNotCall());
 
-  server.on('clientError', common.mustCall((err) => {
+  server.once('clientError', common.mustCall((err) => {
     assert.strictEqual(err.code, 'HPE_HEADER_OVERFLOW');
   }));
 
@@ -121,34 +133,46 @@ const test2 = common.mustCall(() => {
     });
 
     finished(client, common.mustCall((err) => {
-      server.close();
-      setImmediate(test3);
+      server.close(test3);
     }));
   }));
 });
 
 const test3 = common.mustCall(() => {
+  console.log('test3');
   let headers =
     'GET / HTTP/1.1\r\n' +
     'Host: localhost\r\n' +
-    'Agent: node\r\n' +
+    'Agent: nod3\r\n' +
     'X-CRASH: ';
 
   // /, Host, localhost, Agent, node, X-CRASH, a...
   const currentSize = 1 + 4 + 9 + 5 + 4 + 7;
   headers = fillHeaders(headers, currentSize, true);
 
+  console.log('writing', headers.length);
+
   const server = http.createServer(common.mustCall((req, res) => {
-    res.end('hello world');
-    setImmediate(server.close.bind(server));
+    res.end('hello from test3 server');
+    server.close();
   }));
 
+  server.on('clientError', (err) => {
+    console.log(err.code);
+    if (err.code === 'HPE_HEADER_OVERFLOW') {
+      console.log(err.rawPacket.toString('hex'));
+    }
+  });
+  server.on('clientError', common.mustNotCall());
+
   server.listen(0, common.mustCall(() => {
     const client = net.connect(server.address().port);
     client.on('connect', () => {
       writeHeaders(client, headers);
       client.resume();
     });
+
+    client.pipe(process.stdout);
   }));
 });
 
Index: node-v4.9.1/test/sequential/test-set-http-max-http-headers.js
===================================================================
--- /dev/null
+++ node-v4.9.1/test/sequential/test-set-http-max-http-headers.js
@@ -0,0 +1,104 @@
+'use strict';
+
+const common = require('../common');
+const assert = require('assert');
+const spawn = require('child_process').spawn;
+const path = require('path');
+const testName = path.join(__dirname, 'test-http-max-http-headers.js');
+
+const timeout = common.platformTimeout(100);
+
+const tests = [];
+
+function test(fn) {
+  tests.push(fn);
+}
+
+test(function(cb) {
+  console.log('running subtest expecting failure');
+
+  // Validate that the test fails if the max header size is too small.
+  const args = ['--expose-internals',
+                '--max-http-header-size=1024',
+                testName];
+  const cp = spawn(process.execPath, args, { stdio: 'inherit' });
+
+  cp.on('close', common.mustCall((code, signal) => {
+    assert.strictEqual(code, 1);
+    assert.strictEqual(signal, null);
+    cb();
+  }));
+});
+
+test(function(cb) {
+  console.log('running subtest expecting success');
+
+  const env = Object.assign({}, process.env, {
+    NODE_DEBUG: 'http'
+  });
+
+  // Validate that the test fails if the max header size is too small.
+  // Validate that the test now passes if the same limit becomes large enough.
+  const args = ['--expose-internals',
+                '--max-http-header-size=1024',
+                testName,
+                '1024'];
+  const cp = spawn(process.execPath, args, {
+    env,
+    stdio: 'inherit'
+  });
+
+  cp.on('close', common.mustCall((code, signal) => {
+    assert.strictEqual(code, 0);
+    assert.strictEqual(signal, null);
+    cb();
+  }));
+});
+
+// Next, repeat the same checks using NODE_OPTIONS if it is supported.
+if (process.config.variables.node_without_node_options) {
+  const env = Object.assign({}, process.env, {
+    NODE_OPTIONS: '--max-http-header-size=1024'
+  });
+
+  test(function(cb) {
+    console.log('running subtest expecting failure');
+
+    // Validate that the test fails if the max header size is too small.
+    const args = ['--expose-internals', testName];
+    const cp = spawn(process.execPath, args, { env, stdio: 'inherit' });
+
+    cp.on('close', common.mustCall((code, signal) => {
+      assert.strictEqual(code, 1);
+      assert.strictEqual(signal, null);
+      cb();
+    }));
+  });
+
+  test(function(cb) {
+    // Validate that the test now passes if the same limit
+    // becomes large enough.
+    const args = ['--expose-internals', testName, '1024'];
+    const cp = spawn(process.execPath, args, { env, stdio: 'inherit' });
+
+    cp.on('close', common.mustCall((code, signal) => {
+      assert.strictEqual(code, 0);
+      assert.strictEqual(signal, null);
+      cb();
+    }));
+  });
+}
+
+function runTest() {
+  const fn = tests.shift();
+
+  if (!fn) {
+    return;
+  }
+
+  fn(() => {
+    setTimeout(runTest, timeout);
+  });
+}
+
+runTest();
Index: node-v4.9.1/src/node_internals.h
===================================================================
--- node-v4.9.1.orig/src/node_internals.h
+++ node-v4.9.1/src/node_internals.h
@@ -30,6 +30,9 @@ struct sockaddr;
 
 namespace node {
 
+// Set in node.cc by ParseArgs when --max-http-header-size is used
+extern uint64_t max_http_header_size;
+
 // Forward declaration
 class Environment;
 
Index: node-v4.9.1/src/node.cc
===================================================================
--- node-v4.9.1.orig/src/node.cc
+++ node-v4.9.1/src/node.cc
@@ -161,6 +161,8 @@ unsigned int reverted = 0;
 static const char* icu_data_dir = nullptr;
 #endif
 
+uint64_t max_http_header_size = 8 * 1024;
+
 // used by C++ modules as well
 bool no_deprecation = false;
 
@@ -3409,6 +3411,8 @@ static void PrintHelp() {
          "  --trace-deprecation   show stack traces on deprecations\n"
          "  --throw-deprecation   throw an exception anytime a deprecated "
          "function is used\n"
+         "  --max-http-header-size     Specify the maximum size of HTTP\n"
+         "                             headers in bytes. Defaults to 8KB.\n"
          "  --trace-sync-io       show stack trace when use of sync IO\n"
          "                        is detected after the first tick\n"
          "  --track-heap-objects  track heap object allocations for heap "
@@ -3558,6 +3562,8 @@ static void ParseArgs(int* argc,
       short_circuit = true;
     } else if (strcmp(arg, "--zero-fill-buffers") == 0) {
       zero_fill_all_buffers = true;
+    } else if (strncmp(arg, "--max-http-header-size=", 23) == 0) {
+      max_http_header_size = atoi(arg + 23);
     } else if (strcmp(arg, "--v8-options") == 0) {
       new_v8_argv[new_v8_argc] = "--help";
       new_v8_argc += 1;
Index: node-v4.9.1/test/common.js
===================================================================
--- node-v4.9.1.orig/test/common.js
+++ node-v4.9.1/test/common.js
@@ -410,6 +410,26 @@ exports.mustCall = function(fn, expected
   };
 };
 
+exports.getCallSite = function getCallSite(top) {
+  const originalStackFormatter = Error.prepareStackTrace;
+  Error.prepareStackTrace = (err, stack) =>
+    `${stack[0].getFileName()}:${stack[0].getLineNumber()}`;
+  const err = new Error();
+  Error.captureStackTrace(err, top);
+  // with the V8 Error API, the stack is not formatted until it is accessed
+  err.stack;
+  Error.prepareStackTrace = originalStackFormatter;
+  return err.stack;
+};
+
+exports.mustNotCall = function(msg) {
+  const callSite = exports.getCallSite(exports.mustNotCall);
+  return function mustNotCall() {
+    assert.fail(
+      `${msg || 'function should not have been called'} at ${callSite}`);
+  };
+};
+
 var etcServicesFileName = path.join('/etc', 'services');
 if (exports.isWindows) {
   etcServicesFileName = path.join(process.env.SystemRoot, 'System32', 'drivers',
openSUSE Build Service is sponsored by