From 0cc64a557926c9815e27a2fd39ececf836cbe7f5 Mon Sep 17 00:00:00 2001
From: Frank Jogeleit <frank.jogeleit@web.de>
Date: Wed, 7 Oct 2020 18:29:38 +0200
Subject: [PATCH] Support for unescaped newlines in data (#16)

* support newline escaping
---
 .github/workflows/test.yml | 12 ++++++++++++
 README.md                  |  1 +
 action.yml                 |  3 +++
 dist/index.js              | 13 ++++++++++---
 src/httpClient.js          | 10 ++++++++--
 src/index.js               |  3 ++-
 6 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index e6cb058..3841dcf 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -23,6 +23,18 @@ jobs:
           method: 'POST'
           data: '{ "key": "value" }'
       
+      - name: Request Postment Echo POST
+        uses: ./
+        with:
+          url: 'https://postman-echo.com/post'
+          method: 'POST'
+          escapeData: 'true'
+          data: >-
+            {
+              "key":"multi line\ntest
+              text"
+            }
+      
       - name: Request Postment Echo BasicAuth
         uses: ./
         with:
diff --git a/README.md b/README.md
index ef619b0..30a3116 100644
--- a/README.md
+++ b/README.md
@@ -29,6 +29,7 @@ jobs:
 |bearerToken| Bearer Authentication Token (without Bearer Prefix) ||
 |customHeaders| Additional header values as JSON string, keys in this object overwrite default headers like Content-Type |'{}'|
 |preventFailureOnNoResponse| Prevent this Action to fail if the request respond without an response. Use 'true' (string) as value to enable it ||
+|escapeData| Escape newlines in data string content. Use 'true' (string) as value to enable it ||
 
 ### Output
 
diff --git a/action.yml b/action.yml
index ad2dbc2..987e5aa 100644
--- a/action.yml
+++ b/action.yml
@@ -35,6 +35,9 @@ inputs:
     preventFailureOnNoResponse:
         description: 'Prevent this Action to fail if the request respond without an response'
         required: false
+    escapeData:
+        description: 'Escape newlines in data string content'
+        required: false
 outputs:
     response:
         description: 'HTTP Response Content'
diff --git a/dist/index.js b/dist/index.js
index e57a210..94efe5f 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -1023,10 +1023,16 @@ const axios = __webpack_require__(53);
 const METHOD_GET = 'GET'
 const METHOD_POST = 'POST'
 
-const request = async({ method, instanceConfig, data, auth, actions, preventFailureOnNoResponse }) => {
+const request = async({ method, instanceConfig, data, auth, actions, preventFailureOnNoResponse, escapeData }) => {
   try {
     const instance = axios.create(instanceConfig);
 
+    if (escapeData) {
+      data = data.replace(/"[^"]*"/g, (match) => { 
+          return match.replace(/[\n\r]\s*/g, "\\n");
+      }); 
+    }
+
     const jsonData = method === METHOD_GET ? undefined : JSON.parse(data)
 
     const requestData = {
@@ -1052,7 +1058,7 @@ const request = async({ method, instanceConfig, data, auth, actions, preventFail
     } else if (error.request && preventFailureOnNoResponse) {
       actions.warning(JSON.stringify(error));
     } else {
-      actions.setFailed(error.message);
+      actions.setFailed(JSON.stringify({ message: error.message, data }));
     }
   }
 }
@@ -2612,8 +2618,9 @@ core.debug('Instance Configuration: ' + JSON.stringify(instanceConfig))
 const data = core.getInput('data') || '{}';
 const method = core.getInput('method') || METHOD_POST;
 const preventFailureOnNoResponse = core.getInput('preventFailureOnNoResponse') === 'true';
+const escapeData = core.getInput('escapeData') === 'true';
 
-request({ data, method, instanceConfig, auth, preventFailureOnNoResponse, actions: new GithubActions() })
+request({ data, method, instanceConfig, auth, preventFailureOnNoResponse, escapeData, actions: new GithubActions() })
 
 
 /***/ }),
diff --git a/src/httpClient.js b/src/httpClient.js
index 3a4ff02..620c880 100644
--- a/src/httpClient.js
+++ b/src/httpClient.js
@@ -3,10 +3,16 @@ const axios = require("axios");
 const METHOD_GET = 'GET'
 const METHOD_POST = 'POST'
 
-const request = async({ method, instanceConfig, data, auth, actions, preventFailureOnNoResponse }) => {
+const request = async({ method, instanceConfig, data, auth, actions, preventFailureOnNoResponse, escapeData }) => {
   try {
     const instance = axios.create(instanceConfig);
 
+    if (escapeData) {
+      data = data.replace(/"[^"]*"/g, (match) => { 
+          return match.replace(/[\n\r]\s*/g, "\\n");
+      }); 
+    }
+
     const jsonData = method === METHOD_GET ? undefined : JSON.parse(data)
 
     const requestData = {
@@ -32,7 +38,7 @@ const request = async({ method, instanceConfig, data, auth, actions, preventFail
     } else if (error.request && preventFailureOnNoResponse) {
       actions.warning(JSON.stringify(error));
     } else {
-      actions.setFailed(error.message);
+      actions.setFailed(JSON.stringify({ message: error.message, data }));
     }
   }
 }
diff --git a/src/index.js b/src/index.js
index 2ab8255..18220ac 100644
--- a/src/index.js
+++ b/src/index.js
@@ -39,5 +39,6 @@ core.debug('Instance Configuration: ' + JSON.stringify(instanceConfig))
 const data = core.getInput('data') || '{}';
 const method = core.getInput('method') || METHOD_POST;
 const preventFailureOnNoResponse = core.getInput('preventFailureOnNoResponse') === 'true';
+const escapeData = core.getInput('escapeData') === 'true';
 
-request({ data, method, instanceConfig, auth, preventFailureOnNoResponse, actions: new GithubActions() })
+request({ data, method, instanceConfig, auth, preventFailureOnNoResponse, escapeData, actions: new GithubActions() })