Skip to content

Commit b10141d

Browse files
committed
Allow statusCode/headers to be set directly within HTTP Response node
1 parent 68e0b35 commit b10141d

3 files changed

Lines changed: 162 additions & 5 deletions

File tree

nodes/core/io/21-httpin.html

Lines changed: 147 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,16 @@
7979
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
8080
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
8181
</div>
82+
<div class="form-row">
83+
<label for="node-input-statusCode"><i class="fa fa-long-arrow-left"></i> <span data-i18n="httpin.label.status"></span></label>
84+
<input type="text" id="node-input-statusCode" placeholder="msg.statusCode">
85+
</div>
86+
<div class="form-row" style="margin-bottom:0;">
87+
<label><i class="fa fa-list"></i> <span data-i18n="httpin.label.headers"></span></label>
88+
</div>
89+
<div class="form-row node-input-headers-container-row">
90+
<ol id="node-input-headers-container"></ol>
91+
</div>
8292
<div class="form-tips"><span data-i18n="[html]httpin.tip.res"></span></div>
8393
</script>
8494

@@ -92,6 +102,9 @@
92102
pairs to be added as response headers.</li>
93103
<li><code>cookies</code>, if set, can be used to set or delete cookies.
94104
</ul>
105+
<p>The <code>statusCode</code> and <code>headers</code> can also be set within
106+
the node itself. If a property is set within the node, it cannot be overridden
107+
by the corresponding message property.</p>
95108
<h3>Cookie handling</h3>
96109
<p>The <code>cookies</code> property must be an object of name/value pairs.
97110
The value can be either a string to set the value of the cookie with default
@@ -120,6 +133,7 @@ <h3>Cookie handling</h3>
120133
</script>
121134

122135
<script type="text/javascript">
136+
(function() {
123137
RED.nodes.registerType('http in',{
124138
category: 'input',
125139
color:"rgb(231, 231, 174)",
@@ -180,22 +194,153 @@ <h3>Cookie handling</h3>
180194
}
181195

182196
});
197+
var headerTypes = [
198+
{value:"content-type",label:"Content-Type",hasValue: false},
199+
{value:"location",label:"Location",hasValue: false},
200+
{value:"other",label:"other",icon:"red/images/typedInput/az.png"}
201+
]
202+
var contentTypes = [
203+
{value:"application/json",label:"application/json",hasValue: false},
204+
{value:"application/xml",label:"application/xml",hasValue: false},
205+
{value:"text/css",label:"text/css",hasValue: false},
206+
{value:"text/html",label:"text/html",hasValue: false},
207+
{value:"text/plain",label:"text/plain",hasValue: false},
208+
{value:"image/gif",label:"image/gif",hasValue: false},
209+
{value:"image/png",label:"image/png",hasValue: false},
210+
{value:"other",label:"other",icon:"red/images/typedInput/az.png"}
211+
];
183212

184213
RED.nodes.registerType('http response',{
185214
category: 'output',
186215
color:"rgb(231, 231, 174)",
187216
defaults: {
188-
name: {value:""}
217+
name: {value:""},
218+
statusCode: {value:"",validate: RED.validators.number(true)},
219+
headers: {value:{}}
189220
},
190221
inputs:1,
191222
outputs:0,
192223
align: "right",
193224
icon: "white-globe.png",
194225
label: function() {
195-
return this.name||"http";
226+
return this.name||("http"+(this.statusCode?" ("+this.statusCode+")":""));
196227
},
197228
labelStyle: function() {
198229
return this.name?"node_label_italic":"";
230+
},
231+
oneditprepare: function() {
232+
function resizeRule(rule) {
233+
var newWidth = rule.width();
234+
rule.find('.red-ui-typedInput').typedInput("width",(newWidth-15)/2);
235+
236+
}
237+
var headerList = $("#node-input-headers-container").css('min-height','150px').css('min-width','450px').editableList({
238+
addItem: function(container,i,header) {
239+
var row = $('<div/>').appendTo(container);
240+
var propertyName = $('<input/>',{class:"node-input-header-name",type:"text"})
241+
.appendTo(row)
242+
.typedInput({types:headerTypes});
243+
244+
var propertyValue = $('<input/>',{class:"node-input-header-value",type:"text",style:"margin-left: 10px"})
245+
.appendTo(row)
246+
.typedInput({types:
247+
header.h === 'content-type'?contentTypes:[{value:"other",label:"other",icon:"red/images/typedInput/az.png"}]
248+
});
249+
250+
var matchedType = headerTypes.filter(function(ht) {
251+
return ht.value === header.h
252+
});
253+
if (matchedType.length === 0) {
254+
propertyName.typedInput('type','other');
255+
propertyName.typedInput('value',header.h);
256+
propertyValue.typedInput('value',header.v);
257+
} else {
258+
propertyName.typedInput('type',header.h);
259+
260+
if (header.h === "content-type") {
261+
matchedType = contentTypes.filter(function(ct) {
262+
return ct.value === header.v;
263+
});
264+
if (matchedType.length === 0) {
265+
propertyValue.typedInput('type','other');
266+
propertyValue.typedInput('value',header.v);
267+
} else {
268+
propertyValue.typedInput('type',header.v);
269+
}
270+
} else {
271+
propertyValue.typedInput('value',header.v);
272+
}
273+
}
274+
275+
matchedType = headerTypes.filter(function(ht) {
276+
return ht.value === header.h
277+
});
278+
if (matchedType.length === 0) {
279+
propertyName.typedInput('type','other');
280+
propertyName.typedInput('value',header.h);
281+
} else {
282+
propertyName.typedInput('type',header.h);
283+
}
284+
285+
propertyName.on('change',function(event) {
286+
var type = propertyName.typedInput('type');
287+
if (type === 'content-type') {
288+
propertyValue.typedInput('types',contentTypes);
289+
} else {
290+
propertyValue.typedInput('types',[{value:"other",label:"other",icon:"red/images/typedInput/az.png"}]);
291+
}
292+
});
293+
294+
295+
296+
resizeRule(container);
297+
},
298+
resizeItem: resizeRule,
299+
removable: true
300+
});
301+
302+
if (this.headers) {
303+
for (var key in this.headers) {
304+
if (this.headers.hasOwnProperty(key)) {
305+
headerList.editableList('addItem',{h:key,v:this.headers[key]});
306+
}
307+
}
308+
}
309+
},
310+
oneditsave: function() {
311+
var headers = $("#node-input-headers-container").editableList('items');
312+
var node = this;
313+
node.headers = {};
314+
headers.each(function(i) {
315+
var header = $(this);
316+
var keyType = header.find(".node-input-header-name").typedInput('type');
317+
var keyValue = header.find(".node-input-header-name").typedInput('value');
318+
var valueType = header.find(".node-input-header-value").typedInput('type');
319+
var valueValue = header.find(".node-input-header-value").typedInput('value');
320+
var key = keyType;
321+
var value = valueType;
322+
if (keyType === 'other') {
323+
key = keyValue;
324+
}
325+
if (valueType === 'other') {
326+
value = valueValue;
327+
}
328+
if (key !== '') {
329+
node.headers[key] = value;
330+
}
331+
});
332+
},
333+
oneditresize: function(size) {
334+
var rows = $("#dialog-form>div:not(.node-input-headers-container-row)");
335+
var height = size.height;
336+
for (var i=0; i<rows.size(); i++) {
337+
height -= $(rows[i]).outerHeight(true);
338+
}
339+
var editorRow = $("#dialog-form>div.node-input-headers-container-row");
340+
height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom")));
341+
342+
$("#node-input-headers-container").editableList('height',height);
199343
}
200344
});
345+
})();
201346
</script>

nodes/core/io/21-httpin.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,10 +268,20 @@ module.exports = function(RED) {
268268
function HTTPOut(n) {
269269
RED.nodes.createNode(this,n);
270270
var node = this;
271+
this.headers = n.headers||{};
272+
this.statusCode = n.statusCode;
271273
this.on("input",function(msg) {
272274
if (msg.res) {
275+
var headers = RED.util.cloneMessage(node.headers);
273276
if (msg.headers) {
274-
msg.res._res.set(msg.headers);
277+
for (var h in msg.headers) {
278+
if (msg.headers.hasOwnProperty(h) && !headers.hasOwnProperty(h)) {
279+
headers[h] = msg.headers[h];
280+
}
281+
}
282+
}
283+
if (Object.keys(headers).length > 0) {
284+
msg.res._res.set(headers);
275285
}
276286
if (msg.cookies) {
277287
for (var name in msg.cookies) {
@@ -290,7 +300,7 @@ module.exports = function(RED) {
290300
}
291301
}
292302
}
293-
var statusCode = msg.statusCode || 200;
303+
var statusCode = node.statusCode || msg.statusCode || 200;
294304
if (typeof msg.payload == "object" && !Buffer.isBuffer(msg.payload)) {
295305
msg.res._res.status(statusCode).jsonp(msg.payload);
296306
} else {

nodes/core/locales/en-US/messages.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,9 @@
314314
"url": "URL",
315315
"doc": "Docs",
316316
"return": "Return",
317-
"upload": "Accept file uploads?"
317+
"upload": "Accept file uploads?",
318+
"status": "Status code",
319+
"headers": "Headers"
318320
},
319321
"setby": "- set by msg.method -",
320322
"basicauth": "Use basic authentication",

0 commit comments

Comments
 (0)