mirror of
https://github.com/ading2210/libcurl.js.git
synced 2025-05-13 14:30:02 -04:00
add support for socks5, socks4, and http proxies
This commit is contained in:
parent
9f033fc848
commit
4d64b27a82
9 changed files with 58 additions and 5 deletions
|
@ -1,5 +1,8 @@
|
||||||
# Libcurl.js Changelog:
|
# Libcurl.js Changelog:
|
||||||
|
|
||||||
|
## v0.6.11 (7/18/24):
|
||||||
|
- Add support for SOCKS5, SOCKS4, and HTTP proxies
|
||||||
|
|
||||||
## v0.6.10 (7/11/24):
|
## v0.6.10 (7/11/24):
|
||||||
- Fix a problem where the websocket URL wouldn't be set properly in some cases
|
- Fix a problem where the websocket URL wouldn't be set properly in some cases
|
||||||
|
|
||||||
|
|
|
@ -122,6 +122,8 @@ Sending cookies is supported, but they will not be automatically sent unless you
|
||||||
|
|
||||||
The response may contain multiple HTTP headers with the same name, which the `Headers` object isn't able to properly represent. If this matters to you, use `response.raw_headers`, which is an array of key value pairs, instead of `response.headers`. There is support for streaming the response body using a `ReadableStream`, as well as canceling requests using an `AbortSignal`. All requests made using this method share the same connection pool, which has a limit of 50 active TCP connections.
|
The response may contain multiple HTTP headers with the same name, which the `Headers` object isn't able to properly represent. If this matters to you, use `response.raw_headers`, which is an array of key value pairs, instead of `response.headers`. There is support for streaming the response body using a `ReadableStream`, as well as canceling requests using an `AbortSignal`. All requests made using this method share the same connection pool, which has a limit of 50 active TCP connections.
|
||||||
|
|
||||||
|
The `proxy` option may be used to specify the URL of a `socks5h`, `socks4a`, or `http` proxy server. For example `proxy: "socks5h://127.0.0.0:1080"` will set the proxy server for just the current request.
|
||||||
|
|
||||||
### Creating New HTTP Sessions:
|
### Creating New HTTP Sessions:
|
||||||
To create new sessions for HTTP requests, use the `libcurl.HTTPSession` class. The constructor for this class takes the following arguments:
|
To create new sessions for HTTP requests, use the `libcurl.HTTPSession` class. The constructor for this class takes the following arguments:
|
||||||
- `options` - An optional object with various settings.
|
- `options` - An optional object with various settings.
|
||||||
|
@ -129,6 +131,7 @@ To create new sessions for HTTP requests, use the `libcurl.HTTPSession` class. T
|
||||||
The valid HTTP session settings are:
|
The valid HTTP session settings are:
|
||||||
- `enable_cookies` - A boolean which indicate whether or not cookies should be persisted within the session.
|
- `enable_cookies` - A boolean which indicate whether or not cookies should be persisted within the session.
|
||||||
- `cookie_jar` - A string containing the data in the cookie jar file. This should have been exported from a previous session. For more information on the format for this file, see the [curl documentation](https://curl.se/docs/http-cookies.html).
|
- `cookie_jar` - A string containing the data in the cookie jar file. This should have been exported from a previous session. For more information on the format for this file, see the [curl documentation](https://curl.se/docs/http-cookies.html).
|
||||||
|
- `proxy` - A URL for a `socks5h`, `socks4a`, or `http` proxy server.
|
||||||
|
|
||||||
Each HTTP session has the following methods available:
|
Each HTTP session has the following methods available:
|
||||||
- `fetch` - Identical to the `libcurl.fetch` function but only creates connections in this session.
|
- `fetch` - Identical to the `libcurl.fetch` function but only creates connections in this session.
|
||||||
|
@ -156,6 +159,7 @@ To use WebSockets, create a `libcurl.CurlWebSocket` object, which takes the foll
|
||||||
The valid WebSocket options are:
|
The valid WebSocket options are:
|
||||||
- `headers` - HTTP request headers for the websocket handshake.
|
- `headers` - HTTP request headers for the websocket handshake.
|
||||||
- `verbose` - A boolean flag that toggles the verbose libcurl output. This verbose output will be passed to the function defined in `libcurl.stderr`, which is `console.warn` by default.
|
- `verbose` - A boolean flag that toggles the verbose libcurl output. This verbose output will be passed to the function defined in `libcurl.stderr`, which is `console.warn` by default.
|
||||||
|
- `proxy` - A URL for a `socks5h`, `socks4a`, or `http` proxy server.
|
||||||
|
|
||||||
The following callbacks are available:
|
The following callbacks are available:
|
||||||
- `CurlWebSocket.onopen` - Called when the websocket is successfully connected.
|
- `CurlWebSocket.onopen` - Called when the websocket is successfully connected.
|
||||||
|
@ -198,6 +202,7 @@ Raw TLS sockets can be created with the `libcurl.TLSSocket` class, which takes t
|
||||||
|
|
||||||
The valid TLS socket options are:
|
The valid TLS socket options are:
|
||||||
- `verbose` - A boolean flag that toggles the verbose libcurl output.
|
- `verbose` - A boolean flag that toggles the verbose libcurl output.
|
||||||
|
- `proxy` - A URL for a `socks5h`, `socks4a`, or `http` proxy server.
|
||||||
|
|
||||||
The callbacks work similarly to the `libcurl.CurlWebSocket` object, with the main difference being that the `onmessage` callback always returns a `Uint8Array`.
|
The callbacks work similarly to the `libcurl.CurlWebSocket` object, with the main difference being that the `onmessage` callback always returns a `Uint8Array`.
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ session_cleanup
|
||||||
|
|
||||||
request_cleanup
|
request_cleanup
|
||||||
create_request
|
create_request
|
||||||
|
request_set_proxy
|
||||||
get_version
|
get_version
|
||||||
get_cacert
|
get_cacert
|
||||||
get_error_str
|
get_error_str
|
||||||
|
|
|
@ -88,6 +88,9 @@ class HTTPSession extends CurlSession {
|
||||||
if (this.cookie_filename && params.credentials !== "omit") {
|
if (this.cookie_filename && params.credentials !== "omit") {
|
||||||
c_func(_http_set_cookie_jar, [http_handle, this.cookie_filename]);
|
c_func(_http_set_cookie_jar, [http_handle, this.cookie_filename]);
|
||||||
}
|
}
|
||||||
|
if (params.proxy) {
|
||||||
|
c_func_str(_request_set_proxy, [http_handle, params.proxy]);
|
||||||
|
}
|
||||||
|
|
||||||
this.start_request(http_handle);
|
this.start_request(http_handle);
|
||||||
});
|
});
|
||||||
|
@ -110,6 +113,12 @@ class HTTPSession extends CurlSession {
|
||||||
else {
|
else {
|
||||||
url = "" + url;
|
url = "" + url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.options && this.options.proxy) {
|
||||||
|
params.proxy = this.options.proxy;
|
||||||
|
}
|
||||||
|
check_proxy(params.proxy);
|
||||||
|
|
||||||
let body = await this.constructor.create_options(params);
|
let body = await this.constructor.create_options(params);
|
||||||
return await this.request_async(url, params, body);
|
return await this.request_async(url, params, body);
|
||||||
}
|
}
|
||||||
|
@ -152,6 +161,7 @@ class HTTPSession extends CurlSession {
|
||||||
if (params.body instanceof ReadableStream) {
|
if (params.body instanceof ReadableStream) {
|
||||||
params.duplex = "half";
|
params.duplex = "half";
|
||||||
}
|
}
|
||||||
|
|
||||||
let request_obj = new Request("http://127.0.0.1/", params);
|
let request_obj = new Request("http://127.0.0.1/", params);
|
||||||
let array_buffer = await request_obj.arrayBuffer();
|
let array_buffer = await request_obj.arrayBuffer();
|
||||||
if (array_buffer.byteLength > 0) {
|
if (array_buffer.byteLength > 0) {
|
||||||
|
|
|
@ -17,8 +17,15 @@ class TLSSocket extends CurlSession {
|
||||||
this.connected = false;
|
this.connected = false;
|
||||||
this.recv_loop = null;
|
this.recv_loop = null;
|
||||||
|
|
||||||
this.set_connections(1, 0);
|
try {
|
||||||
this.connect();
|
check_proxy(this.options.proxy);
|
||||||
|
this.set_connections(1, 0);
|
||||||
|
this.connect();
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
this.cleanup(true);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
connect() {
|
connect() {
|
||||||
|
@ -40,6 +47,9 @@ class TLSSocket extends CurlSession {
|
||||||
|
|
||||||
this.http_handle = this.create_request(this.url, data_callback, finish_callback, headers_callback);
|
this.http_handle = this.create_request(this.url, data_callback, finish_callback, headers_callback);
|
||||||
_tls_socket_set_options(this.http_handle, +this.options.verbose);
|
_tls_socket_set_options(this.http_handle, +this.options.verbose);
|
||||||
|
if (this.options.proxy) {
|
||||||
|
c_func_str(_request_set_proxy, [this.http_handle, this.options.proxy]);
|
||||||
|
}
|
||||||
this.start_request(this.http_handle);
|
this.start_request(this.http_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,3 +105,13 @@ function c_func_str(target, args=[]) {
|
||||||
_free(ptr);
|
_free(ptr);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//ensure that the proxy url has a valid protocol
|
||||||
|
function check_proxy(proxy) {
|
||||||
|
if (typeof proxy === "string" || proxy instanceof String) {
|
||||||
|
let protocol = new URL(proxy).protocol;
|
||||||
|
if (!["socks5h:", "socks4a:", "http:"].includes(protocol)) {
|
||||||
|
throw new TypeError("Only socks5h, socks4a, and http proxies are supported.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,8 +19,15 @@ class CurlWebSocket extends CurlSession {
|
||||||
this.http_handle = null;
|
this.http_handle = null;
|
||||||
this.recv_buffer = [];
|
this.recv_buffer = [];
|
||||||
|
|
||||||
this.set_connections(1, 0);
|
try {
|
||||||
this.connect();
|
check_proxy(this.options.proxy);
|
||||||
|
this.set_connections(1, 0);
|
||||||
|
this.connect();
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
this.cleanup(true);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
connect() {
|
connect() {
|
||||||
|
@ -52,6 +59,9 @@ class CurlWebSocket extends CurlSession {
|
||||||
this.http_handle = this.create_request(this.url, data_callback, finish_callback, headers_callback);
|
this.http_handle = this.create_request(this.url, data_callback, finish_callback, headers_callback);
|
||||||
c_func(_http_set_options, [this.http_handle, JSON.stringify(request_options), null, 0]);
|
c_func(_http_set_options, [this.http_handle, JSON.stringify(request_options), null, 0]);
|
||||||
_websocket_set_options(this.http_handle);
|
_websocket_set_options(this.http_handle);
|
||||||
|
if (this.options.proxy) {
|
||||||
|
c_func_str(_request_set_proxy, [this.http_handle, this.options.proxy]);
|
||||||
|
}
|
||||||
this.start_request(this.http_handle);
|
this.start_request(this.http_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,10 @@ void finish_request(CURLMsg *curl_msg) {
|
||||||
(*request_info->end_callback)(request_info->request_id, error);
|
(*request_info->end_callback)(request_info->request_id, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void request_set_proxy(CURL* http_handle, const char* proxy_url) {
|
||||||
|
curl_easy_setopt(http_handle, CURLOPT_PROXY, proxy_url);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned char* get_cacert() {
|
unsigned char* get_cacert() {
|
||||||
return _cacert_pem;
|
return _cacert_pem;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "libcurl.js",
|
"name": "libcurl.js",
|
||||||
"version": "0.6.10",
|
"version": "0.6.11",
|
||||||
"description": "An experimental port of libcurl to WebAssembly for use in the browser.",
|
"description": "An experimental port of libcurl to WebAssembly for use in the browser.",
|
||||||
"main": "libcurl.mjs",
|
"main": "libcurl.mjs",
|
||||||
"exports": {
|
"exports": {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue