Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[chunk/network] use glib error system to report errors (instead of us…

…ing virtualrequest context)
  • Loading branch information...
commit b1c45e6a8f8ae0cc7dae308d75bd73a481e08471 1 parent 77f786e
Stefan Bühler stbuehler authored
23 include/lighttpd/chunk.h
@@ -50,7 +50,7 @@ struct liChunk {
50 50 GList cq_link;
51 51 };
52 52
53   -typedef void (*liCQLimitNnotifyCB)(liVRequest *vr, gpointer context, gboolean locked);
  53 +typedef void (*liCQLimitNotifyCB)(liVRequest *vr, gpointer context, gboolean locked);
54 54 struct liCQLimit {
55 55 gint refcount;
56 56 liVRequest *vr;
@@ -60,7 +60,7 @@ struct liCQLimit {
60 60
61 61 ev_io *io_watcher;
62 62
63   - liCQLimitNnotifyCB notify; /* callback to reactivate input */
  63 + liCQLimitNotifyCB notify; /* callback to reactivate input */
64 64 gpointer context;
65 65 };
66 66
@@ -79,18 +79,21 @@ struct liChunkIter {
79 79 GList *element;
80 80 };
81 81
  82 +#define LI_CHUNK_ERROR li_chunk_error_quark()
  83 +LI_API GQuark li_chunk_error_quark(void);
  84 +
82 85 /******************
83 86 * chunkfile *
84 87 ******************/
85 88
86   -liChunkFile *li_chunkfile_new(GString *name, int fd, gboolean is_temp);
87   -void li_chunkfile_acquire(liChunkFile *cf);
88   -void li_chunkfile_release(liChunkFile *cf);
  89 +LI_API liChunkFile *li_chunkfile_new(GString *name, int fd, gboolean is_temp);
  90 +LI_API void li_chunkfile_acquire(liChunkFile *cf);
  91 +LI_API void li_chunkfile_release(liChunkFile *cf);
89 92
90 93 /* open the file cf->name if it is not already opened for reading
91 94 * may return HANDLER_GO_ON, HANDLER_ERROR
92 95 */
93   -LI_API liHandlerResult li_chunkfile_open(liVRequest *vr, liChunkFile *cf);
  96 +LI_API liHandlerResult li_chunkfile_open(liChunkFile *cf, GError **err);
94 97
95 98 /******************
96 99 * chunk iterator *
@@ -104,12 +107,12 @@ INLINE goffset li_chunkiter_length(liChunkIter iter);
104 107 * but needs to do io in case of FILE_CHUNK; the data is _not_ marked as "done"
105 108 * may return HANDLER_GO_ON, HANDLER_ERROR
106 109 */
107   -LI_API liHandlerResult li_chunkiter_read(liVRequest *vr, liChunkIter iter, off_t start, off_t length, char **data_start, off_t *data_len);
  110 +LI_API liHandlerResult li_chunkiter_read(liChunkIter iter, off_t start, off_t length, char **data_start, off_t *data_len, GError **err);
108 111
109 112 /* same as li_chunkiter_read, but tries mmap() first and falls back to read();
110 113 * as accessing mmap()-ed areas may result in SIGBUS, you have to handle that signal somehow.
111 114 */
112   -LI_API liHandlerResult li_chunkiter_read_mmap(liVRequest *vr, liChunkIter iter, off_t start, off_t length, char **data_start, off_t *data_len);
  115 +LI_API liHandlerResult li_chunkiter_read_mmap(liChunkIter iter, off_t start, off_t length, char **data_start, off_t *data_len, GError **err);
113 116
114 117 /******************
115 118 * chunk *
@@ -198,8 +201,8 @@ INLINE liChunkIter li_chunkqueue_iter(liChunkQueue *cq);
198 201
199 202 INLINE liChunk* li_chunkqueue_first_chunk(liChunkQueue *cq);
200 203
201   -LI_API gboolean li_chunkqueue_extract_to(liVRequest *vr, liChunkQueue *cq, goffset len, GString *dest);
202   -LI_API gboolean li_chunkqueue_extract_to_bytearr(liVRequest *vr, liChunkQueue *cq, goffset len, GByteArray *dest);
  204 +LI_API gboolean li_chunkqueue_extract_to(liChunkQueue *cq, goffset len, GString *dest, GError **err);
  205 +LI_API gboolean li_chunkqueue_extract_to_bytearr(liChunkQueue *cq, goffset len, GByteArray *dest, GError **err);
203 206
204 207 /* helper functions to append to the last BUFFER_CHUNK of a chunkqueue */
205 208
8 include/lighttpd/chunk_parser.h
@@ -28,12 +28,12 @@ struct liChunkParserMark {
28 28 LI_API void li_chunk_parser_init(liChunkParserCtx *ctx, liChunkQueue *cq);
29 29 LI_API void li_chunk_parser_reset(liChunkParserCtx *ctx);
30 30 LI_API liHandlerResult li_chunk_parser_prepare(liChunkParserCtx *ctx);
31   -LI_API liHandlerResult li_chunk_parser_next(liVRequest *vr, liChunkParserCtx *ctx, char **p, char **pe);
  31 +LI_API liHandlerResult li_chunk_parser_next(liChunkParserCtx *ctx, char **p, char **pe, GError **err);
32 32 LI_API void li_chunk_parser_done(liChunkParserCtx *ctx, goffset len);
33 33
34 34 /* extract [from..to) */
35   -LI_API gboolean li_chunk_extract_to(liVRequest *vr, liChunkParserMark from, liChunkParserMark to, GString *dest);
36   -LI_API GString* li_chunk_extract(liVRequest *vr, liChunkParserMark from, liChunkParserMark to);
  35 +LI_API gboolean li_chunk_extract_to(liChunkParserMark from, liChunkParserMark to, GString *dest, GError **err);
  36 +LI_API GString* li_chunk_extract(liChunkParserMark from, liChunkParserMark to, GError **err);
37 37
38 38 INLINE liChunkParserMark li_chunk_parser_getmark(liChunkParserCtx *ctx, const char *fpc);
39 39
@@ -49,6 +49,6 @@ INLINE liChunkParserMark li_chunk_parser_getmark(liChunkParserCtx *ctx, const ch
49 49 return m;
50 50 }
51 51
52   -#define GETMARK(FPC) (li_chunk_parser_getmark(&ctx->chunk_ctx, FPC))
  52 +#define LI_GETMARK(FPC) (li_chunk_parser_getmark(&ctx->chunk_ctx, FPC))
53 53
54 54 #endif
17 include/lighttpd/network.h
@@ -9,30 +9,33 @@
9 9 # define USE_SENDFILE
10 10 #endif
11 11
  12 +#define LI_NETWORK_ERROR li_network_error_quark()
  13 +LI_API GQuark li_network_error_quark(void);
  14 +
12 15 /** repeats write after EINTR */
13 16 LI_API ssize_t li_net_write(int fd, void *buf, ssize_t nbyte);
14 17
15 18 /** repeats read after EINTR */
16 19 LI_API ssize_t li_net_read(int fd, void *buf, ssize_t nbyte);
17 20
18   -LI_API liNetworkStatus li_network_write(liVRequest *vr, int fd, liChunkQueue *cq, goffset write_max);
19   -LI_API liNetworkStatus li_network_read(liVRequest *vr, int fd, liChunkQueue *cq, liBuffer **buffer);
  21 +LI_API liNetworkStatus li_network_write(int fd, liChunkQueue *cq, goffset write_max, GError **err);
  22 +LI_API liNetworkStatus li_network_read(int fd, liChunkQueue *cq, liBuffer **buffer, GError **err);
20 23
21 24 /* use writev for mem chunks, buffered read/write for files */
22   -LI_API liNetworkStatus li_network_write_writev(liVRequest *vr, int fd, liChunkQueue *cq, goffset *write_max);
  25 +LI_API liNetworkStatus li_network_write_writev(int fd, liChunkQueue *cq, goffset *write_max, GError **err);
23 26
24 27 #ifdef USE_SENDFILE
25 28 /* use sendfile for files, writev for mem chunks */
26   -LI_API liNetworkStatus li_network_write_sendfile(liVRequest *vr, int fd, liChunkQueue *cq, goffset *write_max);
  29 +LI_API liNetworkStatus li_network_write_sendfile(int fd, liChunkQueue *cq, goffset *write_max, GError **err);
27 30 #endif
28 31
29 32 /* write backends */
30   -LI_API liNetworkStatus li_network_backend_write(liVRequest *vr, int fd, liChunkQueue *cq, goffset *write_max);
31   -LI_API liNetworkStatus li_network_backend_writev(liVRequest *vr, int fd, liChunkQueue *cq, goffset *write_max);
  33 +LI_API liNetworkStatus li_network_backend_write(int fd, liChunkQueue *cq, goffset *write_max, GError **err);
  34 +LI_API liNetworkStatus li_network_backend_writev(int fd, liChunkQueue *cq, goffset *write_max, GError **err);
32 35
33 36 #define LI_NETWORK_FALLBACK(f, write_max) do { \
34 37 liNetworkStatus res; \
35   - switch(res = f(vr, fd, cq, write_max)) { \
  38 + switch(res = f(fd, cq, write_max, err)) { \
36 39 case LI_NETWORK_STATUS_SUCCESS: \
37 40 break; \
38 41 default: \
80 src/main/chunk.c
@@ -4,6 +4,10 @@
4 4 #include <sys/stat.h>
5 5 #include <fcntl.h>
6 6
  7 +GQuark li_chunk_error_quark(void) {
  8 + return g_quark_from_string("g-chunk-error-quark");
  9 +}
  10 +
7 11 /******************
8 12 * chunkfile *
9 13 ******************/
@@ -43,18 +47,20 @@ void li_chunkfile_release(liChunkFile *cf) {
43 47 /* open the file cf->name if it is not already opened for reading
44 48 * may return HANDLER_GO_ON, HANDLER_ERROR
45 49 */
46   -liHandlerResult li_chunkfile_open(liVRequest *vr, liChunkFile *cf) {
47   - if (!cf) return LI_HANDLER_ERROR;
  50 +liHandlerResult li_chunkfile_open(liChunkFile *cf, GError **err) {
  51 + g_return_val_if_fail (err == NULL || *err == NULL, LI_HANDLER_ERROR);
  52 +
  53 + if (NULL == cf) {
  54 + g_set_error(err, LI_CHUNK_ERROR, 0, "li_chunkfile_open: cf is NULL");
  55 + return LI_HANDLER_ERROR;
  56 + }
48 57 if (-1 != cf->fd) return LI_HANDLER_GO_ON;
49   - if (!cf->name) {
50   - VR_ERROR(vr, "%s", "Missing filename for FILE_CHUNK");
  58 + if (NULL == cf->name) {
  59 + g_set_error(err, LI_CHUNK_ERROR, 0, "li_chunkfile_open: Missing filename");
51 60 return LI_HANDLER_ERROR;
52 61 }
53 62 if (-1 == (cf->fd = open(cf->name->str, O_RDONLY))) {
54   - if (EMFILE == errno) {
55   - li_server_out_of_fds(vr->wrk->srv);
56   - }
57   - VR_ERROR(vr, "Couldn't open file '%s': %s", GSTR_SAFE_STR(cf->name), g_strerror(errno));
  63 + g_set_error(err, LI_CHUNK_ERROR, 0, "li_chunkfile_open: Couldn't open file '%s': %s", GSTR_SAFE_STR(cf->name), g_strerror(errno));
58 64 return LI_HANDLER_ERROR;
59 65 }
60 66 #ifdef FD_CLOEXEC
@@ -64,7 +70,7 @@ liHandlerResult li_chunkfile_open(liVRequest *vr, liChunkFile *cf) {
64 70 /* tell the kernel that we want to stream the file */
65 71 if (-1 == posix_fadvise(cf->fd, 0, 0, POSIX_FADV_SEQUENTIAL)) {
66 72 if (ENOSYS != errno) {
67   - VR_ERROR(vr, "posix_fadvise failed for '%s': %s (%i)", GSTR_SAFE_STR(cf->name), g_strerror(errno), cf->fd);
  73 + /* g_debug("posix_fadvise failed for '%s': %s (%i)", GSTR_SAFE_STR(cf->name), g_strerror(errno), cf->fd); */
68 74 }
69 75 }
70 76 #endif
@@ -83,11 +89,13 @@ liHandlerResult li_chunkfile_open(liVRequest *vr, liChunkFile *cf) {
83 89 * but needs to do io in case of FILE_CHUNK; the data is _not_ marked as "done"
84 90 * may return HANDLER_GO_ON, HANDLER_ERROR
85 91 */
86   -liHandlerResult li_chunkiter_read(liVRequest *vr, liChunkIter iter, off_t start, off_t length, char **data_start, off_t *data_len) {
  92 +liHandlerResult li_chunkiter_read(liChunkIter iter, off_t start, off_t length, char **data_start, off_t *data_len, GError **err) {
87 93 liChunk *c = li_chunkiter_chunk(iter);
88 94 off_t we_have, our_start;
89 95 liHandlerResult res = LI_HANDLER_GO_ON;
90 96
  97 + g_return_val_if_fail (err == NULL || *err == NULL, LI_HANDLER_ERROR);
  98 +
91 99 if (!c) return LI_HANDLER_ERROR;
92 100 if (!data_start || !data_len) return LI_HANDLER_ERROR;
93 101
@@ -106,7 +114,7 @@ liHandlerResult li_chunkiter_read(liVRequest *vr, liChunkIter iter, off_t start,
106 114 *data_len = length;
107 115 break;
108 116 case FILE_CHUNK:
109   - if (LI_HANDLER_GO_ON != (res = li_chunkfile_open(vr, c->data.file.file))) return res;
  117 + if (LI_HANDLER_GO_ON != (res = li_chunkfile_open(c->data.file.file, err))) return res;
110 118
111 119 if (length > MAX_MMAP_CHUNK) length = MAX_MMAP_CHUNK;
112 120
@@ -121,7 +129,7 @@ liHandlerResult li_chunkiter_read(liVRequest *vr, liChunkIter iter, off_t start,
121 129 read_chunk:
122 130 if (-1 == (we_have = pread(c->data.file.file->fd, c->mem->data, length, our_start))) {
123 131 if (EINTR == errno) goto read_chunk;
124   - VR_ERROR(vr, "pread failed for '%s' (fd = %i): %s",
  132 + g_set_error(err, LI_CHUNK_ERROR, 0, "li_chunkiter_read: pread failed for '%s' (fd = %i): %s",
125 133 GSTR_SAFE_STR(c->data.file.file->name), c->data.file.file->fd,
126 134 g_strerror(errno));
127 135 g_byte_array_free(c->mem, TRUE);
@@ -131,7 +139,7 @@ liHandlerResult li_chunkiter_read(liVRequest *vr, liChunkIter iter, off_t start,
131 139 /* may return less than requested bytes due to signals */
132 140 /* CON_TRACE(srv, "read return unexpected number of bytes"); */
133 141 if (we_have == 0) {
134   - VR_ERROR(vr, "pread returned 0 bytes for '%s' (fd = %i): unexpected end of file?",
  142 + g_set_error(err, LI_CHUNK_ERROR, 0, "li_chunkiter_read: pread returned 0 bytes for '%s' (fd = %i): unexpected end of file?",
135 143 GSTR_SAFE_STR(c->data.file.file->name), c->data.file.file->fd);
136 144 g_byte_array_free(c->mem, TRUE);
137 145 c->mem = NULL;
@@ -154,12 +162,14 @@ liHandlerResult li_chunkiter_read(liVRequest *vr, liChunkIter iter, off_t start,
154 162 /* same as li_chunkiter_read, but tries mmap() first and falls back to pread();
155 163 * as accessing mmap()-ed areas may result in SIGBUS, you have to handle that signal somehow.
156 164 */
157   -liHandlerResult li_chunkiter_read_mmap(liVRequest *vr, liChunkIter iter, off_t start, off_t length, char **data_start, off_t *data_len) {
  165 +liHandlerResult li_chunkiter_read_mmap(liChunkIter iter, off_t start, off_t length, char **data_start, off_t *data_len, GError **err) {
158 166 liChunk *c = li_chunkiter_chunk(iter);
159 167 off_t we_want, we_have, our_start, our_offset;
160 168 liHandlerResult res = LI_HANDLER_GO_ON;
161 169 int mmap_errno = 0;
162 170
  171 + g_return_val_if_fail (err == NULL || *err == NULL, LI_HANDLER_ERROR);
  172 +
163 173 if (!c) return LI_HANDLER_ERROR;
164 174 if (!data_start || !data_len) return LI_HANDLER_ERROR;
165 175
@@ -178,7 +188,7 @@ liHandlerResult li_chunkiter_read_mmap(liVRequest *vr, liChunkIter iter, off_t s
178 188 *data_len = length;
179 189 break;
180 190 case FILE_CHUNK:
181   - if (LI_HANDLER_GO_ON != (res = li_chunkfile_open(vr, c->data.file.file))) return res;
  191 + if (LI_HANDLER_GO_ON != (res = li_chunkfile_open(c->data.file.file, err))) return res;
182 192
183 193 if (length > MAX_MMAP_CHUNK) length = MAX_MMAP_CHUNK;
184 194
@@ -217,11 +227,11 @@ liHandlerResult li_chunkiter_read_mmap(liVRequest *vr, liChunkIter iter, off_t s
217 227 if (EINTR == errno) goto read_chunk;
218 228 /* prefer the error of the first syscall */
219 229 if (0 != mmap_errno) {
220   - VR_ERROR(vr, "mmap failed for '%s' (fd = %i): %s",
  230 + g_set_error(err, LI_CHUNK_ERROR, 0, "li_chunkiter_read_mmap: mmap failed for '%s' (fd = %i): %s",
221 231 GSTR_SAFE_STR(c->data.file.file->name), c->data.file.file->fd,
222 232 g_strerror(mmap_errno));
223 233 } else {
224   - VR_ERROR(vr, "pread failed for '%s' (fd = %i): %s",
  234 + g_set_error(err, LI_CHUNK_ERROR, 0, "li_chunkiter_read_mmap: pread failed for '%s' (fd = %i): %s",
225 235 GSTR_SAFE_STR(c->data.file.file->name), c->data.file.file->fd,
226 236 g_strerror(errno));
227 237 }
@@ -241,9 +251,11 @@ liHandlerResult li_chunkiter_read_mmap(liVRequest *vr, liChunkIter iter, off_t s
241 251 /* don't advise files < 64Kb */
242 252 if (c->data.file.mmap.length > (64*1024) &&
243 253 0 != madvise(c->data.file.mmap.data, c->data.file.mmap.length, MADV_WILLNEED)) {
244   - VR_ERROR(vr, "madvise failed for '%s' (fd = %i): %s",
  254 + /*
  255 + g_debug("madvise failed for '%s' (fd = %i): %s",
245 256 GSTR_SAFE_STR(c->data.file.file->name), c->data.file.file->fd,
246 257 g_strerror(errno));
  258 + */
247 259 }
248 260 #endif
249 261 }
@@ -270,24 +282,6 @@ static liChunk* chunk_new() {
270 282 return c;
271 283 }
272 284
273   -/*
274   -static void chunk_reset(chunk *c) {
275   - if (!c) return;
276   - c->type = UNUSED_CHUNK;
277   - c->offset = 0;
278   - if (c->data.str) g_string_free(c->data.str, TRUE);
279   - c->data.str = NULL;
280   - if (c->data.file.file) chunkfile_release(c->data.file.file);
281   - c->data.file.file = NULL;
282   - c->data.file.start = 0;
283   - c->data.file.length = 0;
284   - if (MAP_FAILED != c->data.file.mmap.data) munmap(c->data.file.mmap.data, c->data.file.mmap.length);
285   - c->data.file.mmap.data = MAP_FAILED;
286   - c->data.file.mmap.length = 0;
287   - c->data.file.mmap.offset = 0;
288   -}
289   -*/
290   -
291 285 static void chunk_free(liChunkQueue *cq, liChunk *c) {
292 286 if (!c) return;
293 287 if (cq) {
@@ -815,9 +809,12 @@ goffset li_chunkqueue_skip_all(liChunkQueue *cq) {
815 809 return bytes;
816 810 }
817 811
818   -gboolean li_chunkqueue_extract_to(liVRequest *vr, liChunkQueue *cq, goffset len, GString *dest) {
  812 +gboolean li_chunkqueue_extract_to(liChunkQueue *cq, goffset len, GString *dest, GError **err) {
819 813 liChunkIter ci;
820 814 goffset coff, clen;
  815 +
  816 + g_return_val_if_fail (err == NULL || *err == NULL, FALSE);
  817 +
821 818 g_string_set_size(dest, 0);
822 819 if (len > cq->length) return FALSE;
823 820
@@ -829,7 +826,7 @@ gboolean li_chunkqueue_extract_to(liVRequest *vr, liChunkQueue *cq, goffset len,
829 826 while (coff < clen) {
830 827 gchar *buf;
831 828 off_t we_have;
832   - if (LI_HANDLER_GO_ON != li_chunkiter_read(vr, ci, coff, len, &buf, &we_have)) goto error;
  829 + if (LI_HANDLER_GO_ON != li_chunkiter_read(ci, coff, len, &buf, &we_have, err)) goto error;
833 830 g_string_append_len(dest, buf, we_have);
834 831 coff += we_have;
835 832 len -= we_have;
@@ -845,9 +842,12 @@ gboolean li_chunkqueue_extract_to(liVRequest *vr, liChunkQueue *cq, goffset len,
845 842 return FALSE;
846 843 }
847 844
848   -gboolean li_chunkqueue_extract_to_bytearr(liVRequest *vr, liChunkQueue *cq, goffset len, GByteArray *dest) {
  845 +gboolean li_chunkqueue_extract_to_bytearr(liChunkQueue *cq, goffset len, GByteArray *dest, GError **err) {
849 846 liChunkIter ci;
850 847 goffset coff, clen;
  848 +
  849 + g_return_val_if_fail (err == NULL || *err == NULL, FALSE);
  850 +
851 851 g_byte_array_set_size(dest, 0);
852 852 if (len > cq->length) return FALSE;
853 853
@@ -862,7 +862,7 @@ gboolean li_chunkqueue_extract_to_bytearr(liVRequest *vr, liChunkQueue *cq, goff
862 862 while (coff < clen) {
863 863 gchar *buf;
864 864 off_t we_have;
865   - if (LI_HANDLER_GO_ON != li_chunkiter_read(vr, ci, coff, len, &buf, &we_have)) goto error;
  865 + if (LI_HANDLER_GO_ON != li_chunkiter_read(ci, coff, len, &buf, &we_have, err)) goto error;
866 866 g_byte_array_append(dest, (guint8*) buf, we_have);
867 867 coff += we_have;
868 868 len -= we_have;
18 src/main/chunk_parser.c
@@ -22,10 +22,12 @@ liHandlerResult li_chunk_parser_prepare(liChunkParserCtx *ctx) {
22 22 return LI_HANDLER_GO_ON;
23 23 }
24 24
25   -liHandlerResult li_chunk_parser_next(liVRequest *vr, liChunkParserCtx *ctx, char **p, char **pe) {
  25 +liHandlerResult li_chunk_parser_next(liChunkParserCtx *ctx, char **p, char **pe, GError **err) {
26 26 off_t l;
27 27 liHandlerResult res;
28 28
  29 + g_return_val_if_fail (err == NULL || *err == NULL, LI_HANDLER_ERROR);
  30 +
29 31 if (NULL == ctx->curi.element) return LI_HANDLER_WAIT_FOR_EVENT;
30 32
31 33 while (ctx->start >= (l = li_chunkiter_length(ctx->curi))) {
@@ -38,7 +40,7 @@ liHandlerResult li_chunk_parser_next(liVRequest *vr, liChunkParserCtx *ctx, char
38 40
39 41 if (NULL == ctx->curi.element) return LI_HANDLER_WAIT_FOR_EVENT;
40 42
41   - if (LI_HANDLER_GO_ON != (res = li_chunkiter_read(vr, ctx->curi, ctx->start, l - ctx->start, &ctx->buf, &ctx->length))) {
  43 + if (LI_HANDLER_GO_ON != (res = li_chunkiter_read(ctx->curi, ctx->start, l - ctx->start, &ctx->buf, &ctx->length, err))) {
42 44 return res;
43 45 }
44 46
@@ -52,9 +54,11 @@ void li_chunk_parser_done(liChunkParserCtx *ctx, goffset len) {
52 54 ctx->start += len;
53 55 }
54 56
55   -gboolean li_chunk_extract_to(liVRequest *vr, liChunkParserMark from, liChunkParserMark to, GString *dest) {
  57 +gboolean li_chunk_extract_to(liChunkParserMark from, liChunkParserMark to, GString *dest, GError **err) {
56 58 liChunkParserMark i;
57 59
  60 + g_return_val_if_fail (err == NULL || *err == NULL, FALSE);
  61 +
58 62 g_string_set_size(dest, to.abs_pos - from.abs_pos);
59 63 li_g_string_clear(dest);
60 64
@@ -63,7 +67,7 @@ gboolean li_chunk_extract_to(liVRequest *vr, liChunkParserMark from, liChunkPars
63 67 while (i.pos < len) {
64 68 char *buf;
65 69 off_t we_have;
66   - if (LI_HANDLER_GO_ON != li_chunkiter_read(vr, i.ci, i.pos, len - i.pos, &buf, &we_have)) goto error;
  70 + if (LI_HANDLER_GO_ON != li_chunkiter_read(i.ci, i.pos, len - i.pos, &buf, &we_have, err)) goto error;
67 71 if (dest->len + we_have < dest->allocated_len) {
68 72 /* "fast" append */
69 73 memcpy(dest->str + dest->len, buf, we_have);
@@ -79,7 +83,7 @@ gboolean li_chunk_extract_to(liVRequest *vr, liChunkParserMark from, liChunkPars
79 83 while (i.pos < to.pos) {
80 84 char *buf;
81 85 off_t we_have;
82   - if (LI_HANDLER_GO_ON != li_chunkiter_read(vr, i.ci, i.pos, to.pos - i.pos, &buf, &we_have)) goto error;
  86 + if (LI_HANDLER_GO_ON != li_chunkiter_read(i.ci, i.pos, to.pos - i.pos, &buf, &we_have, err)) goto error;
83 87 if (dest->len + we_have < dest->allocated_len) {
84 88 /* "fast" append */
85 89 memcpy(dest->str + dest->len, buf, we_have);
@@ -98,9 +102,9 @@ gboolean li_chunk_extract_to(liVRequest *vr, liChunkParserMark from, liChunkPars
98 102 return FALSE;
99 103 }
100 104
101   -GString* li_chunk_extract(liVRequest *vr, liChunkParserMark from, liChunkParserMark to) {
  105 +GString* li_chunk_extract(liChunkParserMark from, liChunkParserMark to, GError **err) {
102 106 GString *str = g_string_sized_new(0);
103   - if (li_chunk_extract_to(vr, from, to, str)) return str;
  107 + if (li_chunk_extract_to(from, to, str, err)) return str;
104 108 g_string_free(str, TRUE);
105 109 return NULL;
106 110 }
14 src/main/connection.c
@@ -303,7 +303,12 @@ static G_GNUC_WARN_UNUSED_RESULT gboolean connection_try_read(liConnection *con)
303 303 if (con->srv_sock->read_cb) {
304 304 res = con->srv_sock->read_cb(con);
305 305 } else {
306   - res = li_network_read(con->mainvr, con->sock_watcher.fd, con->raw_in, &con->raw_in_buffer);
  306 + GError *err = NULL;
  307 + res = li_network_read(con->sock_watcher.fd, con->raw_in, &con->raw_in_buffer, &err);
  308 + if (NULL != err) {
  309 + VR_ERROR(con->mainvr, "%s", err->message);
  310 + g_error_free(err);
  311 + }
307 312 }
308 313
309 314 if (NULL == con->wrk->network_read_buf && NULL != con->raw_in_buffer
@@ -366,7 +371,12 @@ static G_GNUC_WARN_UNUSED_RESULT gboolean connection_try_write(liConnection *con
366 371 if (con->srv_sock->write_cb) {
367 372 res = con->srv_sock->write_cb(con, write_max);
368 373 } else {
369   - res = li_network_write(con->mainvr, con->sock_watcher.fd, con->raw_out, write_max);
  374 + GError *err = NULL;
  375 + res = li_network_write(con->sock_watcher.fd, con->raw_out, write_max, &err);
  376 + if (NULL != err) {
  377 + VR_ERROR(con->mainvr, "%s", err->message);
  378 + g_error_free(err);
  379 + }
370 380 }
371 381
372 382 transferred = transferred - con->raw_out->length;
8 src/main/filter_buffer_on_disk.c
@@ -68,6 +68,7 @@ liHandlerResult li_filter_buffer_on_disk(liVRequest *vr, liChunkQueue *out, liCh
68 68 liChunkIter ci;
69 69 off_t length, data_len;
70 70 char *data = NULL;
  71 + GError *err;
71 72
72 73 switch (c->type) {
73 74 case UNUSED_CHUNK: return LI_HANDLER_ERROR;
@@ -86,7 +87,12 @@ liHandlerResult li_filter_buffer_on_disk(liVRequest *vr, liChunkQueue *out, liCh
86 87 length = li_chunk_length(c);
87 88 ci = li_chunkqueue_iter(in);
88 89
89   - if (LI_HANDLER_GO_ON != li_chunkiter_read(vr, ci, 0, length, &data, &data_len)) {
  90 + err = NULL;
  91 + if (LI_HANDLER_GO_ON != li_chunkiter_read(ci, 0, length, &data, &data_len, &err)) {
  92 + if (NULL != err) {
  93 + VR_ERROR(vr, "%s", err->message);
  94 + g_error_free(err);
  95 + }
90 96 return LI_HANDLER_ERROR;
91 97 }
92 98
7 src/main/filter_chunked.c
@@ -45,7 +45,12 @@ liHandlerResult li_filter_chunked_encode(liVRequest *vr, liChunkQueue *out, liCh
45 45
46 46 #define read_char(c) do { \
47 47 while (!p || p >= pe) { \
48   - res = li_chunk_parser_next(vr, &ctx, &p, &pe); \
  48 + GError *err = NULL; \
  49 + res = li_chunk_parser_next(&ctx, &p, &pe, &err); \
  50 + if (NULL != err) { \
  51 + VR_ERROR(vr, "%s", err->message); \
  52 + g_error_free(err); \
  53 + } \
49 54 if (res == LI_HANDLER_WAIT_FOR_EVENT && in->is_closed) { \
50 55 res = LI_HANDLER_ERROR; \
51 56 } \
17 src/main/http_request_parser.rl
@@ -5,10 +5,10 @@
5 5
6 6 /** Machine **/
7 7
8   -#define _getString(M, FPC) (li_chunk_extract(vr, ctx->M, GETMARK(FPC)))
  8 +#define _getString(M, FPC) (li_chunk_extract(ctx->M, LI_GETMARK(FPC), NULL))
9 9 #define getString(FPC) _getString(mark, FPC)
10 10
11   -#define _getStringTo(M, FPC, s) (li_chunk_extract_to(vr, ctx->M, GETMARK(FPC), s))
  11 +#define _getStringTo(M, FPC, s) (li_chunk_extract_to(ctx->M, LI_GETMARK(FPC), s, NULL))
12 12 #define getStringTo(FPC, s) _getStringTo(mark, FPC, s)
13 13
14 14
@@ -17,7 +17,7 @@
17 17 machine li_http_request_parser;
18 18 variable cs ctx->chunk_ctx.cs;
19 19
20   - action mark { ctx->mark = GETMARK(fpc); }
  20 + action mark { ctx->mark = LI_GETMARK(fpc); }
21 21 action done { fbreak; }
22 22
23 23 action method {
@@ -149,8 +149,15 @@ liHandlerResult li_http_request_parse(liVRequest *vr, liHttpRequestCtx *ctx) {
149 149
150 150 while (!li_http_request_parser_has_error(ctx) && !li_http_request_parser_is_finished(ctx)) {
151 151 char *p, *pe;
152   -
153   - if (LI_HANDLER_GO_ON != (res = li_chunk_parser_next(vr, &ctx->chunk_ctx, &p, &pe))) return res;
  152 + GError *err = NULL;
  153 +
  154 + if (LI_HANDLER_GO_ON != (res = li_chunk_parser_next(&ctx->chunk_ctx, &p, &pe, &err))) {
  155 + if (NULL != err) {
  156 + VR_ERROR(vr, "%s", err->message);
  157 + g_error_free(err);
  158 + }
  159 + return res;
  160 + }
154 161
155 162 %% write exec;
156 163
17 src/main/http_response_parser.rl
@@ -4,10 +4,12 @@
4 4
5 5 /** Machine **/
6 6
7   -#define _getString(M, FPC) (li_chunk_extract(vr, ctx->M, GETMARK(FPC)))
  7 +
  8 +
  9 +#define _getString(M, FPC) (li_chunk_extract(ctx->M, LI_GETMARK(FPC), NULL))
8 10 #define getString(FPC) _getString(mark, FPC)
9 11
10   -#define _getStringTo(M, FPC, s) (li_chunk_extract_to(vr, ctx->M, GETMARK(FPC), s))
  12 +#define _getStringTo(M, FPC, s) (li_chunk_extract_to(ctx->M, LI_GETMARK(FPC), s, NULL))
11 13 #define getStringTo(FPC, s) _getStringTo(mark, FPC, s)
12 14
13 15
@@ -16,7 +18,7 @@
16 18 machine li_http_response_parser;
17 19 variable cs ctx->chunk_ctx.cs;
18 20
19   - action mark { ctx->mark = GETMARK(fpc); }
  21 + action mark { ctx->mark = LI_GETMARK(fpc); }
20 22 action done { fbreak; }
21 23
22 24 action status {
@@ -162,8 +164,15 @@ liHandlerResult li_http_response_parse(liVRequest *vr, liHttpResponseCtx *ctx) {
162 164
163 165 while (!li_http_response_parser_has_error(ctx)) {
164 166 char *p, *pe;
  167 + GError *err = NULL;
165 168
166   - if (LI_HANDLER_GO_ON != (res = li_chunk_parser_next(vr, &ctx->chunk_ctx, &p, &pe))) return res;
  169 + if (LI_HANDLER_GO_ON != (res = li_chunk_parser_next(&ctx->chunk_ctx, &p, &pe, &err))) {
  170 + if (NULL != err) {
  171 + VR_ERROR(vr, "%s", err->message);
  172 + g_error_free(err);
  173 + }
  174 + return res;
  175 + }
167 176
168 177 %% write exec;
169 178
18 src/main/network.c
@@ -2,6 +2,10 @@
2 2 #include <lighttpd/base.h>
3 3 #include <lighttpd/plugin_core.h>
4 4
  5 +GQuark li_network_error_quark(void) {
  6 + return g_quark_from_string("g-network-error-quark");
  7 +}
  8 +
5 9 /** repeats write after EINTR */
6 10 ssize_t li_net_write(int fd, void *buf, ssize_t nbyte) {
7 11 ssize_t r;
@@ -36,7 +40,7 @@ ssize_t li_net_read(int fd, void *buf, ssize_t nbyte) {
36 40 return r;
37 41 }
38 42
39   -liNetworkStatus li_network_write(liVRequest *vr, int fd, liChunkQueue *cq, goffset write_max) {
  43 +liNetworkStatus li_network_write(int fd, liChunkQueue *cq, goffset write_max, GError **err) {
40 44 liNetworkStatus res;
41 45 #ifdef TCP_CORK
42 46 int corked = 0;
@@ -54,9 +58,9 @@ liNetworkStatus li_network_write(liVRequest *vr, int fd, liChunkQueue *cq, goffs
54 58
55 59 /* TODO: add setup-option to select the backend */
56 60 #ifdef USE_SENDFILE
57   - res = li_network_write_sendfile(vr, fd, cq, &write_max);
  61 + res = li_network_write_sendfile(fd, cq, &write_max, err);
58 62 #else
59   - res = li_network_write_writev(vr, fd, cq, &write_max);
  63 + res = li_network_write_writev(fd, cq, &write_max, err);
60 64 #endif
61 65
62 66 #ifdef TCP_CORK
@@ -69,7 +73,7 @@ liNetworkStatus li_network_write(liVRequest *vr, int fd, liChunkQueue *cq, goffs
69 73 return res;
70 74 }
71 75
72   -liNetworkStatus li_network_read(liVRequest *vr, int fd, liChunkQueue *cq, liBuffer **buffer) {
  76 +liNetworkStatus li_network_read(int fd, liChunkQueue *cq, liBuffer **buffer, GError **err) {
73 77 const ssize_t blocksize = 16*1024; /* 16k */
74 78 off_t max_read = 16 * blocksize; /* 256k */
75 79 ssize_t r;
@@ -79,8 +83,8 @@ liNetworkStatus li_network_read(liVRequest *vr, int fd, liChunkQueue *cq, liBuff
79 83 if (max_read > cq->limit->limit - cq->limit->current) {
80 84 max_read = cq->limit->limit - cq->limit->current;
81 85 if (max_read <= 0) {
82   - max_read = 0; /* we still have to read something */
83   - VR_ERROR(vr, "%s", "li_network_read: fd should be disabled as chunkqueue is already full");
  86 + g_set_error(err, LI_NETWORK_ERROR, 0, "li_network_read: fd should be disabled as chunkqueue is already full, aborting connection.");
  87 + return LI_NETWORK_STATUS_FATAL_ERROR;
84 88 }
85 89 }
86 90 }
@@ -137,7 +141,7 @@ liNetworkStatus li_network_read(liVRequest *vr, int fd, liChunkQueue *cq, liBuff
137 141 case ETIMEDOUT:
138 142 return LI_NETWORK_STATUS_CONNECTION_CLOSE;
139 143 default:
140   - VR_ERROR(vr, "oops, read from fd=%d failed: %s", fd, g_strerror(errno) );
  144 + g_set_error(err, LI_NETWORK_ERROR, 0, "li_network_read: oops, read from fd=%d failed: %s", fd, g_strerror(errno) );
141 145 return LI_NETWORK_STATUS_FATAL_ERROR;
142 146 }
143 147 } else if (0 == r) {
34 src/main/network_sendfile.c
@@ -11,11 +11,11 @@ typedef enum {
11 11 NSR_FATAL_ERROR
12 12 } network_sendfile_result;
13 13
14   -static network_sendfile_result lighty_sendfile(liVRequest *vr, int fd, int filefd, goffset offset, ssize_t len, ssize_t *wrote);
  14 +static network_sendfile_result lighty_sendfile(int fd, int filefd, goffset offset, ssize_t len, ssize_t *wrote, GError **err);
15 15
16 16 #if defined(USE_LINUX_SENDFILE)
17 17
18   -static network_sendfile_result lighty_sendfile(liVRequest *vr, int fd, int filefd, goffset offset, ssize_t len, ssize_t *wrote) {
  18 +static network_sendfile_result lighty_sendfile(int fd, int filefd, goffset offset, ssize_t len, ssize_t *wrote, GError **err) {
19 19 ssize_t r;
20 20 off_t file_offset = offset;
21 21
@@ -34,10 +34,9 @@ static network_sendfile_result lighty_sendfile(liVRequest *vr, int fd, int filef
34 34 break; /* try again */
35 35 case EINVAL:
36 36 case ENOSYS:
37   - /* TODO: print a warning? */
38 37 return NSR_FALLBACK;
39 38 default:
40   - VR_ERROR(vr, "oops, write to fd=%d failed: %s", fd, g_strerror(errno));
  39 + g_set_error(err, LI_NETWORK_ERROR, 0, "lighty_sendfile(linux): oops, write to fd=%d failed: %s", fd, g_strerror(errno));
41 40 return NSR_FATAL_ERROR;
42 41 }
43 42 }
@@ -47,7 +46,7 @@ static network_sendfile_result lighty_sendfile(liVRequest *vr, int fd, int filef
47 46
48 47 #elif defined(USE_FREEBSD_SENDFILE)
49 48
50   -static network_sendfile_result lighty_sendfile(liVRequest *vr, int fd, int filefd, goffset offset, ssize_t len, ssize_t *wrote) {
  49 +static network_sendfile_result lighty_sendfile(int fd, int filefd, goffset offset, ssize_t len, ssize_t *wrote, GError **err) {
51 50 off_t r = 0;
52 51
53 52 while (-1 == sendfile(filefd, fd, offset, len, NULL, &r, 0)) {
@@ -71,10 +70,9 @@ static network_sendfile_result lighty_sendfile(liVRequest *vr, int fd, int filef
71 70 case EINVAL:
72 71 case EOPNOTSUPP:
73 72 case ENOTSOCK:
74   - /* TODO: print a warning? */
75 73 return NSR_FALLBACK;
76 74 default:
77   - VR_ERROR(vr, "oops, write to fd=%d failed: %s", fd, g_strerror(errno));
  75 + g_set_error(err, LI_NETWORK_ERROR, 0, "lighty_sendfile(freebsd): oops, write to fd=%d failed: %s", fd, g_strerror(errno));
78 76 return NSR_FATAL_ERROR;
79 77 }
80 78 }
@@ -84,7 +82,7 @@ static network_sendfile_result lighty_sendfile(liVRequest *vr, int fd, int filef
84 82
85 83 #elif defined(USE_SOLARIS_SENDFILEV)
86 84
87   -static network_sendfile_result lighty_sendfile(liVRequest *vr, int fd, int filefd, goffset offset, ssize_t len, ssize_t *wrote) {
  85 +static network_sendfile_result lighty_sendfile(int fd, int filefd, goffset offset, ssize_t len, ssize_t *wrote, GError **err) {
88 86 sendfilevec_t fvec;
89 87
90 88 fvec.sfv_fd = filefd;
@@ -103,10 +101,9 @@ static network_sendfile_result lighty_sendfile(liVRequest *vr, int fd, int filef
103 101 break; /* try again */
104 102 case EAFNOSUPPORT:
105 103 case EPROTOTYPE:
106   - /* TODO: print a warning? */
107 104 return NSR_FALLBACK;
108 105 default:
109   - VR_ERROR(vr, "oops, write to fd=%d failed: %s", fd, g_strerror(errno));
  106 + g_set_error(err, LI_NETWORK_ERROR, 0, "lighty_sendfile(solaris): oops, write to fd=%d failed: %s", fd, g_strerror(errno));
110 107 return NSR_FATAL_ERROR;
111 108 }
112 109 }
@@ -115,7 +112,7 @@ static network_sendfile_result lighty_sendfile(liVRequest *vr, int fd, int filef
115 112
116 113 #elif defined(USE_OSX_SENDFILE)
117 114
118   -static network_sendfile_result lighty_sendfile(liVRequest *vr, int fd, int filefd, goffset offset, ssize_t len, ssize_t *wrote) {
  115 +static network_sendfile_result lighty_sendfile(int fd, int filefd, goffset offset, ssize_t len, ssize_t *wrote, GError **err) {
119 116 off_t bytes = len;
120 117
121 118 while (-1 == sendfile(filefd, fd, offset, &bytes, NULL, 0)) {
@@ -139,10 +136,9 @@ static network_sendfile_result lighty_sendfile(liVRequest *vr, int fd, int filef
139 136 case ENOTSUP:
140 137 case EOPNOTSUPP:
141 138 case ENOTSOCK:
142   - /* TODO: print a warning? */
143 139 return NSR_FALLBACK;
144 140 default:
145   - VR_ERROR(vr, "oops, write to fd=%d failed: %s", fd, g_strerror(errno));
  141 + g_set_error(err, LI_NETWORK_ERROR, 0, "lighty_sendfile(osx): oops, write to fd=%d failed: %s", fd, g_strerror(errno));
146 142 return NSR_FATAL_ERROR;
147 143 }
148 144 }
@@ -155,7 +151,7 @@ static network_sendfile_result lighty_sendfile(liVRequest *vr, int fd, int filef
155 151
156 152
157 153 /* first chunk must be a FILE_CHUNK ! */
158   -static liNetworkStatus network_backend_sendfile(liVRequest *vr, int fd, liChunkQueue *cq, goffset *write_max) {
  154 +static liNetworkStatus network_backend_sendfile(int fd, liChunkQueue *cq, goffset *write_max, GError **err) {
159 155 off_t file_offset, toSend;
160 156 ssize_t r;
161 157 gboolean did_write_something = FALSE;
@@ -171,7 +167,7 @@ static liNetworkStatus network_backend_sendfile(liVRequest *vr, int fd, liChunkQ
171 167 return did_write_something ? LI_NETWORK_STATUS_SUCCESS : LI_NETWORK_STATUS_FATAL_ERROR;
172 168 }
173 169
174   - switch (li_chunkfile_open(vr, c->data.file.file)) {
  170 + switch (li_chunkfile_open(c->data.file.file, err)) {
175 171 case LI_HANDLER_GO_ON:
176 172 break;
177 173 default:
@@ -183,7 +179,7 @@ static liNetworkStatus network_backend_sendfile(liVRequest *vr, int fd, liChunkQ
183 179 if (toSend > *write_max) toSend = *write_max;
184 180
185 181 r = 0;
186   - switch (lighty_sendfile(vr, fd, c->data.file.file->fd, file_offset, toSend, &r)) {
  182 + switch (lighty_sendfile(fd, c->data.file.file->fd, file_offset, toSend, &r, err)) {
187 183 case NSR_SUCCESS:
188 184 li_chunkqueue_skip(cq, r);
189 185 *write_max -= r;
@@ -202,13 +198,13 @@ static liNetworkStatus network_backend_sendfile(liVRequest *vr, int fd, liChunkQ
202 198 /* don't care about cached stat - file is open */
203 199 struct stat st;
204 200 if (-1 == fstat(fd, &st)) {
205   - VR_ERROR(vr, "Couldn't fstat file: %s", g_strerror(errno));
  201 + g_set_error(err, LI_NETWORK_ERROR, 0, "network_backend_sendfile: Couldn't fstat file: %s", g_strerror(errno));
206 202 return LI_NETWORK_STATUS_FATAL_ERROR;
207 203 }
208 204
209 205 if (file_offset > st.st_size) {
210 206 /* file shrinked, close the connection */
211   - VR_ERROR(vr, "%s", "File shrinked, aborting");
  207 + g_set_error(err, LI_NETWORK_ERROR, 0, "network_backend_sendfile: File shrinked, aborting");
212 208 return LI_NETWORK_STATUS_FATAL_ERROR;
213 209 }
214 210 return LI_NETWORK_STATUS_WAIT_FOR_EVENT;
@@ -222,7 +218,7 @@ static liNetworkStatus network_backend_sendfile(liVRequest *vr, int fd, liChunkQ
222 218 return LI_NETWORK_STATUS_SUCCESS;
223 219 }
224 220
225   -liNetworkStatus li_network_write_sendfile(liVRequest *vr, int fd, liChunkQueue *cq, goffset *write_max) {
  221 +liNetworkStatus li_network_write_sendfile(int fd, liChunkQueue *cq, goffset *write_max, GError **err) {
226 222 if (cq->length == 0) return LI_NETWORK_STATUS_FATAL_ERROR;
227 223
228 224 do {
6 src/main/network_write.c
... ... @@ -1,7 +1,7 @@
1 1
2 2 #include <lighttpd/base.h>
3 3
4   -liNetworkStatus li_network_backend_write(liVRequest *vr, int fd, liChunkQueue *cq, goffset *write_max) {
  4 +liNetworkStatus li_network_backend_write(int fd, liChunkQueue *cq, goffset *write_max, GError **err) {
5 5 const ssize_t blocksize = 16*1024; /* 16k */
6 6 char *block_data;
7 7 off_t block_len;
@@ -14,7 +14,7 @@ liNetworkStatus li_network_backend_write(liVRequest *vr, int fd, liChunkQueue *c
14 14 return did_write_something ? LI_NETWORK_STATUS_SUCCESS : LI_NETWORK_STATUS_FATAL_ERROR;
15 15
16 16 ci = li_chunkqueue_iter(cq);
17   - switch (li_chunkiter_read(vr, ci, 0, blocksize, &block_data, &block_len)) {
  17 + switch (li_chunkiter_read(ci, 0, blocksize, &block_data, &block_len, err)) {
18 18 case LI_HANDLER_GO_ON:
19 19 break;
20 20 case LI_HANDLER_ERROR:
@@ -34,7 +34,7 @@ liNetworkStatus li_network_backend_write(liVRequest *vr, int fd, liChunkQueue *c
34 34 case ETIMEDOUT:
35 35 return LI_NETWORK_STATUS_CONNECTION_CLOSE;
36 36 default:
37   - VR_ERROR(vr, "oops, write to fd=%d failed: %s", fd, g_strerror(errno));
  37 + g_set_error(err, LI_NETWORK_ERROR, 0, "li_network_backend_write: oops, write to fd=%d failed: %s", fd, g_strerror(errno));
38 38 return LI_NETWORK_STATUS_FATAL_ERROR;
39 39 }
40 40 } else if (0 == r) {
6 src/main/network_writev.c
@@ -25,7 +25,7 @@
25 25 #endif
26 26
27 27 /* first chunk must be a STRING_CHUNK ! */
28   -liNetworkStatus li_network_backend_writev(liVRequest *vr, int fd, liChunkQueue *cq, goffset *write_max) {
  28 +liNetworkStatus li_network_backend_writev(int fd, liChunkQueue *cq, goffset *write_max, GError **err) {
29 29 off_t we_have;
30 30 ssize_t r;
31 31 gboolean did_write_something = FALSE;
@@ -83,7 +83,7 @@ liNetworkStatus li_network_backend_writev(liVRequest *vr, int fd, liChunkQueue *
83 83 case EINTR:
84 84 break; /* try again */
85 85 default:
86   - VR_ERROR(vr, "oops, write to fd=%d failed: %s", fd, g_strerror(errno));
  86 + g_set_error(err, LI_NETWORK_ERROR, 0, "li_network_backend_writev: oops, write to fd=%d failed: %s", fd, g_strerror(errno));
87 87 goto cleanup;
88 88 }
89 89 }
@@ -115,7 +115,7 @@ liNetworkStatus li_network_backend_writev(liVRequest *vr, int fd, liChunkQueue *
115 115 return res;
116 116 }
117 117
118   -liNetworkStatus li_network_write_writev(liVRequest *vr, int fd, liChunkQueue *cq, goffset *write_max) {
  118 +liNetworkStatus li_network_write_writev(int fd, liChunkQueue *cq, goffset *write_max, GError **err) {
119 119 if (cq->length == 0) return LI_NETWORK_STATUS_FATAL_ERROR;
120 120 do {
121 121 switch (li_chunkqueue_first_chunk(cq)->type) {
10 src/modules/mod_cache_disk_etag.c
@@ -153,6 +153,7 @@ static liHandlerResult cache_etag_filter_miss(liVRequest *vr, liFilter *f) {
153 153 gchar *buf;
154 154 off_t buflen;
155 155 liChunkIter citer = li_chunkqueue_iter(f->in);
  156 + GError *err = NULL;
156 157 UNUSED(vr);
157 158
158 159 if (0 == f->in->length) return LI_HANDLER_GO_ON;
@@ -163,8 +164,13 @@ static liHandlerResult cache_etag_filter_miss(liVRequest *vr, liFilter *f) {
163 164 return LI_HANDLER_GO_ON;
164 165 }
165 166
166   - if (LI_HANDLER_GO_ON != li_chunkiter_read(vr, citer, 0, 64*1024, &buf, &buflen)) {
167   - VR_ERROR(vr, "%s", "Couldn't read data from chunkqueue");
  167 + if (LI_HANDLER_GO_ON != li_chunkiter_read(citer, 0, 64*1024, &buf, &buflen, &err)) {
  168 + if (NULL != err) {
  169 + VR_ERROR(vr, "Couldn't read data from chunkqueue: %s", err->message);
  170 + g_error_free(err);
  171 + } else {
  172 + VR_ERROR(vr, "%s", "Couldn't read data from chunkqueue");
  173 + }
168 174 cache_etag_file_free(cfile);
169 175 f->param = NULL;
170 176 li_chunkqueue_steal_all(f->out, f->in);
16 src/modules/mod_deflate.c
@@ -217,13 +217,19 @@ static liHandlerResult deflate_filter_zlib(liVRequest *vr, liFilter *f) {
217 217 char *data;
218 218 off_t len;
219 219 liChunkIter ci;
  220 + GError *err = NULL;
220 221
221 222 if (0 == f->in->length) break;
222 223
223 224 ci = li_chunkqueue_iter(f->in);
224 225
225   - if (LI_HANDLER_GO_ON != (res = li_chunkiter_read(vr, ci, 0, blocksize, &data, &len)))
  226 + if (LI_HANDLER_GO_ON != (res = li_chunkiter_read(ci, 0, blocksize, &data, &len, &err))) {
  227 + if (NULL != err) {
  228 + VR_ERROR(vr, "Couldn't read data from chunkqueue: %s", err->message);
  229 + g_error_free(err);
  230 + }
226 231 return res;
  232 + }
227 233
228 234 if (ctx->is_gzip) {
229 235 ctx->crc = crc32(ctx->crc, (unsigned char*) data, len);
@@ -406,13 +412,19 @@ static liHandlerResult deflate_filter_bzip2(liVRequest *vr, liFilter *f) {
406 412 char *data;
407 413 off_t len;
408 414 liChunkIter ci;
  415 + GError *err = NULL;
409 416
410 417 if (0 == f->in->length) break;
411 418
412 419 ci = li_chunkqueue_iter(f->in);
413 420
414   - if (LI_HANDLER_GO_ON != (res = li_chunkiter_read(vr, ci, 0, blocksize, &data, &len)))
  421 + if (LI_HANDLER_GO_ON != (res = li_chunkiter_read(ci, 0, blocksize, &data, &len, &err))) {
  422 + if (NULL != err) {
  423 + VR_ERROR(vr, "Couldn't read data from chunkqueue: %s", err->message);
  424 + g_error_free(err);
  425 + }
415 426 return res;
  427 + }
416 428
417 429 bz->next_in = data;
418 430 bz->avail_in = len;
24 src/modules/mod_fastcgi.c
@@ -479,7 +479,7 @@ static gboolean fastcgi_get_packet(fastcgi_connection *fcon) {
479 479 }
480 480 }
481 481
482   - if (!li_chunkqueue_extract_to_bytearr(fcon->vr, fcon->fcgi_in, FCGI_HEADER_LEN, fcon->buf_in_record)) return FALSE; /* need more data */
  482 + if (!li_chunkqueue_extract_to_bytearr(fcon->fcgi_in, FCGI_HEADER_LEN, fcon->buf_in_record, NULL)) return FALSE; /* need more data */
483 483
484 484 data = (const unsigned char*) fcon->buf_in_record->data;
485 485 fcon->fcgi_in_record.version = data[0];
@@ -531,7 +531,7 @@ static gboolean fastcgi_parse_response(fastcgi_connection *fcon) {
531 531 break;
532 532 case FCGI_STDERR:
533 533 len = fastcgi_available(fcon);
534   - li_chunkqueue_extract_to(vr, fcon->fcgi_in, len, vr->wrk->tmp_str);
  534 + li_chunkqueue_extract_to(fcon->fcgi_in, len, vr->wrk->tmp_str, NULL);
535 535 if (OPTION(FASTCGI_OPTION_LOG_PLAIN_ERRORS).boolean) {
536 536 li_log_split_lines(vr->wrk->srv, vr->wrk, li_log_vr_map(vr), LI_LOG_LEVEL_BACKEND, 0, vr->wrk->tmp_str->str, "");
537 537 } else {
@@ -567,11 +567,17 @@ static void fastcgi_fd_cb(struct ev_loop *loop, ev_io *w, int revents) {
567 567 if (fcon->fcgi_in->is_closed) {
568 568 li_ev_io_rem_events(loop, w, EV_READ);
569 569 } else {
570   - switch (li_network_read(fcon->vr, w->fd, fcon->fcgi_in, &fcon->fcgi_in_buffer)) {
  570 + GError *err = NULL;
  571 + switch (li_network_read(w->fd, fcon->fcgi_in, &fcon->fcgi_in_buffer, &err)) {
571 572 case LI_NETWORK_STATUS_SUCCESS:
572 573 break;
573 574 case LI_NETWORK_STATUS_FATAL_ERROR:
574   - VR_ERROR(fcon->vr, "(%s) network read fatal error", fcon->ctx->socket_str->str);
  575 + if (NULL != err) {
  576 + VR_ERROR(fcon->vr, "(%s) network read fatal error: %s", fcon->ctx->socket_str->str, err->message);
  577 + g_error_free(err);
  578 + } else {
  579 + VR_ERROR(fcon->vr, "(%s) network read fatal error", fcon->ctx->socket_str->str);
  580 + }
575 581 li_vrequest_error(fcon->vr);
576 582 return;
577 583 case LI_NETWORK_STATUS_CONNECTION_CLOSE:
@@ -589,11 +595,17 @@ static void fastcgi_fd_cb(struct ev_loop *loop, ev_io *w, int revents) {
589 595
590 596 if (fcon->fd != -1 && (revents & EV_WRITE)) {
591 597 if (fcon->fcgi_out->length > 0) {
592   - switch (li_network_write(fcon->vr, w->fd, fcon->fcgi_out, 256*1024)) {
  598 + GError *err = NULL;
  599 + switch (li_network_write(w->fd, fcon->fcgi_out, 256*1024, &err)) {
593 600 case LI_NETWORK_STATUS_SUCCESS:
594 601 break;
595 602 case LI_NETWORK_STATUS_FATAL_ERROR:
596   - VR_ERROR(fcon->vr, "(%s) network write fatal error", fcon->ctx->socket_str->str);
  603 + if (NULL != err) {
  604 + VR_ERROR(fcon->vr, "(%s) network write fatal error: %s", fcon->ctx->socket_str->str, err->message);
  605 + g_error_free(err);
  606 + } else {
  607 + VR_ERROR(fcon->vr, "(%s) network write fatal error", fcon->ctx->socket_str->str);
  608 + }
597 609 li_vrequest_error(fcon->vr);
598 610 return;
599 611 case LI_NETWORK_STATUS_CONNECTION_CLOSE:
10 src/modules/mod_gnutls.c
@@ -272,6 +272,7 @@ static liNetworkStatus mod_gnutls_con_write(liConnection *con, goffset write_max
272 272 liChunkIter ci;
273 273 liChunkQueue *cq = con->raw_out;
274 274 mod_connection_ctx *conctx = con->srv_sock_data;
  275 + GError *err = NULL;
275 276
276 277 if (!conctx->initial_handshaked_finished) {
277 278 liNetworkStatus res = mod_gnutls_do_handshake(con, conctx);
@@ -279,14 +280,19 @@ static liNetworkStatus mod_gnutls_con_write(liConnection *con, goffset write_max
279 280 }
280 281
281 282 do {
282   - if (0 == cq->length)
  283 + if (0 == cq->length) {
283 284 return LI_NETWORK_STATUS_SUCCESS;
  285 + }
284 286
285 287 ci = li_chunkqueue_iter(cq);
286   - switch (li_chunkiter_read(con->mainvr, ci, 0, blocksize, &block_data, &block_len)) {
  288 + switch (li_chunkiter_read(ci, 0, blocksize, &block_data, &block_len, &err)) {
287 289 case LI_HANDLER_GO_ON:
288 290 break;
289 291 case LI_HANDLER_ERROR:
  292 + if (NULL != err) {
  293 + VR_ERROR(con->mainvr, "Couldn't read data from chunkqueue: %s", err->message);
  294 + g_error_free(err);
  295 + }
290 296 default:
291 297 return LI_NETWORK_STATUS_FATAL_ERROR;
292 298 }
8 src/modules/mod_memcached.c
@@ -451,13 +451,19 @@ static liHandlerResult memcache_store_filter(liVRequest *vr, liFilter *f) {
451 451 off_t len;
452 452 liChunkIter ci;
453 453 liHandlerResult res;
  454 + GError *err = NULL;
454 455
455 456 if (0 == f->in->length) break;
456 457
457 458 ci = li_chunkqueue_iter(f->in);
458 459
459   - if (LI_HANDLER_GO_ON != (res = li_chunkiter_read(vr, ci, 0, 16*1024, &data, &len)))
  460 + if (LI_HANDLER_GO_ON != (res = li_chunkiter_read(ci, 0, 16*1024, &data, &len, &err))) {
  461 + if (NULL != err) {
  462 + VR_ERROR(vr, "Couldn't read data from chunkqueue: %s", err->message);
  463 + g_error_free(err);
  464 + }
460 465 return res;
  466 + }
461 467
462 468 if ((gssize) (len + mf->buf->used) > (gssize) mf->ctx->maxsize) {
463 469 /* response too big, switch to "forward" mode */
11 src/modules/mod_openssl.c
@@ -293,14 +293,21 @@ static liNetworkStatus openssl_con_write(liConnection *con, goffset write_max) {
293 293 }
294 294
295 295 do {
296   - if (0 == cq->length)
  296 + GError *err = NULL;
  297 +
  298 + if (0 == cq->length) {
297 299 return LI_NETWORK_STATUS_SUCCESS;
  300 + }
298 301
299 302 ci = li_chunkqueue_iter(cq);
300   - switch (li_chunkiter_read(con->mainvr, ci, 0, blocksize, &block_data, &block_len)) {
  303 + switch (li_chunkiter_read(ci, 0, blocksize, &block_data, &block_len, &err)) {
301 304 case LI_HANDLER_GO_ON:
302 305 break;
303 306 case LI_HANDLER_ERROR:
  307 + if (NULL != err) {
  308 + VR_ERROR(con->mainvr, "Couldn't read data from chunkqueue: %s", err->message);
  309 + g_error_free(err);
  310 + }
304 311 default:
305 312 return LI_NETWORK_STATUS_FATAL_ERROR;
306 313 }
20 src/modules/mod_proxy.c
@@ -228,11 +228,17 @@ static void proxy_fd_cb(struct ev_loop *loop, ev_io *w, int revents) {
228 228 if (pcon->proxy_in->is_closed) {
229 229 li_ev_io_rem_events(loop, w, EV_READ);
230 230 } else {
231   - switch (li_network_read(pcon->vr, w->fd, pcon->proxy_in, &pcon->proxy_in_buffer)) {
  231 + GError *err = NULL;
  232 + switch (li_network_read(w->fd, pcon->proxy_in, &pcon->proxy_in_buffer, &err)) {
232 233 case LI_NETWORK_STATUS_SUCCESS:
233 234 break;
234 235 case LI_NETWORK_STATUS_FATAL_ERROR:
235   - VR_ERROR(pcon->vr, "(%s) network read fatal error", pcon->ctx->socket_str->str);
  236 + if (NULL != err) {
  237 + VR_ERROR(pcon->vr, "(%s) network read fatal error: %s", pcon->ctx->socket_str->str, err->message);
  238 + g_error_free(err);
  239 + } else {
  240 + VR_ERROR(pcon->vr, "(%s) network read fatal error", pcon->ctx->socket_str->str);
  241 + }
236 242 li_vrequest_error(pcon->vr);
237 243 return;
238 244 case LI_NETWORK_STATUS_CONNECTION_CLOSE:
@@ -250,11 +256,17 @@ static void proxy_fd_cb(struct ev_loop *loop, ev_io *w, int revents) {
250 256
251 257 if (pcon->fd != -1 && (revents & EV_WRITE)) {
252 258 if (pcon->proxy_out->length > 0) {
253   - switch (li_network_write(pcon->vr, w->fd, pcon->proxy_out, 256*1024)) {
  259 + GError *err = NULL;
  260 + switch (li_network_write(w->fd, pcon->proxy_out, 256*1024, &err)) {
254 261 case LI_NETWORK_STATUS_SUCCESS:
255 262 break;
256 263 case LI_NETWORK_STATUS_FATAL_ERROR:
257   - VR_ERROR(pcon->vr, "(%s) network write fatal error", pcon->ctx->socket_str->str);
  264 + if (NULL != err) {
  265 + VR_ERROR(pcon->vr, "(%s) network write fatal error: %s", pcon->ctx->socket_str->str, err->message);
  266 + g_error_free(err);
  267 + } else {
  268 + VR_ERROR(pcon->vr, "(%s) network write fatal error", pcon->ctx->socket_str->str);
  269 + }
258 270 li_vrequest_error(pcon->vr);
259 271 return;
260 272 case LI_NETWORK_STATUS_CONNECTION_CLOSE:
20 src/modules/mod_scgi.c
@@ -331,11 +331,17 @@ static void scgi_fd_cb(struct ev_loop *loop, ev_io *w, int revents) {
331 331 if (scon->scgi_in->is_closed) {
332 332 li_ev_io_rem_events(loop, w, EV_READ);
333 333 } else {
334   - switch (li_network_read(scon->vr, w->fd, scon->scgi_in, &scon->scgi_in_buffer)) {
  334 + GError *err = NULL;
  335 + switch (li_network_read(w->fd, scon->scgi_in, &scon->scgi_in_buffer, &err)) {
335 336 case LI_NETWORK_STATUS_SUCCESS:
336 337 break;
337 338 case LI_NETWORK_STATUS_FATAL_ERROR:
338   - VR_ERROR(scon->vr, "(%s) network read fatal error", scon->ctx->socket_str->str);
  339 + if (NULL != err) {
  340 + VR_ERROR(scon->vr, "(%s) network read fatal error: %s", scon->ctx->socket_str->str, err->message);
  341 + g_error_free(err);
  342 + } else {
  343 + VR_ERROR(scon->vr, "(%s) network read fatal error", scon->ctx->socket_str->str);
  344 + }
339 345 li_vrequest_error(scon->vr);
340 346 return;
341 347 case LI_NETWORK_STATUS_CONNECTION_CLOSE:
@@ -353,11 +359,17 @@ static void scgi_fd_cb(struct ev_loop *loop, ev_io *w, int revents) {
353 359
354 360 if (scon->fd != -1 && (revents & EV_WRITE)) {
355 361 if (scon->scgi_out->length > 0) {
356   - switch (li_network_write(scon->vr, w->fd, scon->scgi_out, 256*1024)) {
  362 + GError *err = NULL;
  363 + switch (li_network_write(w->fd, scon->scgi_out, 256*1024, &err)) {
357 364 case LI_NETWORK_STATUS_SUCCESS:
358 365 break;
359 366 case LI_NETWORK_STATUS_FATAL_ERROR:
360   - VR_ERROR(scon->vr, "(%s) network write fatal error", scon->ctx->socket_str->str);
  367 + if (NULL != err) {
  368 + VR_ERROR(scon->vr, "(%s) network write fatal error: %s", scon->ctx->socket_str->str, err->message);
  369 + g_error_free(err);
  370 + } else {
  371 + VR_ERROR(scon->vr, "(%s) network write fatal error", scon->ctx->socket_str->str);
  372 + }
361 373 li_vrequest_error(scon->vr);
362 374 return;
363 375 case LI_NETWORK_STATUS_CONNECTION_CLOSE:
2  src/unittests/test-chunk.c
@@ -18,7 +18,7 @@ static void cq_load_str(liChunkQueue *cq, const gchar *s, size_t len) {
18 18
19 19 static void cq_assert_eq(liChunkQueue *cq, const gchar *s, size_t len) {
20 20 GString *buf = g_string_sized_new(cq->length);
21   - g_assert(li_chunkqueue_extract_to(NULL, cq, cq->length, buf));
  21 + g_assert(li_chunkqueue_extract_to(cq, cq->length, buf, NULL));
22 22 g_assert(0 == memcmp(s, buf->str, len));
23 23 g_string_free(buf, TRUE);
24 24 }

0 comments on commit b1c45e6

Please sign in to comment.
Something went wrong with that request. Please try again.