Skip to content

Commit 0b91468

Browse files
committed
Merge branch 'tlwr-feature-http-request'
2 parents 45a9da5 + 127364e commit 0b91468

File tree

3 files changed

+143
-1
lines changed

3 files changed

+143
-1
lines changed

src/core/config/Categories.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ const Categories = [
126126
{
127127
name: "Networking",
128128
ops: [
129+
"HTTP request",
129130
"Strip HTTP headers",
130131
"Parse User Agent",
131132
"Parse IP range",

src/core/config/OperationConfig.js

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3397,7 +3397,49 @@ const OperationConfig = {
33973397
run: Image.runRemoveEXIF,
33983398
inputType: "byteArray",
33993399
outputType: "byteArray",
3400-
args: [],
3400+
args: []
3401+
},
3402+
"HTTP request": {
3403+
description: [
3404+
"Makes an HTTP request and returns the response.",
3405+
"<br><br>",
3406+
"This operation supports different HTTP verbs like GET, POST, PUT, etc.",
3407+
"<br><br>",
3408+
"You can add headers line by line in the format <code>Key: Value</code>",
3409+
"<br><br>",
3410+
"The status code of the response, along with a limited selection of exposed headers, can be viewed by checking the 'Show response metadata' option. Only a limited set of response headers are exposed by the browser for security reasons.",
3411+
].join("\n"),
3412+
run: HTTP.runHTTPRequest,
3413+
inputType: "string",
3414+
outputType: "string",
3415+
manualBake: true,
3416+
args: [
3417+
{
3418+
name: "Method",
3419+
type: "option",
3420+
value: HTTP.METHODS,
3421+
},
3422+
{
3423+
name: "URL",
3424+
type: "string",
3425+
value: "",
3426+
},
3427+
{
3428+
name: "Headers",
3429+
type: "text",
3430+
value: "",
3431+
},
3432+
{
3433+
name: "Mode",
3434+
type: "option",
3435+
value: HTTP.MODE,
3436+
},
3437+
{
3438+
name: "Show response metadata",
3439+
type: "boolean",
3440+
value: false,
3441+
}
3442+
]
34013443
},
34023444
};
34033445

src/core/operations/HTTP.js

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,17 @@ import {UAS_parser as UAParser} from "../lib/uas_parser.js";
1212
*/
1313
const HTTP = {
1414

15+
/**
16+
* @constant
17+
* @default
18+
*/
19+
METHODS: [
20+
"GET", "POST", "HEAD",
21+
"PUT", "PATCH", "DELETE",
22+
"CONNECT", "TRACE", "OPTIONS"
23+
],
24+
25+
1526
/**
1627
* Strip HTTP headers operation.
1728
*
@@ -51,6 +62,94 @@ const HTTP = {
5162
"Device Type: " + ua.deviceType + "\n";
5263
},
5364

65+
66+
/**
67+
* @constant
68+
* @default
69+
*/
70+
MODE: [
71+
"Cross-Origin Resource Sharing",
72+
"No CORS (limited to HEAD, GET or POST)",
73+
],
74+
75+
/**
76+
* Lookup table for HTTP modes
77+
*
78+
* @private
79+
* @constant
80+
*/
81+
_modeLookup: {
82+
"Cross-Origin Resource Sharing": "cors",
83+
"No CORS (limited to HEAD, GET or POST)": "no-cors",
84+
},
85+
86+
/**
87+
* HTTP request operation.
88+
*
89+
* @author tlwr [[email protected]]
90+
* @author n1474335 [[email protected]]
91+
* @param {string} input
92+
* @param {Object[]} args
93+
* @returns {string}
94+
*/
95+
runHTTPRequest(input, args) {
96+
const method = args[0],
97+
url = args[1],
98+
headersText = args[2],
99+
mode = args[3],
100+
showResponseMetadata = args[4];
101+
102+
if (url.length === 0) return "";
103+
104+
let headers = new Headers();
105+
headersText.split(/\r?\n/).forEach(line => {
106+
line = line.trim();
107+
108+
if (line.length === 0) return;
109+
110+
let split = line.split(":");
111+
if (split.length !== 2) throw `Could not parse header in line: ${line}`;
112+
113+
headers.set(split[0].trim(), split[1].trim());
114+
});
115+
116+
let config = {
117+
method: method,
118+
headers: headers,
119+
mode: HTTP._modeLookup[mode],
120+
cache: "no-cache",
121+
};
122+
123+
if (method !== "GET" && method !== "HEAD") {
124+
config.body = input;
125+
}
126+
127+
return fetch(url, config)
128+
.then(r => {
129+
if (r.status === 0 && r.type === "opaque") {
130+
return "Error: Null response. Try setting the connection mode to CORS.";
131+
}
132+
133+
if (showResponseMetadata) {
134+
let headers = "";
135+
for (let pair of r.headers.entries()) {
136+
headers += " " + pair[0] + ": " + pair[1] + "\n";
137+
}
138+
return r.text().then(b => {
139+
return "####\n Status: " + r.status + " " + r.statusText +
140+
"\n Exposed headers:\n" + headers + "####\n\n" + b;
141+
});
142+
}
143+
return r.text();
144+
})
145+
.catch(e => {
146+
return e.toString() +
147+
"\n\nThis error could be caused by one of the following:\n" +
148+
" - An invalid URL\n" +
149+
" - Making a cross-origin request to a server which does not support CORS\n";
150+
});
151+
},
152+
54153
};
55154

56155
export default HTTP;

0 commit comments

Comments
 (0)