summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/c/include/unit/unit-wasm.h10
-rw-r--r--src/c/libunit-wasm.c29
2 files changed, 39 insertions, 0 deletions
diff --git a/src/c/include/unit/unit-wasm.h b/src/c/include/unit/unit-wasm.h
index 48079b1..c7625de 100644
--- a/src/c/include/unit/unit-wasm.h
+++ b/src/c/include/unit/unit-wasm.h
@@ -84,6 +84,15 @@ typedef enum {
LUW_HTTP_GATEWAY_TIMEOUT = 504,
} luw_http_status_t;
+#if !defined(__DEFINED_ssize_t)
+/*
+ * Match the typedef from wasm32-wasi/include/bits/alltypes.h
+ * without requiring the wasi-sysroot for building the rust
+ * stuff.
+ */
+typedef long ssize_t;
+#endif
+
struct luw_hdr_field {
u32 name_off;
u32 name_len;
@@ -239,6 +248,7 @@ extern int luw_mem_writep(luw_ctx_t *ctx, const char *fmt, ...);
extern size_t luw_mem_writep_data(luw_ctx_t *ctx, const u8 *src, size_t size);
extern void luw_req_buf_append(luw_ctx_t *ctx, const u8 *src);
extern void luw_req_buf_copy(luw_ctx_t *ctx, const u8 *src);
+extern ssize_t luw_mem_splice_file(const u8 *src, int fd);
extern size_t luw_mem_fill_buf_from_req(luw_ctx_t *ctx, size_t from);
extern void luw_mem_reset(luw_ctx_t *ctx);
extern void luw_http_set_response_status(luw_http_status_t status);
diff --git a/src/c/libunit-wasm.c b/src/c/libunit-wasm.c
index fdf9499..1b36cf9 100644
--- a/src/c/libunit-wasm.c
+++ b/src/c/libunit-wasm.c
@@ -14,10 +14,16 @@
#include <stdarg.h>
#include <string.h>
#include <strings.h>
+#include <unistd.h>
#include <errno.h>
#include "unit/unit-wasm.h"
+#define MIN(a, b) \
+ ({ __typeof__(a) _a = (a); \
+ __typeof__ (b) _b = (b); \
+ _a < _b ? _a : _b; })
+
/*
* Some handlers are required some are optional.
*
@@ -315,6 +321,29 @@ void luw_req_buf_copy(luw_ctx_t *ctx, const u8 *src)
ctx->req->total_content_sent = req->total_content_sent;
}
+/* Copy data from the request to a given file-descriptor. */
+ssize_t luw_mem_splice_file(const u8 *src, int fd)
+{
+ struct luw_req *req = (struct luw_req *)src;
+ size_t written = 0;
+ size_t bytes_splice = 1024 * 128; /* It's what cp(1) uses */
+
+ do {
+ ssize_t bytes_wrote;
+
+ bytes_splice = MIN(bytes_splice, req->content_sent - written);
+
+ bytes_wrote = write(fd, src + req->content_off + written,
+ bytes_splice);
+ if (bytes_wrote == -1)
+ return -1;
+
+ written += bytes_wrote;
+ } while (written < req->content_sent);
+
+ return written;
+}
+
/*
* Convenience function to fill the response buffer with data from
* the request buffer.