Wed, 27 Nov 2024 23:00:07 +0100
add TODO to use a future ucx feature
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2013 Olaf Wintermann. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef IOSTREAM_H #define IOSTREAM_H #include <openssl/ssl.h> #include "../public/nsapi.h" #include "systems.h" #ifdef _WIN32 #include <windows.h> #include <winsock2.h> #endif #ifdef __cplusplus extern "C" { #endif #ifdef XP_UNIX #define SYS_SOCKET int #elif defined(XP_WIN32) #define SYS_SOCKET SOCKET #endif #define IO_MODE_BLOCKING 0 #define IO_MODE_NONBLOCKING 1 #define IO_POLL_NONE 0 #define IO_POLL_IN 1 #define IO_POLL_OUT 2 #define IO_STREAM_TYPE_HTTP 0x48545450 #define IO_STREAM_TYPE_SSL 0x53534C typedef struct IOStream IOStream; typedef struct Sysstream Sysstream; typedef struct HttpStream HttpStream; typedef ssize_t(*io_write_f)(IOStream *, const void *, size_t); typedef ssize_t(*io_writev_f)(IOStream *, struct iovec *, int); typedef ssize_t(*io_read_f)(IOStream *, void *, size_t); typedef ssize_t(*io_sendfile_f)(IOStream *, sendfiledata *); typedef void(*io_close_f)(IOStream *); typedef void(*io_finish_f)(IOStream *); typedef void(*io_setmode_f)(IOStream *, int); typedef int(*io_poll_f)(IOStream *, EventHandler *, int, Event *); struct IOStream { io_write_f write; io_writev_f writev; io_read_f read; io_sendfile_f sendfile; io_close_f close; io_finish_f finish; io_setmode_f setmode; io_poll_f poll; int io_errno; unsigned int type; }; struct Sysstream { IOStream st; #ifdef XP_UNIX int fd; #elif defined(XP_WIN32) SOCKET fd; #endif }; #define HTTP_STREAM_CBUF_SIZE 16 struct HttpStream { IOStream st; IOStream *fd; uint64_t written; /* * content-length or current chunk size */ uint64_t max_read; /* * total bytes read (with content-length) or bytes read of current chunk */ uint64_t read; /* * total bytes read with chunked transfer encoding */ uint64_t read_total; /* * read buffer (used only with chunked transfer encoding) */ char *readbuf; /* * readbuf allocated size */ size_t bufsize; /* * number of bytes currently stored in readbuf */ int *buflen; /* * current position in the read buffer */ int *bufpos; /* * current chunk_buf position */ int chunk_buf_pos; /* * buffer used only for parsing chunk headers */ char chunk_buf[HTTP_STREAM_CBUF_SIZE]; /* * chunked transfer encoding for write enabled? */ WSBool chunked_enc; /* * current chunk size (set after the header is sent) */ size_t current_chunk_length; /* * current chunk position */ size_t current_chunk_pos; /* * missing trailer before new data * 0: no trailer * 2: crlf * 1: lf */ int current_trailer; /* * write chunk header buffer */ char write_chunk_buf[HTTP_STREAM_CBUF_SIZE]; /* * chunk header buffer length * only used when the chunk header was completely sent * must be 0 before payload data is sent */ int write_chunk_buf_len; /* * current write_chunk_buf position (if remaining != 0) */ int write_chunk_buf_pos; /* * end of file indicator (read) */ WSBool read_eof; /* * end of file indicator (write) */ WSBool write_eof; }; typedef struct SSLStream { IOStream st; SSL *ssl; int error; } SSLStream; void io_set_max_writes(int n); /* system stream */ IOStream* Sysstream_new(pool_handle_t *pool, SYS_SOCKET fd); ssize_t net_sys_write(Sysstream *st, const void *buf, size_t nbytes); ssize_t net_sys_writev(Sysstream *st, struct iovec *iovec, int iovcnt); ssize_t net_sys_read(Sysstream *st, void *buf, size_t nbytes); ssize_t net_sys_sendfile(Sysstream *st, sendfiledata *sfd); void net_sys_close(Sysstream *st); void net_sys_setmode(Sysstream *st, int mode); int net_sys_poll(Sysstream *st, EventHandler *ev, int events, Event *cb); /* http stream */ IOStream* httpstream_new(pool_handle_t *pool, IOStream *fd); int httpstream_enable_chunked_read(IOStream *st, char *buffer, size_t bufsize, int *cursize, int *pos); int httpstream_enable_chunked_write(IOStream *st); int httpstream_set_max_read(IOStream *st, int64_t maxread); WSBool httpstream_eof(IOStream *st); int64_t httpstream_written(IOStream *st); ssize_t net_http_write(HttpStream *st, const void *buf, size_t nbytes); ssize_t net_http_writev(HttpStream *st, struct iovec *iovec, int iovcnt); ssize_t net_http_read(HttpStream *st, void *buf, size_t nbytes); ssize_t net_http_read_chunked(HttpStream *st, void *buf, size_t nbytes); ssize_t net_http_sendfile(HttpStream *st, sendfiledata *sfd); void net_http_close(HttpStream *st); void net_http_finish(HttpStream *st); void net_http_setmode(HttpStream *st, int mode); int net_http_poll(HttpStream *st, EventHandler *ev, int events, Event *cb); int http_stream_parse_chunk_header(char *str, int len, WSBool first, int64_t *chunklen); /* ssl stream */ IOStream* sslstream_new(pool_handle_t *pool, SSL *ssl); ssize_t net_ssl_write(SSLStream *st, const void *buf, size_t nbytes); ssize_t net_ssl_writev(SSLStream *st, struct iovec *iovec, int iovcnt); ssize_t net_ssl_read(SSLStream *st, void *buf, size_t nbytes); void net_ssl_close(SSLStream *st); void net_ssl_finish(SSLStream *st); void net_ssl_setmode(SSLStream *st, int mode); int net_ssl_poll(SSLStream *st, EventHandler *ev, int events, Event *cb); /* net_ functions */ ssize_t net_fallback_sendfile(IOStream *fd, sendfiledata *sfd); void net_finish(SYS_NETFD fd); #ifdef __cplusplus } #endif #endif /* IOSTREAM_H */