UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2013 Olaf Wintermann. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #ifndef IOSTREAM_H 30 #define IOSTREAM_H 31 32 #include <openssl/ssl.h> 33 #include "../public/nsapi.h" 34 #include "systems.h" 35 36 #ifdef _WIN32 37 #include <windows.h> 38 #include <winsock2.h> 39 #endif 40 41 #ifdef __cplusplus 42 extern "C" { 43 #endif 44 45 #ifdef XP_UNIX 46 #define SYS_SOCKET int 47 #elif defined(XP_WIN32) 48 #define SYS_SOCKET SOCKET 49 #endif 50 51 #define IO_MODE_BLOCKING 0 52 #define IO_MODE_NONBLOCKING 1 53 54 #define IO_POLL_NONE 0 55 #define IO_POLL_IN 1 56 #define IO_POLL_OUT 2 57 58 #define IO_STREAM_TYPE_HTTP 0x48545450 59 #define IO_STREAM_TYPE_SSL 0x53534C 60 61 typedef struct IOStream IOStream; 62 typedef struct Sysstream Sysstream; 63 typedef struct HttpStream HttpStream; 64 65 typedef ssize_t(*io_write_f)(IOStream *, const void *, size_t); 66 typedef ssize_t(*io_writev_f)(IOStream *, struct iovec *, int); 67 typedef ssize_t(*io_read_f)(IOStream *, void *, size_t); 68 typedef ssize_t(*io_sendfile_f)(IOStream *, sendfiledata *); 69 typedef void(*io_close_f)(IOStream *); 70 typedef void(*io_finish_f)(IOStream *); 71 typedef void(*io_setmode_f)(IOStream *, int); 72 typedef int(*io_poll_f)(IOStream *, EventHandler *, int, Event *); 73 74 struct IOStream { 75 io_write_f write; 76 io_writev_f writev; 77 io_read_f read; 78 io_sendfile_f sendfile; 79 io_close_f close; 80 io_finish_f finish; 81 io_setmode_f setmode; 82 io_poll_f poll; 83 int io_errno; 84 unsigned int type; 85 }; 86 87 struct Sysstream { 88 IOStream st; 89 #ifdef XP_UNIX 90 int fd; 91 #elif defined(XP_WIN32) 92 SOCKET fd; 93 #endif 94 }; 95 96 #define HTTP_STREAM_CBUF_SIZE 16 97 struct HttpStream { 98 IOStream st; 99 IOStream *fd; 100 101 uint64_t written; 102 /* 103 * content-length or current chunk size 104 */ 105 uint64_t max_read; 106 /* 107 * total bytes read (with content-length) or bytes read of current chunk 108 */ 109 uint64_t read; 110 /* 111 * total bytes read with chunked transfer encoding 112 */ 113 uint64_t read_total; 114 /* 115 * read buffer (used only with chunked transfer encoding) 116 */ 117 char *readbuf; 118 /* 119 * readbuf allocated size 120 */ 121 size_t bufsize; 122 /* 123 * number of bytes currently stored in readbuf 124 */ 125 int *buflen; 126 /* 127 * current position in the read buffer 128 */ 129 int *bufpos; 130 /* 131 * current chunk_buf position 132 */ 133 int chunk_buf_pos; 134 /* 135 * buffer used only for parsing chunk headers 136 */ 137 char chunk_buf[HTTP_STREAM_CBUF_SIZE]; 138 /* 139 * chunked transfer encoding for write enabled? 140 */ 141 WSBool chunked_enc; 142 /* 143 * current chunk size (set after the header is sent) 144 */ 145 size_t current_chunk_length; 146 /* 147 * current chunk position 148 */ 149 size_t current_chunk_pos; 150 /* 151 * missing trailer before new data 152 * 0: no trailer 153 * 2: crlf 154 * 1: lf 155 */ 156 int current_trailer; 157 /* 158 * write chunk header buffer 159 */ 160 char write_chunk_buf[HTTP_STREAM_CBUF_SIZE]; 161 /* 162 * chunk header buffer length 163 * only used when the chunk header was completely sent 164 * must be 0 before payload data is sent 165 */ 166 int write_chunk_buf_len; 167 /* 168 * current write_chunk_buf position (if remaining != 0) 169 */ 170 int write_chunk_buf_pos; 171 /* 172 * end of file indicator (read) 173 */ 174 WSBool read_eof; 175 /* 176 * end of file indicator (write) 177 */ 178 WSBool write_eof; 179 }; 180 181 typedef struct SSLStream { 182 IOStream st; 183 SSL *ssl; 184 int error; 185 } SSLStream; 186 187 void io_set_max_writes(int n); 188 189 /* system stream */ 190 IOStream* Sysstream_new(pool_handle_t *pool, SYS_SOCKET fd); 191 192 ssize_t net_sys_write(Sysstream *st, const void *buf, size_t nbytes); 193 ssize_t net_sys_writev(Sysstream *st, struct iovec *iovec, int iovcnt); 194 ssize_t net_sys_read(Sysstream *st, void *buf, size_t nbytes); 195 ssize_t net_sys_sendfile(Sysstream *st, sendfiledata *sfd); 196 void net_sys_close(Sysstream *st); 197 void net_sys_setmode(Sysstream *st, int mode); 198 int net_sys_poll(Sysstream *st, EventHandler *ev, int events, Event *cb); 199 200 /* http stream */ 201 IOStream* httpstream_new(pool_handle_t *pool, IOStream *fd); 202 203 int httpstream_enable_chunked_read(IOStream *st, char *buffer, size_t bufsize, int *cursize, int *pos); 204 int httpstream_enable_chunked_write(IOStream *st); 205 int httpstream_set_max_read(IOStream *st, int64_t maxread); 206 WSBool httpstream_eof(IOStream *st); 207 int64_t httpstream_written(IOStream *st); 208 209 ssize_t net_http_write(HttpStream *st, const void *buf, size_t nbytes); 210 ssize_t net_http_writev(HttpStream *st, struct iovec *iovec, int iovcnt); 211 ssize_t net_http_read(HttpStream *st, void *buf, size_t nbytes); 212 ssize_t net_http_read_chunked(HttpStream *st, void *buf, size_t nbytes); 213 ssize_t net_http_sendfile(HttpStream *st, sendfiledata *sfd); 214 void net_http_close(HttpStream *st); 215 void net_http_finish(HttpStream *st); 216 void net_http_setmode(HttpStream *st, int mode); 217 int net_http_poll(HttpStream *st, EventHandler *ev, int events, Event *cb); 218 219 int http_stream_parse_chunk_header(char *str, int len, WSBool first, int64_t *chunklen); 220 221 /* ssl stream */ 222 IOStream* sslstream_new(pool_handle_t *pool, SSL *ssl); 223 224 ssize_t net_ssl_write(SSLStream *st, const void *buf, size_t nbytes); 225 ssize_t net_ssl_writev(SSLStream *st, struct iovec *iovec, int iovcnt); 226 ssize_t net_ssl_read(SSLStream *st, void *buf, size_t nbytes); 227 void net_ssl_close(SSLStream *st); 228 void net_ssl_finish(SSLStream *st); 229 void net_ssl_setmode(SSLStream *st, int mode); 230 int net_ssl_poll(SSLStream *st, EventHandler *ev, int events, Event *cb); 231 232 /* net_ functions */ 233 ssize_t net_fallback_sendfile(IOStream *fd, sendfiledata *sfd); 234 void net_finish(SYS_NETFD fd); 235 236 #ifdef __cplusplus 237 } 238 #endif 239 240 #endif /* IOSTREAM_H */ 241 242