mirror of
https://github.com/ading2210/libcurl.js.git
synced 2025-05-13 14:30:02 -04:00
not yet working coroutines
This commit is contained in:
parent
2a072ecee0
commit
e5118c9c2e
8 changed files with 102 additions and 11 deletions
|
@ -104,8 +104,8 @@ To create new sessions for HTTP requests, use the `libcurl.HTTPSession` class. T
|
||||||
- `options` - An optional object with various settings.
|
- `options` - An optional object with various settings.
|
||||||
|
|
||||||
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. NOT IMPLEMENTED YET
|
||||||
- `cookie_jar` - A blob containing the data in the cookie jar file. This should have been exported from a previous session.
|
- `cookie_jar` - A blob containing the data in the cookie jar file. This should have been exported from a previous session. NOT IMPLEMENTED YET
|
||||||
|
|
||||||
### Creating WebSocket Connections:
|
### Creating WebSocket Connections:
|
||||||
To use WebSockets, create a `libcurl.CurlWebSocket` object, which takes the following arguments:
|
To use WebSockets, create a `libcurl.CurlWebSocket` object, which takes the following arguments:
|
||||||
|
|
|
@ -27,8 +27,8 @@ EXPORTED_FUNCS="${EXPORTED_FUNCS:1}"
|
||||||
|
|
||||||
#compile options
|
#compile options
|
||||||
RUNTIME_METHODS="addFunction,removeFunction,allocate,ALLOC_NORMAL"
|
RUNTIME_METHODS="addFunction,removeFunction,allocate,ALLOC_NORMAL"
|
||||||
COMPILER_OPTIONS="-o $MODULE_FILE -lcurl -lssl -lcrypto -lcjson -lz -lbrotlidec -lbrotlicommon -lnghttp2 -I $INCLUDE_DIR -L $LIB_DIR"
|
COMPILER_OPTIONS="-o $MODULE_FILE -lcurl -lssl -lcrypto -lcjson -lz -lbrotlidec -lbrotlicommon -lnghttp2 -I $INCLUDE_DIR -L $LIB_DIR -Wl,--wrap=poll"
|
||||||
EMSCRIPTEN_OPTIONS="-lwebsocket.js -sENVIRONMENT=worker,web -sASSERTIONS=1 -sLLD_REPORT_UNDEFINED -sALLOW_TABLE_GROWTH -sALLOW_MEMORY_GROWTH -sEXPORTED_FUNCTIONS=$EXPORTED_FUNCS -sEXPORTED_RUNTIME_METHODS=$RUNTIME_METHODS"
|
EMSCRIPTEN_OPTIONS="-lwebsocket.js -sASYNCIFY -sENVIRONMENT=worker,web -sASSERTIONS=1 -sLLD_REPORT_UNDEFINED -sALLOW_TABLE_GROWTH -sALLOW_MEMORY_GROWTH -sEXPORTED_FUNCTIONS=$EXPORTED_FUNCS -sEXPORTED_RUNTIME_METHODS=$RUNTIME_METHODS"
|
||||||
|
|
||||||
#clean output dir
|
#clean output dir
|
||||||
rm -rf $OUT_DIR
|
rm -rf $OUT_DIR
|
||||||
|
|
|
@ -3,7 +3,7 @@ class FTPSession extends CurlSession {
|
||||||
if (!url.startsWith("ftp://") && !url.startsWith("ftps://")) {
|
if (!url.startsWith("ftp://") && !url.startsWith("ftps://")) {
|
||||||
throw "invalid url protocol";
|
throw "invalid url protocol";
|
||||||
}
|
}
|
||||||
super();
|
super(1);
|
||||||
|
|
||||||
this.url = url;
|
this.url = url;
|
||||||
this.options = options;
|
this.options = options;
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
class CurlSession {
|
class CurlSession {
|
||||||
constructor(options={}) {
|
constructor(need_fiber=0) {
|
||||||
check_loaded(true);
|
check_loaded(true);
|
||||||
|
|
||||||
this.options = options;
|
this.session_ptr = _session_create(need_fiber);
|
||||||
this.session_ptr = _session_create();
|
|
||||||
this.active_requests = 0;
|
this.active_requests = 0;
|
||||||
this.event_loop = null;
|
this.event_loop = null;
|
||||||
this.requests_list = [];
|
this.requests_list = [];
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <poll.h>
|
||||||
|
|
||||||
#include "curl/multi.h"
|
#include "curl/multi.h"
|
||||||
#include "curl/curl.h"
|
#include "curl/curl.h"
|
||||||
|
@ -6,15 +7,24 @@
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "request.h"
|
#include "request.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
struct SessionInfo* session_create() {
|
#define MINICORO_IMPL
|
||||||
|
#include "minicoro.h"
|
||||||
|
|
||||||
|
struct SessionInfo* running_session;
|
||||||
|
|
||||||
|
struct SessionInfo* session_create(int need_fiber) {
|
||||||
struct SessionInfo *session = malloc(sizeof(struct SessionInfo));
|
struct SessionInfo *session = malloc(sizeof(struct SessionInfo));
|
||||||
session->multi_handle = curl_multi_init();
|
session->multi_handle = curl_multi_init();
|
||||||
session->request_active = 0;
|
session->request_active = 0;
|
||||||
|
session->need_fiber = need_fiber;
|
||||||
|
session->fiber_running = 0;
|
||||||
|
session->fiber = NULL;
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
||||||
void session_perform(struct SessionInfo *session) {
|
void session_thread(struct SessionInfo *session) {
|
||||||
CURLMcode mc;
|
CURLMcode mc;
|
||||||
session->request_active = 0;
|
session->request_active = 0;
|
||||||
mc = curl_multi_perform(session->multi_handle, &session->request_active);
|
mc = curl_multi_perform(session->multi_handle, &session->request_active);
|
||||||
|
@ -25,6 +35,68 @@ void session_perform(struct SessionInfo *session) {
|
||||||
if (curl_msg && curl_msg->msg == CURLMSG_DONE) {
|
if (curl_msg && curl_msg->msg == CURLMSG_DONE) {
|
||||||
finish_request(curl_msg);
|
finish_request(curl_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//suspend the coroutine if there are no requests active
|
||||||
|
if (session->need_fiber && !session->request_active) {
|
||||||
|
mco_yield(mco_running());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void session_thread_wrapper(mco_coro* fiber) {
|
||||||
|
//infinitely loop here so we don't need to keep remaking the coroutine
|
||||||
|
while (1) {
|
||||||
|
session_thread(fiber->user_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void session_perform(struct SessionInfo *session) {
|
||||||
|
running_session = session;
|
||||||
|
if (!session->need_fiber) {
|
||||||
|
session_thread(session);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//create a new coroutine if there isn't one running already
|
||||||
|
mco_coro* fiber;
|
||||||
|
if (!session->fiber_running) {
|
||||||
|
mco_desc desc = mco_desc_init(session_thread_wrapper, 0);
|
||||||
|
desc.user_data = session;
|
||||||
|
mco_result res = mco_create(&fiber, &desc);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fiber = session->fiber;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mco_status(fiber) == MCO_SUSPENDED) {
|
||||||
|
printf("fiber suspended \n");
|
||||||
|
}
|
||||||
|
if (mco_status(fiber) == MCO_DEAD) {
|
||||||
|
printf("fiber dead \n");
|
||||||
|
}
|
||||||
|
if (mco_status(fiber) == MCO_NORMAL) {
|
||||||
|
printf("fiber normal \n");
|
||||||
|
}
|
||||||
|
|
||||||
|
//swich contexts into coroutine
|
||||||
|
session->fiber_running = 1;
|
||||||
|
mco_resume(fiber);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//wrap the poll function
|
||||||
|
//we want to switch contexts when curl is polling the socket
|
||||||
|
extern int __real_poll(struct pollfd *fds, nfds_t nfds, int timeout);
|
||||||
|
int __wrap_poll(struct pollfd *fds, nfds_t nfds, int timeout) {
|
||||||
|
int ret = __real_poll(fds, nfds, timeout);
|
||||||
|
|
||||||
|
//don't switch contexts if there is activity on the socket
|
||||||
|
if (!running_session->need_fiber || ret != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
//perform the context switch if there is nothing on the socket
|
||||||
|
mco_yield(mco_running());
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void session_set_options(struct SessionInfo *session, int connections_limit, int cache_limit) {
|
void session_set_options(struct SessionInfo *session, int connections_limit, int cache_limit) {
|
||||||
|
@ -49,4 +121,9 @@ void session_remove_request(struct SessionInfo *session, CURL* http_handle) {
|
||||||
|
|
||||||
void session_cleanup(struct SessionInfo *session) {
|
void session_cleanup(struct SessionInfo *session) {
|
||||||
curl_multi_cleanup(session->multi_handle);
|
curl_multi_cleanup(session->multi_handle);
|
||||||
|
|
||||||
|
if (session->fiber != NULL)
|
||||||
|
mco_destroy(session->fiber);
|
||||||
|
|
||||||
|
free(session);
|
||||||
}
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
#include "curl/curl.h"
|
#include "curl/curl.h"
|
||||||
|
#include "minicoro.h"
|
||||||
|
|
||||||
typedef void(*DataCallback)(char* chunk_ptr, int chunk_size);
|
typedef void(*DataCallback)(char* chunk_ptr, int chunk_size);
|
||||||
typedef void(*EndCallback)(int error);
|
typedef void(*EndCallback)(int error);
|
||||||
|
@ -24,4 +25,7 @@ struct WSResult {
|
||||||
struct SessionInfo {
|
struct SessionInfo {
|
||||||
CURLM* multi_handle;
|
CURLM* multi_handle;
|
||||||
int request_active;
|
int request_active;
|
||||||
|
int need_fiber;
|
||||||
|
int fiber_running;
|
||||||
|
mco_coro* fiber;
|
||||||
};
|
};
|
|
@ -11,6 +11,7 @@ CURL_PREFIX=$(realpath build/curl-wasm)
|
||||||
ZLIB_PREFIX=$(realpath build/zlib-wasm)
|
ZLIB_PREFIX=$(realpath build/zlib-wasm)
|
||||||
BROTLI_PREFIX=$(realpath build/brotli-wasm)
|
BROTLI_PREFIX=$(realpath build/brotli-wasm)
|
||||||
NGHTTP2_PREFIX=$(realpath build/nghttp2-wasm)
|
NGHTTP2_PREFIX=$(realpath build/nghttp2-wasm)
|
||||||
|
MINICORO_PREFIX=$(realpath build/minicoro-wasm)
|
||||||
|
|
||||||
if [ ! -d $OPENSSL_PREFIX ]; then
|
if [ ! -d $OPENSSL_PREFIX ]; then
|
||||||
tools/openssl.sh
|
tools/openssl.sh
|
||||||
|
@ -30,9 +31,13 @@ fi
|
||||||
if [ ! -d $CURL_PREFIX ]; then
|
if [ ! -d $CURL_PREFIX ]; then
|
||||||
tools/curl.sh
|
tools/curl.sh
|
||||||
fi
|
fi
|
||||||
|
if [ ! -d $MINICORO_PREFIX ]; then
|
||||||
|
tools/minicoro.sh
|
||||||
|
fi
|
||||||
|
|
||||||
cp -r $OPENSSL_PREFIX/* $CURL_PREFIX
|
cp -r $OPENSSL_PREFIX/* $CURL_PREFIX
|
||||||
cp -r $CJSON_PREFIX/* $CURL_PREFIX
|
cp -r $CJSON_PREFIX/* $CURL_PREFIX
|
||||||
cp -r $ZLIB_PREFIX/* $CURL_PREFIX
|
cp -r $ZLIB_PREFIX/* $CURL_PREFIX
|
||||||
cp -r $BROTLI_PREFIX/* $CURL_PREFIX
|
cp -r $BROTLI_PREFIX/* $CURL_PREFIX
|
||||||
cp -r $NGHTTP2_PREFIX/* $CURL_PREFIX
|
cp -r $NGHTTP2_PREFIX/* $CURL_PREFIX
|
||||||
|
cp -r $MINICORO_PREFIX/* $CURL_PREFIX
|
6
client/tools/minicoro.sh
Executable file
6
client/tools/minicoro.sh
Executable file
|
@ -0,0 +1,6 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#download the minicoro library
|
||||||
|
|
||||||
|
mkdir -p build/minicoro-wasm/include/
|
||||||
|
wget "https://raw.githubusercontent.com/edubart/minicoro/main/minicoro.h" -O build/minicoro-wasm/include/minicoro.h
|
Loading…
Add table
Add a link
Reference in a new issue