Philip Martin <phi...@codematters.co.uk> writes: > Philip Martin <philip.mar...@wandisco.com> writes: > >> handle_fetch (request=0x7ffff3e56038, response=0x7ffff3e918b8, >> handler_baton=0x7ffff3e611e0, pool=0x7ffff3e6d028) >> at ../src/subversion/libsvn_ra_serf/update.c:1152 >> 1152 if (SERF_BUCKET_READ_ERROR(status)) >> (gdb) p status >> $13 = 0 > > So that's what happens when I interrupt the infinite loop, i.e. long > after the first failure to read from the socket. If I catch the first > socket read error then serf does supply an error to ra_serf:
I can reproduce over plain HTTP without mod_ssl - - the closed socket causes apr_socket_recv() to returns APR_EOF - APR_EOF gets returned to serf_deflate_read() - APR_EOF gets stored in deflate_context_t->stream_status - serf_deflate_read() returns APR_SUCCESS - serf_response_read() returns APR_SUCCESS The ra_serf infinite loop is calling serf_response_read() which calls serf_deflate_read() which keeps converting APR_EOF into APR_SUCCESS: serf_deflate_read (bucket=0x7ffff3e8f4b8, requested=8000, data=0x7fffffffd460, len=0x7fffffffd458) at buckets/deflate_buckets.c:143 143 deflate_context_t *ctx = bucket->data; (gdb) n 150 switch (ctx->state) { (gdb) p ctx->stream_status $24 = 70014 (gdb) n 224 status = serf_bucket_read(ctx->inflate_stream, requested, data, (gdb) 226 if (SERF_BUCKET_READ_ERROR(status)) { (gdb) 230 if (APR_STATUS_IS_EOF(status)) { (gdb) 231 status = ctx->stream_status; (gdb) 232 if (APR_STATUS_IS_EOF(status)) { (gdb) 237 status = APR_SUCCESS; (gdb) 240 if (*len != 0) { (gdb) 251 if (ctx->zstream.avail_in == 0) { (gdb) 255 ctx->stream_status = serf_bucket_read(ctx->stream, (gdb) 260 if (SERF_BUCKET_READ_ERROR(ctx->stream_status)) { (gdb) 264 if (!private_len && APR_STATUS_IS_EAGAIN(ctx->stream_status)) { (gdb) 271 ctx->zstream.next_in = (unsigned char*)private_data; (gdb) 272 ctx->zstream.avail_in = private_len; (gdb) 277 zRC = inflate(&ctx->zstream, Z_NO_FLUSH); (gdb) 281 if (zRC == Z_BUF_ERROR || ctx->zstream.avail_out == 0) { (gdb) 283 ctx->zstream.next_out = ctx->buffer; (gdb) 284 private_len = ctx->bufferSize - ctx->zstream.avail_out; (gdb) 286 ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, (gdb) 290 tmp = SERF_BUCKET_SIMPLE_STRING_LEN((char *)ctx->buffer, (gdb) 293 serf_bucket_aggregate_append(ctx->inflate_stream, tmp); (gdb) 294 ctx->zstream.avail_out = ctx->bufferSize; (gdb) 295 break; (gdb) 352 status = serf_bucket_read(ctx->inflate_stream, requested, data, (gdb) 355 if (APR_STATUS_IS_EOF(status)) { (gdb) p status $25 = 70014 (gdb) n 356 status = ctx->stream_status; (gdb) 359 if (zRC != Z_STREAM_END) (gdb) 360 return APR_SUCCESS; -- Philip Martin | Subversion Committer WANdisco // *Non-Stop Data* serf