@@ -9,11 +9,40 @@ module.exports = function (RED) {
9
9
RED . nodes . createNode ( this , config ) ;
10
10
var node = this ;
11
11
12
+ var paytoqs = config . paytoqs || "ignore" ;
13
+
14
+ function _stringifyParams ( params ) {
15
+ var paramList = [ ] ;
16
+ for ( var [ key , value ] of Object . entries ( params ) ) {
17
+ var dataType = typeof value ;
18
+ if ( [ "string" , "number" ] . includes ( dataType ) ) {
19
+ paramList . push ( `${ key } =${ value } ` ) ;
20
+ }
21
+ }
22
+
23
+ return paramList . join ( "&" ) ;
24
+ }
25
+
26
+ function _appendQueryParams ( reqOpts , payload ) {
27
+ if ( typeof payload === "object" ) {
28
+ var newParams = _stringifyParams ( payload ) ;
29
+ if ( newParams && reqOpts . query !== "" ) {
30
+ newParams = "&" + newParams ;
31
+ }
32
+
33
+ reqOpts . query = reqOpts . query + newParams ;
34
+ } else {
35
+ throw new Error ( "Hallo" ) ;
36
+ }
37
+ }
38
+
12
39
function _constructPayload ( msg , contentFormat ) {
13
40
var payload = null ;
14
41
15
- if ( contentFormat === "text/plain" ) {
16
- payload = msg . payload ;
42
+ if ( ! msg . payload ) {
43
+ return null ;
44
+ } else if ( contentFormat === "text/plain" ) {
45
+ payload = msg . payload . toString ( ) ;
17
46
} else if ( contentFormat === "application/json" ) {
18
47
payload = JSON . stringify ( msg . payload ) ;
19
48
} else if ( contentFormat === "application/cbor" ) {
@@ -49,18 +78,26 @@ module.exports = function (RED) {
49
78
port : url . port ,
50
79
query : url . search . substring ( 1 ) ,
51
80
} ;
52
- reqOpts . method = (
53
- config . method ||
54
- msg . method ||
55
- "GET"
56
- ) . toUpperCase ( ) ;
57
- reqOpts . headers = { } ;
58
- reqOpts . headers [ "Content-Format" ] = config [ "content-format" ] ;
81
+ reqOpts . method = config . method . toUpperCase ( ) || "GET" ;
82
+ if ( config . method === "use" && msg . method != null ) {
83
+ reqOpts . method = msg . method . toUpperCase ( ) ;
84
+ }
85
+
86
+ reqOpts . headers = msg . headers ;
87
+ if ( reqOpts . headers == null ) {
88
+ reqOpts . headers = { } ;
89
+ }
90
+ if ( reqOpts . headers [ "Content-Format" ] == null ) {
91
+ reqOpts . headers [ "Content-Format" ] = "application/json" ;
92
+ }
59
93
reqOpts . multicast = config . multicast ;
60
94
reqOpts . multicastTimeout = config . multicastTimeout ;
61
95
62
96
function _onResponse ( res ) {
63
97
function _send ( payload ) {
98
+ if ( ! reqOpts . observe ) {
99
+ node . status ( { } ) ;
100
+ }
64
101
node . send (
65
102
Object . assign ( { } , msg , {
66
103
payload : payload ,
@@ -71,31 +108,38 @@ module.exports = function (RED) {
71
108
}
72
109
73
110
function _onResponseData ( data ) {
74
- if ( config [ "raw-buffer" ] ) {
111
+ var contentFormat = res . headers [ "Content-Format" ] ;
112
+ var configContentFormat = config [ "content-format" ] ;
113
+
114
+ if ( config [ "raw-buffer" ] === true || configContentFormat === "raw-buffer" ) {
75
115
_send ( data ) ;
76
- } else if ( res . headers [ "Content-Format" ] === "text/plain" ) {
116
+ } else if ( contentFormat === "text/plain" || configContentFormat === "text/plain" ) {
77
117
_send ( data . toString ( ) ) ;
78
- } else if (
79
- res . headers [ "Content-Format" ] === "application/json"
80
- ) {
118
+ } else if ( contentFormat . startsWith ( "application/" ) && contentFormat . includes ( "json" ) ) {
81
119
try {
82
120
_send ( JSON . parse ( data . toString ( ) ) ) ;
83
121
} catch ( error ) {
122
+ node . status ( {
123
+ fill : "red" ,
124
+ shape : "ring" ,
125
+ text : error . message ,
126
+ } ) ;
84
127
node . error ( error . message ) ;
85
128
}
86
- } else if (
87
- res . headers [ "Content-Format" ] === "application/cbor"
88
- ) {
89
- cbor . decodeAll ( data , function ( err , data ) {
90
- if ( err ) {
129
+ } else if ( contentFormat . startsWith ( "application/" ) && contentFormat . includes ( "cbor" ) ) {
130
+ cbor . decodeAll ( data , function ( error , data ) {
131
+ if ( error ) {
132
+ node . error ( error . message ) ;
133
+ node . status ( {
134
+ fill : "red" ,
135
+ shape : "ring" ,
136
+ text : error . message ,
137
+ } ) ;
91
138
return false ;
92
139
}
93
140
_send ( data [ 0 ] ) ;
94
141
} ) ;
95
- } else if (
96
- res . headers [ "Content-Format" ] ===
97
- "application/link-format"
98
- ) {
142
+ } else if ( contentFormat === "application/link-format" ) {
99
143
_send ( linkFormat . parse ( data . toString ( ) ) ) ;
100
144
} else {
101
145
_send ( data . toString ( ) ) ;
@@ -104,40 +148,70 @@ module.exports = function (RED) {
104
148
105
149
res . on ( "data" , _onResponseData ) ;
106
150
107
- if ( reqOpts . observe ) {
151
+ if ( reqOpts . observe === true ) {
152
+ node . status ( {
153
+ fill : "blue" ,
154
+ shape : "dot" ,
155
+ text : "coapRequest.status.observing" ,
156
+ } ) ;
108
157
node . stream = res ;
109
158
}
110
159
}
111
160
112
- var payload = _constructPayload ( msg , config [ "content-format" ] ) ;
161
+ var payload ;
162
+
163
+ if ( reqOpts . method !== "GET" ) {
164
+ payload = _constructPayload ( msg , reqOpts . headers [ "Content-Format" ] ) ;
165
+ } else if ( paytoqs === "query" ) {
166
+ try {
167
+ _appendQueryParams ( reqOpts , msg . payload ) ;
168
+ } catch ( error ) {
169
+ node . error ( "Coap request: Invalid payload format!" ) ;
170
+ return ;
171
+ }
172
+ }
113
173
114
174
if ( config . observe === true ) {
115
175
reqOpts . observe = true ;
116
176
} else {
117
177
delete reqOpts . observe ;
118
178
}
119
179
120
- //TODO: should revisit this block
180
+ // TODO: should revisit this block
121
181
if ( node . stream ) {
122
182
node . stream . close ( ) ;
123
183
}
124
184
125
185
var req = coap . request ( reqOpts ) ;
126
186
req . on ( "response" , _onResponse ) ;
127
- req . on ( "error" , function ( err ) {
187
+ req . on ( "error" , function ( error ) {
188
+ node . status ( {
189
+ fill : "red" ,
190
+ shape : "ring" ,
191
+ text : error . message ,
192
+ } ) ;
128
193
node . log ( "client error" ) ;
129
- node . log ( err ) ;
194
+ node . log ( error . message ) ;
130
195
} ) ;
131
196
132
- if ( payload ) {
197
+ if ( payload != null ) {
133
198
req . write ( payload ) ;
134
199
}
135
200
req . end ( ) ;
136
201
}
137
202
138
203
this . on ( "input" , function ( msg ) {
204
+ node . status ( {
205
+ fill : "blue" ,
206
+ shape : "dot" ,
207
+ text : "coapRequest.status.requesting" ,
208
+ } ) ;
139
209
_makeRequest ( msg ) ;
140
210
} ) ;
211
+
212
+ this . on ( "close" , function ( ) {
213
+ node . status ( { } ) ;
214
+ } ) ;
141
215
}
142
216
RED . nodes . registerType ( "coap request" , CoapRequestNode ) ;
143
217
} ;
0 commit comments