@openziti/ziti-sdk-nodejs 0.12.0 → 0.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -4
- package/lib/httpRequest.js +2 -2
- package/lib/init.js +5 -0
- package/package.json +1 -1
- package/src/Ziti_https_request.c +162 -62
- package/src/ziti-nodejs.h +2 -0
- package/src/ziti_init.c +71 -0
package/README.md
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
<p align="center" width="100%">
|
|
2
|
+
OpenZiti is a free and open source project focused on bringing zero trust to any application.
|
|
3
|
+
<br>
|
|
4
|
+
The project provides all the pieces required to implement or integrate zero trust into your solutions.
|
|
5
|
+
<br/>
|
|
6
|
+
<br/>
|
|
7
|
+
Please star us.
|
|
8
|
+
<br/>
|
|
9
|
+
<a href="https://github.com/openziti/ziti/stargazers"><img src="https://img.shields.io/github/stars/openziti/ziti?style=flat" ></a>
|
|
10
|
+
<br/>
|
|
11
|
+
<br>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
1
14
|
<p align="center" width="100%">
|
|
2
15
|
<a href="https://openziti.io"><img src="ziti.png" width="100"></a>
|
|
3
16
|
</p>
|
|
@@ -8,7 +21,7 @@
|
|
|
8
21
|
<br>
|
|
9
22
|
<br>
|
|
10
23
|
<b>
|
|
11
|
-
|
|
24
|
+
This repo hosts the OpenZiti SDK for NodeJS, and is designed to help you deliver secure applications over a <a href="https://openziti.io">OpenZiti Network</a>
|
|
12
25
|
<br>
|
|
13
26
|
<br>
|
|
14
27
|
<b>Part of the <a href="https://openziti.io/about">OpenZiti</a> ecosystem</b>
|
|
@@ -33,6 +46,9 @@
|
|
|
33
46
|
|
|
34
47
|
---
|
|
35
48
|
|
|
49
|
+
# Associated Article(s)
|
|
50
|
+
For more context on this SDK, you may be interested in this
|
|
51
|
+
[article concerning how to secure NodeJS applications](https://openziti.io/securing-nodejs-applications)
|
|
36
52
|
|
|
37
53
|
|
|
38
54
|
|
|
@@ -51,9 +67,14 @@ Binaries for most Node versions and platforms are provided by default via [@mapb
|
|
|
51
67
|
|
|
52
68
|
# Installing
|
|
53
69
|
|
|
70
|
+
NPM
|
|
54
71
|
``` js
|
|
55
72
|
npm i @openziti/ziti-sdk-nodejs
|
|
56
73
|
```
|
|
74
|
+
or Yarn
|
|
75
|
+
``` js
|
|
76
|
+
yarn add @openziti/ziti-sdk-nodejs
|
|
77
|
+
```
|
|
57
78
|
|
|
58
79
|
Special note on previous package:
|
|
59
80
|
|
|
@@ -68,6 +89,59 @@ npm install @openziti/ziti-sdk-nodejs --save
|
|
|
68
89
|
|
|
69
90
|
**Note:** the module must be [installed](#installing) before use.
|
|
70
91
|
|
|
92
|
+
ESM example (client-side)
|
|
93
|
+
``` js
|
|
94
|
+
import ziti from '@openziti/ziti-sdk-nodejs';
|
|
95
|
+
|
|
96
|
+
// Somehow provide path to identity file, e.g. via env var
|
|
97
|
+
const zitiIdentityFile = process.env.ZITI_IDENTITY_FILE;
|
|
98
|
+
// Authenticate ourselves onto the Ziti network
|
|
99
|
+
await ziti.init( zitiIdentityFile ).catch(( err ) => { /* probably exit */ });
|
|
100
|
+
|
|
101
|
+
const on_resp_data = ( obj ) => {
|
|
102
|
+
console.log(`response is: ${obj.body.toString('utf8')}`);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
// Perform an HTTP GET request to a dark OpenZiti web service
|
|
106
|
+
ziti.httpRequest(
|
|
107
|
+
'myDarkWebService',
|
|
108
|
+
'GET',
|
|
109
|
+
'/', // path
|
|
110
|
+
['Accept: application/json' ], // headers
|
|
111
|
+
undefined, // optional on_req cb
|
|
112
|
+
undefined, // optional on_req_data cb
|
|
113
|
+
on_resp_data // optional on_resp_data cb
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
ESM example (server-side ExpressJS)
|
|
119
|
+
``` js
|
|
120
|
+
import ziti from '@openziti/ziti-sdk-nodejs';
|
|
121
|
+
import express from 'express';
|
|
122
|
+
let app = ziti.express( express, zitiServiceName );
|
|
123
|
+
app.listen(ignored, function() { ... }
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
|
|
127
|
+
That's right.
|
|
128
|
+
|
|
129
|
+
With only a single-line code change (the ziti.express call), your web server is now capable
|
|
130
|
+
of being invisible to malicious attackers on the internet, and only accessible to your
|
|
131
|
+
trusted remote users.
|
|
132
|
+
|
|
133
|
+
Nothing else in your existing ExpressJS web server code needs to change!
|
|
134
|
+
|
|
135
|
+
Existing routing, middleware, etc., all operates the same as it always did...
|
|
136
|
+
but now you enjoy the comfort of knowing that if a connection comes in, it is from
|
|
137
|
+
a trusted identity on the client side.
|
|
138
|
+
|
|
139
|
+
No malicious actors can see your dark web server, and thus, no malicious actors can attack it.
|
|
140
|
+
|
|
141
|
+
*/
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
CJS example (client-side)
|
|
71
145
|
``` js
|
|
72
146
|
var ziti = require('@openziti/ziti-sdk-nodejs');
|
|
73
147
|
|
|
@@ -134,6 +208,9 @@ const ziti_write = (conn, data) => {
|
|
|
134
208
|
|
|
135
209
|
# Ziti NodeJS SDK - Setup for Development
|
|
136
210
|
|
|
211
|
+
NOTE: You don't need to compile this SDK in order to use it (we publish pre-built binaries for your OS, NodeJS version, and CPU architecture).
|
|
212
|
+
The following information applies only if you are doing development on the SDK itself.
|
|
213
|
+
|
|
137
214
|
The following steps should get your NodeJS SDK for Ziti building. The Ziti NodeJS SDK is a native addon for Node JS,
|
|
138
215
|
and is written in C. C development is specific to your operating system and tool chain used. These steps should work
|
|
139
216
|
properly for you but if your OS has variations you may need to adapt these steps accordingly.
|
|
@@ -159,11 +236,10 @@ $ npm run build
|
|
|
159
236
|
|
|
160
237
|
Getting Help
|
|
161
238
|
------------
|
|
162
|
-
Please use these community resources for getting help. We use GitHub [issues](https://github.com/
|
|
239
|
+
Please use these community resources for getting help. We use GitHub [issues](https://github.com/openziti/ziti-sdk-nodejs/issues)
|
|
163
240
|
for tracking bugs and feature requests and have limited bandwidth to address them.
|
|
164
241
|
|
|
165
|
-
- Read the [docs](https://
|
|
166
|
-
- Join our [Developer Community](https://developer.netfoundry.io)
|
|
242
|
+
- Read the [docs](https://openziti.github.io/ziti/overview.html)
|
|
167
243
|
- Participate in discussion on [Discourse](https://openziti.discourse.group/)
|
|
168
244
|
|
|
169
245
|
|
package/lib/httpRequest.js
CHANGED
|
@@ -46,7 +46,7 @@ const on_resp_data = ( obj ) => {
|
|
|
46
46
|
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
-
const httpRequest = ( url, method, headers, on_req_cb, on_resp_cb, on_resp_data_cb ) => {
|
|
49
|
+
const httpRequest = ( url, method, path, headers, on_req_cb, on_resp_cb, on_resp_data_cb ) => {
|
|
50
50
|
|
|
51
51
|
console.log('httpRequest entered: ', url, method, headers);
|
|
52
52
|
|
|
@@ -72,7 +72,7 @@ const httpRequest = ( url, method, headers, on_req_cb, on_resp_cb, on_resp_data_
|
|
|
72
72
|
_on_resp_data_cb = on_resp_data_cb;
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
ziti.Ziti_http_request( url, method, headers, _on_req_cb, _on_resp_cb, _on_resp_data_cb );
|
|
75
|
+
ziti.Ziti_http_request( url, method, path, headers, _on_req_cb, _on_resp_cb, _on_resp_data_cb );
|
|
76
76
|
|
|
77
77
|
};
|
|
78
78
|
|
package/lib/init.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openziti/ziti-sdk-nodejs",
|
|
3
3
|
"description": "A NodeJS-based SDK for delivering secure applications over a Ziti Network",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.13.1",
|
|
5
5
|
"main": "./lib/ziti",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"build": "npm run build:init; npm run build:c-sdk; npm install --build-from-source --clang=1",
|
package/src/Ziti_https_request.c
CHANGED
|
@@ -17,7 +17,6 @@ limitations under the License.
|
|
|
17
17
|
#include "ziti-nodejs.h"
|
|
18
18
|
#include <ziti/ziti_src.h>
|
|
19
19
|
|
|
20
|
-
static const unsigned int U1 = 1;
|
|
21
20
|
|
|
22
21
|
/**
|
|
23
22
|
* Number of hosts we can have client pools for
|
|
@@ -30,6 +29,7 @@ enum { listMapCapacity = 50 };
|
|
|
30
29
|
enum { perKeyListMapCapacity = 25 };
|
|
31
30
|
|
|
32
31
|
struct ListMap* HttpsClientListMap;
|
|
32
|
+
struct ListMap* ServiceToHostnameListMap = NULL;
|
|
33
33
|
|
|
34
34
|
struct key_value {
|
|
35
35
|
char* key;
|
|
@@ -42,6 +42,11 @@ struct ListMap {
|
|
|
42
42
|
uv_sem_t sem;
|
|
43
43
|
};
|
|
44
44
|
|
|
45
|
+
struct hostname_port {
|
|
46
|
+
char* hostname;
|
|
47
|
+
int port;
|
|
48
|
+
};
|
|
49
|
+
|
|
45
50
|
struct ListMap* newListMap() {
|
|
46
51
|
struct ListMap* listMap = calloc(1, sizeof *listMap);
|
|
47
52
|
return listMap;
|
|
@@ -166,7 +171,16 @@ static void allocate_client(uv_work_t* req) {
|
|
|
166
171
|
|
|
167
172
|
HttpsClient* httpsClient = calloc(1, sizeof *httpsClient);
|
|
168
173
|
httpsClient->scheme_host_port = strdup(addon_data->scheme_host_port);
|
|
169
|
-
|
|
174
|
+
|
|
175
|
+
if (addon_data->haveURL) {
|
|
176
|
+
ZITI_NODEJS_LOG(DEBUG, "URL specified, so pasing NULL to ziti_src_init");
|
|
177
|
+
ziti_src_init(thread_loop, &(httpsClient->ziti_src), addon_data->service, ztx );
|
|
178
|
+
} else {
|
|
179
|
+
ZITI_NODEJS_LOG(DEBUG, "addon_data->service is: %s", addon_data->service);
|
|
180
|
+
ziti_src_init(thread_loop, &(httpsClient->ziti_src), addon_data->service, ztx );
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
ZITI_NODEJS_LOG(DEBUG, "addon_data->scheme_host_port is: %s", addon_data->scheme_host_port);
|
|
170
184
|
um_http_init_with_src(thread_loop, &(httpsClient->client), addon_data->scheme_host_port, (um_src_t *)&(httpsClient->ziti_src) );
|
|
171
185
|
|
|
172
186
|
listMapInsert(clientListMap, addon_data->scheme_host_port, (void*)httpsClient);
|
|
@@ -200,6 +214,61 @@ static void allocate_client(uv_work_t* req) {
|
|
|
200
214
|
}
|
|
201
215
|
|
|
202
216
|
|
|
217
|
+
struct hostname_port* getHostnamePortForService(char* key) {
|
|
218
|
+
|
|
219
|
+
ZITI_NODEJS_LOG(DEBUG, "getHostnamePortForService() entered, key: %s", key);
|
|
220
|
+
|
|
221
|
+
struct hostname_port* value = NULL;
|
|
222
|
+
|
|
223
|
+
if (NULL != ServiceToHostnameListMap) {
|
|
224
|
+
|
|
225
|
+
for (size_t i = 0 ; i < ServiceToHostnameListMap->count && value == NULL ; ++i) {
|
|
226
|
+
if (strcmp(ServiceToHostnameListMap->kvPairs[i].key, key) == 0) {
|
|
227
|
+
value = ServiceToHostnameListMap->kvPairs[i].value;
|
|
228
|
+
ZITI_NODEJS_LOG(DEBUG, "getHostnamePortForService() found value->hostname is: [%s], port is: [%d]", value->hostname, value->port);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
ZITI_NODEJS_LOG(DEBUG, "getHostnamePortForService() returning value '%p'", value);
|
|
234
|
+
|
|
235
|
+
return value;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
*
|
|
241
|
+
*/
|
|
242
|
+
void track_service_to_hostname(char* service_name, char* hostname, int port) {
|
|
243
|
+
|
|
244
|
+
ZITI_NODEJS_LOG(DEBUG, "track_service_to_hostname() entered, service_name: %s hostname: %s port: %d", service_name, hostname, port);
|
|
245
|
+
|
|
246
|
+
if (NULL == ServiceToHostnameListMap) {
|
|
247
|
+
ServiceToHostnameListMap = newListMap();
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
struct hostname_port* value = getHostnamePortForService(service_name);
|
|
251
|
+
|
|
252
|
+
if (NULL == value) {
|
|
253
|
+
|
|
254
|
+
value = calloc(1, sizeof(*value));
|
|
255
|
+
value->hostname = strdup(hostname);
|
|
256
|
+
value->port = port;
|
|
257
|
+
|
|
258
|
+
listMapInsert(ServiceToHostnameListMap, service_name, (void*)value);
|
|
259
|
+
|
|
260
|
+
ZITI_NODEJS_LOG(DEBUG, "track_service_to_hostname() inserting service_name: %s hostname: %s port: %d", service_name, hostname, port);
|
|
261
|
+
|
|
262
|
+
} else {
|
|
263
|
+
|
|
264
|
+
value->hostname = strdup(hostname);
|
|
265
|
+
value->port = port;
|
|
266
|
+
|
|
267
|
+
ZITI_NODEJS_LOG(DEBUG, "track_service_to_hostname() updating service_name: %s hostname: %s port: %d", service_name, hostname, port);
|
|
268
|
+
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
203
272
|
|
|
204
273
|
/**
|
|
205
274
|
* This function is responsible for calling the JavaScript on_resp_body callback function
|
|
@@ -657,12 +726,13 @@ void on_client(uv_work_t* req, int status) {
|
|
|
657
726
|
/**
|
|
658
727
|
* Initiate an HTTPS request
|
|
659
728
|
*
|
|
660
|
-
* @param {string} [0]
|
|
729
|
+
* @param {string} [0] serviceName | URL
|
|
661
730
|
* @param {string} [1] method
|
|
662
|
-
* @param {string
|
|
663
|
-
* @param {
|
|
664
|
-
* @param {func} [4] JS
|
|
665
|
-
* @param {func} [5] JS
|
|
731
|
+
* @param {string} [2] path
|
|
732
|
+
* @param {string[]} [3] headers; Array of strings of the form "name:value"
|
|
733
|
+
* @param {func} [4] JS on_req callback; This is invoked from 'on_client' function above
|
|
734
|
+
* @param {func} [5] JS on_resp callback; This is invoked from 'on_resp' function above
|
|
735
|
+
* @param {func} [6] JS on_resp_data callback; This is invoked from 'on_resp_data' function above
|
|
666
736
|
*
|
|
667
737
|
* @returns {um_http_req_t} req This allows the JS to subsequently write the Body to the request (see _Ziti_http_request_data)
|
|
668
738
|
|
|
@@ -672,7 +742,6 @@ napi_value _Ziti_http_request(napi_env env, const napi_callback_info info) {
|
|
|
672
742
|
napi_status status;
|
|
673
743
|
size_t result;
|
|
674
744
|
napi_value jsRetval;
|
|
675
|
-
char* query = "";
|
|
676
745
|
int rc;
|
|
677
746
|
|
|
678
747
|
ZITI_NODEJS_LOG(DEBUG, "entered");
|
|
@@ -681,14 +750,15 @@ napi_value _Ziti_http_request(napi_env env, const napi_callback_info info) {
|
|
|
681
750
|
HttpsClientListMap = newListMap();
|
|
682
751
|
}
|
|
683
752
|
|
|
684
|
-
size_t argc =
|
|
685
|
-
napi_value args[
|
|
753
|
+
size_t argc = 7;
|
|
754
|
+
napi_value args[7];
|
|
686
755
|
status = napi_get_cb_info(env, info, &argc, args, NULL, NULL);
|
|
687
756
|
if (status != napi_ok) {
|
|
688
757
|
napi_throw_error(env, NULL, "Failed to parse arguments");
|
|
758
|
+
return NULL;
|
|
689
759
|
}
|
|
690
760
|
|
|
691
|
-
if (argc <
|
|
761
|
+
if (argc < 7) {
|
|
692
762
|
napi_throw_error(env, "EINVAL", "Too few arguments");
|
|
693
763
|
return NULL;
|
|
694
764
|
}
|
|
@@ -697,87 +767,104 @@ napi_value _Ziti_http_request(napi_env env, const napi_callback_info info) {
|
|
|
697
767
|
ZITI_NODEJS_LOG(DEBUG, "allocated addon_data : %p", addon_data);
|
|
698
768
|
addon_data->env = env;
|
|
699
769
|
|
|
700
|
-
// Obtain
|
|
701
|
-
size_t
|
|
702
|
-
status = napi_get_value_string_utf8(env, args[0], NULL, 0, &
|
|
770
|
+
// Obtain serviceName length
|
|
771
|
+
size_t serviceName_len;
|
|
772
|
+
status = napi_get_value_string_utf8(env, args[0], NULL, 0, &serviceName_len);
|
|
703
773
|
if (status != napi_ok) {
|
|
704
|
-
napi_throw_error(env, "EINVAL", "
|
|
774
|
+
napi_throw_error(env, "EINVAL", "serviceName is not a string");
|
|
775
|
+
return NULL;
|
|
705
776
|
}
|
|
706
777
|
|
|
707
|
-
// Obtain
|
|
708
|
-
char*
|
|
709
|
-
status = napi_get_value_string_utf8(env, args[0],
|
|
778
|
+
// Obtain serviceName
|
|
779
|
+
char* serviceName = calloc(1, serviceName_len+2);
|
|
780
|
+
status = napi_get_value_string_utf8(env, args[0], serviceName, serviceName_len+1, &result);
|
|
710
781
|
if (status != napi_ok) {
|
|
711
|
-
napi_throw_error(env, "EINVAL", "Failed to obtain
|
|
782
|
+
napi_throw_error(env, "EINVAL", "Failed to obtain serviceName");
|
|
783
|
+
return NULL;
|
|
712
784
|
}
|
|
713
785
|
|
|
714
|
-
|
|
715
|
-
|
|
786
|
+
bool haveURL = false;
|
|
716
787
|
struct http_parser_url url_parse = {0};
|
|
717
|
-
rc = http_parser_parse_url(
|
|
718
|
-
if (rc
|
|
719
|
-
|
|
788
|
+
rc = http_parser_parse_url(serviceName, strlen(serviceName), false, &url_parse);
|
|
789
|
+
if (rc == 0) {
|
|
790
|
+
haveURL = true;
|
|
791
|
+
ZITI_NODEJS_LOG(DEBUG, "serviceName IS a URL");
|
|
792
|
+
} else {
|
|
793
|
+
ZITI_NODEJS_LOG(DEBUG, "serviceName is NOT a URL");
|
|
720
794
|
}
|
|
721
795
|
|
|
722
|
-
|
|
723
|
-
addon_data->service = strndup(url + url_parse.field_data[UF_HOST].off, url_parse.field_data[UF_HOST].len);
|
|
724
|
-
}
|
|
725
|
-
else {
|
|
726
|
-
ZITI_NODEJS_LOG(ERROR, "invalid URL: no host");
|
|
727
|
-
napi_throw_error(env, "EINVAL", "invalid URL: no host");
|
|
728
|
-
}
|
|
796
|
+
struct hostname_port* hostname_port = NULL;
|
|
729
797
|
|
|
730
|
-
|
|
798
|
+
if (haveURL) {
|
|
731
799
|
|
|
732
|
-
|
|
733
|
-
addon_data->path = strndup(url + url_parse.field_data[UF_PATH].off, url_parse.field_data[UF_PATH].len);
|
|
734
|
-
}
|
|
735
|
-
else {
|
|
736
|
-
ZITI_NODEJS_LOG(ERROR, "invalid URL: no path");
|
|
737
|
-
napi_throw_error(env, "EINVAL", "invalid URL: no path");
|
|
738
|
-
}
|
|
800
|
+
addon_data->scheme_host_port = strdup(serviceName);
|
|
739
801
|
|
|
740
|
-
|
|
802
|
+
} else {
|
|
741
803
|
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
804
|
+
hostname_port = getHostnamePortForService(serviceName);
|
|
805
|
+
if (NULL == hostname_port) {
|
|
806
|
+
napi_throw_error(env, "EINVAL", "Unknown serviceName");
|
|
807
|
+
return NULL;
|
|
808
|
+
}
|
|
809
|
+
addon_data->service = strdup(serviceName);
|
|
746
810
|
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
ZITI_NODEJS_LOG(DEBUG, "expanded_path: [%s]", expanded_path);
|
|
751
|
-
free(addon_data->path);
|
|
752
|
-
addon_data->path = expanded_path;
|
|
753
|
-
}
|
|
754
|
-
else {
|
|
755
|
-
ZITI_NODEJS_LOG(DEBUG, "URL: no query found");
|
|
756
|
-
}
|
|
757
|
-
ZITI_NODEJS_LOG(DEBUG, "adjusted path: [%s]", addon_data->path);
|
|
811
|
+
ZITI_NODEJS_LOG(DEBUG, "addon_data->service: %s", addon_data->service);
|
|
812
|
+
|
|
813
|
+
addon_data->scheme_host_port = calloc(1, 100);
|
|
758
814
|
|
|
759
|
-
|
|
815
|
+
if (hostname_port->port == 443) {
|
|
816
|
+
strcat(addon_data->scheme_host_port, "https://");
|
|
817
|
+
strcat(addon_data->scheme_host_port, hostname_port->hostname);
|
|
818
|
+
} else {
|
|
819
|
+
strcat(addon_data->scheme_host_port, "http://");
|
|
820
|
+
strcat(addon_data->scheme_host_port, hostname_port->hostname);
|
|
821
|
+
strcat(addon_data->scheme_host_port, ":");
|
|
822
|
+
char sport[8];
|
|
823
|
+
sprintf(sport, "%d", hostname_port->port);
|
|
824
|
+
strcat(addon_data->scheme_host_port, sport);
|
|
825
|
+
}
|
|
826
|
+
}
|
|
760
827
|
|
|
761
|
-
|
|
828
|
+
addon_data->haveURL = haveURL;
|
|
762
829
|
|
|
830
|
+
ZITI_NODEJS_LOG(DEBUG, "scheme_host_port: %s, haveURL: %d", addon_data->scheme_host_port, haveURL);
|
|
763
831
|
|
|
764
832
|
// Obtain method length
|
|
765
833
|
size_t method_len;
|
|
766
834
|
status = napi_get_value_string_utf8(env, args[1], NULL, 0, &method_len);
|
|
767
835
|
if (status != napi_ok) {
|
|
768
836
|
napi_throw_error(env, "EINVAL", "method is not a string");
|
|
837
|
+
return NULL;
|
|
769
838
|
}
|
|
770
839
|
// Obtain method
|
|
771
840
|
addon_data->method = calloc(1, method_len+2);
|
|
772
841
|
status = napi_get_value_string_utf8(env, args[1], addon_data->method, method_len+1, &result);
|
|
773
842
|
if (status != napi_ok) {
|
|
774
843
|
napi_throw_error(env, "EINVAL", "Failed to obtain method");
|
|
844
|
+
return NULL;
|
|
775
845
|
}
|
|
776
846
|
|
|
777
847
|
ZITI_NODEJS_LOG(DEBUG, "method: %s", addon_data->method);
|
|
778
848
|
|
|
849
|
+
// Obtain path length
|
|
850
|
+
size_t path_len;
|
|
851
|
+
status = napi_get_value_string_utf8(env, args[2], NULL, 0, &path_len);
|
|
852
|
+
if (status != napi_ok) {
|
|
853
|
+
napi_throw_error(env, "EINVAL", "path is not a string");
|
|
854
|
+
return NULL;
|
|
855
|
+
}
|
|
856
|
+
// Obtain path
|
|
857
|
+
addon_data->path = calloc(1, path_len+2);
|
|
858
|
+
status = napi_get_value_string_utf8(env, args[2], addon_data->path, path_len+1, &result);
|
|
859
|
+
if (status != napi_ok) {
|
|
860
|
+
napi_throw_error(env, "EINVAL", "Failed to obtain path");
|
|
861
|
+
return NULL;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
ZITI_NODEJS_LOG(DEBUG, "path: %s", addon_data->path);
|
|
865
|
+
|
|
779
866
|
// Obtain ptr to JS on_req callback function
|
|
780
|
-
napi_value js_cb = args[
|
|
867
|
+
napi_value js_cb = args[4];
|
|
781
868
|
napi_value work_name;
|
|
782
869
|
|
|
783
870
|
|
|
@@ -789,6 +876,7 @@ napi_value _Ziti_http_request(napi_env env, const napi_callback_info info) {
|
|
|
789
876
|
rc = napi_create_string_utf8(env, "on_req", NAPI_AUTO_LENGTH, &work_name);
|
|
790
877
|
if (rc != napi_ok) {
|
|
791
878
|
napi_throw_error(env, "EINVAL", "Failed to create string");
|
|
879
|
+
return NULL;
|
|
792
880
|
}
|
|
793
881
|
|
|
794
882
|
// Convert the callback retrieved from JavaScript into a thread-safe function (tsfn)
|
|
@@ -808,16 +896,18 @@ napi_value _Ziti_http_request(napi_env env, const napi_callback_info info) {
|
|
|
808
896
|
);
|
|
809
897
|
if (rc != napi_ok) {
|
|
810
898
|
napi_throw_error(env, "EINVAL", "Failed to create threadsafe_function");
|
|
899
|
+
return NULL;
|
|
811
900
|
}
|
|
812
901
|
ZITI_NODEJS_LOG(DEBUG, "napi_create_threadsafe_function addon_data->tsfn_on_req() : %p", addon_data->tsfn_on_req);
|
|
813
902
|
|
|
814
903
|
// Obtain ptr to JS on_resp callback function
|
|
815
|
-
napi_value js_cb2 = args[
|
|
904
|
+
napi_value js_cb2 = args[5];
|
|
816
905
|
|
|
817
906
|
// Create a string to describe this asynchronous operation.
|
|
818
907
|
rc = napi_create_string_utf8(env, "on_resp", NAPI_AUTO_LENGTH, &work_name);
|
|
819
908
|
if (rc != napi_ok) {
|
|
820
909
|
napi_throw_error(env, "EINVAL", "Failed to create string");
|
|
910
|
+
return NULL;
|
|
821
911
|
}
|
|
822
912
|
|
|
823
913
|
// Convert the callback retrieved from JavaScript into a thread-safe function (tsfn)
|
|
@@ -837,17 +927,19 @@ napi_value _Ziti_http_request(napi_env env, const napi_callback_info info) {
|
|
|
837
927
|
);
|
|
838
928
|
if (rc != napi_ok) {
|
|
839
929
|
napi_throw_error(env, "EINVAL", "Failed to create threadsafe_function");
|
|
930
|
+
return NULL;
|
|
840
931
|
}
|
|
841
932
|
ZITI_NODEJS_LOG(DEBUG, "napi_create_threadsafe_function addon_data->tsfn_on_resp() : %p", addon_data->tsfn_on_resp);
|
|
842
933
|
|
|
843
934
|
|
|
844
935
|
// Obtain ptr to JS on_resp_data callback function
|
|
845
|
-
napi_value js_cb3 = args[
|
|
936
|
+
napi_value js_cb3 = args[6];
|
|
846
937
|
|
|
847
938
|
// Create a string to describe this asynchronous operation.
|
|
848
939
|
rc = napi_create_string_utf8(env, "on_resp_data", NAPI_AUTO_LENGTH, &work_name);
|
|
849
940
|
if (rc != napi_ok) {
|
|
850
941
|
napi_throw_error(env, "EINVAL", "Failed to create string");
|
|
942
|
+
return NULL;
|
|
851
943
|
}
|
|
852
944
|
|
|
853
945
|
// Convert the callback retrieved from JavaScript into a thread-safe function (tsfn)
|
|
@@ -867,6 +959,7 @@ napi_value _Ziti_http_request(napi_env env, const napi_callback_info info) {
|
|
|
867
959
|
);
|
|
868
960
|
if (rc != napi_ok) {
|
|
869
961
|
napi_throw_error(env, "EINVAL", "Failed to create threadsafe_function");
|
|
962
|
+
return NULL;
|
|
870
963
|
}
|
|
871
964
|
ZITI_NODEJS_LOG(DEBUG, "napi_create_threadsafe_function addon_data->tsfn_on_resp_body() : %p", addon_data->tsfn_on_resp_body);
|
|
872
965
|
|
|
@@ -874,17 +967,19 @@ napi_value _Ziti_http_request(napi_env env, const napi_callback_info info) {
|
|
|
874
967
|
// Capture headers
|
|
875
968
|
//
|
|
876
969
|
uint32_t i;
|
|
877
|
-
status = napi_get_array_length(env, args[
|
|
970
|
+
status = napi_get_array_length(env, args[3], &addon_data->headers_array_length);
|
|
878
971
|
if (status != napi_ok) {
|
|
879
972
|
napi_throw_error(env, "EINVAL", "Failed to obtain headers array");
|
|
973
|
+
return NULL;
|
|
880
974
|
}
|
|
881
975
|
ZITI_NODEJS_LOG(DEBUG, "headers_array_length: %d", addon_data->headers_array_length);
|
|
882
976
|
for (i = 0; i < addon_data->headers_array_length; i++) {
|
|
883
977
|
|
|
884
978
|
napi_value headers_array_element;
|
|
885
|
-
status = napi_get_element(env, args[
|
|
979
|
+
status = napi_get_element(env, args[3], i, &headers_array_element);
|
|
886
980
|
if (status != napi_ok) {
|
|
887
981
|
napi_throw_error(env, "EINVAL", "Failed to obtain headers element");
|
|
982
|
+
return NULL;
|
|
888
983
|
}
|
|
889
984
|
|
|
890
985
|
// Obtain element length
|
|
@@ -892,6 +987,7 @@ napi_value _Ziti_http_request(napi_env env, const napi_callback_info info) {
|
|
|
892
987
|
status = napi_get_value_string_utf8(env, headers_array_element, NULL, 0, &element_len);
|
|
893
988
|
if (status != napi_ok) {
|
|
894
989
|
napi_throw_error(env, "EINVAL", "header arry element is not a string");
|
|
990
|
+
return NULL;
|
|
895
991
|
}
|
|
896
992
|
ZITI_NODEJS_LOG(DEBUG, "element_len: %zd", element_len);
|
|
897
993
|
|
|
@@ -906,16 +1002,19 @@ napi_value _Ziti_http_request(napi_env env, const napi_callback_info info) {
|
|
|
906
1002
|
status = napi_get_value_string_utf8(env, headers_array_element, header_element, element_len+1, &result);
|
|
907
1003
|
if (status != napi_ok) {
|
|
908
1004
|
napi_throw_error(env, "EINVAL", "Failed to obtain element");
|
|
1005
|
+
return NULL;
|
|
909
1006
|
}
|
|
910
1007
|
ZITI_NODEJS_LOG(DEBUG, "header_element: %s", header_element);
|
|
911
1008
|
|
|
912
1009
|
char * header_name = strtok(header_element, ":");
|
|
913
1010
|
if (NULL == header_name) {
|
|
914
1011
|
napi_throw_error(env, "EINVAL", "Failed to split header element");
|
|
1012
|
+
return NULL;
|
|
915
1013
|
}
|
|
916
1014
|
char * header_value = strtok(NULL, ":");
|
|
917
1015
|
if (strlen(header_value) < 1) {
|
|
918
1016
|
napi_throw_error(env, "EINVAL", "Failed to split header element");
|
|
1017
|
+
return NULL;
|
|
919
1018
|
}
|
|
920
1019
|
|
|
921
1020
|
addon_data->header_name[i] = strdup(header_name);
|
|
@@ -938,6 +1037,7 @@ napi_value _Ziti_http_request(napi_env env, const napi_callback_info info) {
|
|
|
938
1037
|
status = napi_create_int64(env, (int64_t)0, &jsRetval);
|
|
939
1038
|
if (status != napi_ok) {
|
|
940
1039
|
napi_throw_error(env, NULL, "Unable to create return value");
|
|
1040
|
+
return NULL;
|
|
941
1041
|
}
|
|
942
1042
|
return jsRetval;
|
|
943
1043
|
}
|
package/src/ziti-nodejs.h
CHANGED
|
@@ -177,6 +177,7 @@ struct HttpsAddonData {
|
|
|
177
177
|
HttpsRespItem* item;
|
|
178
178
|
HttpsReq* httpsReq;
|
|
179
179
|
uv_work_t uv_req;
|
|
180
|
+
bool haveURL;
|
|
180
181
|
char* service;
|
|
181
182
|
char* scheme_host_port;
|
|
182
183
|
char* method;
|
|
@@ -218,6 +219,7 @@ extern void expose_ziti_websocket_write(napi_env env, napi_value exports);
|
|
|
218
219
|
//
|
|
219
220
|
extern int um_websocket_init_with_src (uv_loop_t *loop, um_websocket_t *ws, um_src_t *src);
|
|
220
221
|
|
|
222
|
+
extern void track_service_to_hostname(char* service_name, char* hostname, int port);
|
|
221
223
|
|
|
222
224
|
#ifdef __cplusplus
|
|
223
225
|
}
|
package/src/ziti_init.c
CHANGED
|
@@ -153,6 +153,77 @@ static void on_ziti_event(ziti_context _ztx, const ziti_event_t *event) {
|
|
|
153
153
|
// service_check_cb(ztx, *sp, ZITI_OK, app_ctx);
|
|
154
154
|
}
|
|
155
155
|
}
|
|
156
|
+
|
|
157
|
+
if (event->event.service.changed != NULL) {
|
|
158
|
+
for (ziti_service **sp = event->event.service.changed; *sp != NULL; sp++) {
|
|
159
|
+
// service_check_cb(ztx, *sp, ZITI_OK, app_ctx);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
//
|
|
164
|
+
for (int i = 0; event->event.service.added && event->event.service.added[i] != NULL; i++) {
|
|
165
|
+
|
|
166
|
+
ziti_service *s = event->event.service.added[i];
|
|
167
|
+
ziti_intercept_cfg_v1 *intercept = alloc_ziti_intercept_cfg_v1();
|
|
168
|
+
ziti_client_cfg_v1 clt_cfg = {
|
|
169
|
+
.hostname = {0},
|
|
170
|
+
.port = 0
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
if (ziti_service_get_config(s, ZITI_INTERCEPT_CFG_V1, intercept, (int (*)(void *, const char *, size_t))parse_ziti_intercept_cfg_v1) == ZITI_OK) {
|
|
174
|
+
|
|
175
|
+
const ziti_address *range_addr;
|
|
176
|
+
MODEL_LIST_FOREACH(range_addr, intercept->addresses) {
|
|
177
|
+
ziti_port_range *p;
|
|
178
|
+
MODEL_LIST_FOREACH(p, intercept->port_ranges) {
|
|
179
|
+
int lowport = p->low;
|
|
180
|
+
while (lowport <= p->high) {
|
|
181
|
+
track_service_to_hostname(s->name, (char *)range_addr->addr.hostname, lowport);
|
|
182
|
+
lowport++;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
} else if (ziti_service_get_config(s, ZITI_CLIENT_CFG_V1, &clt_cfg, (int (*)(void *, const char *, unsigned long))parse_ziti_client_cfg_v1) == ZITI_OK) {
|
|
188
|
+
track_service_to_hostname(s->name, clt_cfg.hostname.addr.hostname, clt_cfg.port);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
free_ziti_intercept_cfg_v1(intercept);
|
|
192
|
+
free(intercept);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
for (int i = 0; event->event.service.changed && event->event.service.changed[i] != NULL; i++) {
|
|
196
|
+
|
|
197
|
+
ziti_service *s = event->event.service.changed[i];
|
|
198
|
+
ziti_intercept_cfg_v1 *intercept = alloc_ziti_intercept_cfg_v1();
|
|
199
|
+
ziti_client_cfg_v1 clt_cfg = {
|
|
200
|
+
.hostname = {0},
|
|
201
|
+
.port = 0
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
if (ziti_service_get_config(s, ZITI_INTERCEPT_CFG_V1, intercept, (int (*)(void *, const char *, size_t))parse_ziti_intercept_cfg_v1) == ZITI_OK) {
|
|
205
|
+
|
|
206
|
+
const ziti_address *range_addr;
|
|
207
|
+
MODEL_LIST_FOREACH(range_addr, intercept->addresses) {
|
|
208
|
+
ziti_port_range *p;
|
|
209
|
+
MODEL_LIST_FOREACH(p, intercept->port_ranges) {
|
|
210
|
+
int lowport = p->low;
|
|
211
|
+
while (lowport <= p->high) {
|
|
212
|
+
track_service_to_hostname(s->name, (char *)range_addr->addr.hostname, lowport);
|
|
213
|
+
lowport++;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
} else if (ziti_service_get_config(s, ZITI_CLIENT_CFG_V1, &clt_cfg, (int (*)(void *, const char *, unsigned long))parse_ziti_client_cfg_v1) == ZITI_OK) {
|
|
219
|
+
track_service_to_hostname(s->name, clt_cfg.hostname.addr.hostname, clt_cfg.port);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
free_ziti_intercept_cfg_v1(intercept);
|
|
223
|
+
free(intercept);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
|
|
156
227
|
break;
|
|
157
228
|
|
|
158
229
|
case ZitiRouterEvent:
|