/* Do output back to the browser in the background. This is a socket write handler. This bypasses the output buffer and writes directly to the socket. */ static void fileWriteEvent(Webs *wp) { char *buf; ssize len, wrote; assert(wp); assert(websValid(wp)); /* Note: websWriteSocket may return less than we wanted. It will return -1 on a socket error. */ if ((buf = walloc(ME_GOAHEAD_LIMIT_BUFFER)) == NULL) { websError(wp, HTTP_CODE_INTERNAL_SERVER_ERROR, "Cannot get memory"); return; } /* OPT - we could potentially save this buffer so that on short-writes, it does not need to be re-read. */ while ((len = websPageReadData(wp, buf, ME_GOAHEAD_LIMIT_BUFFER)) > 0) { if ((wrote = websWriteSocket(wp, buf, len)) < 0) { break; } if (wrote != len) { websPageSeek(wp, - (len - wrote), SEEK_CUR); break; } } wfree(buf); if (len <= 0) { websDone(wp); } }
static void websDefaultWriteEvent(webs_t wp) { int len, wrote, flags, bytes, written; char *buf; a_assert(websValid(wp)); flags = websGetRequestFlags(wp); websSetTimeMark(wp); wrote = bytes = 0; written = websGetRequestWritten(wp); /* * We only do this for non-ASP documents */ if ( !(flags & WEBS_ASP)) { bytes = websGetRequestBytes(wp); /* * Note: websWriteDataNonBlock may return less than we wanted. It will * return -1 on a socket error */ if ((buf = balloc(B_L, PAGE_READ_BUFSIZE)) == NULL) { websError(wp, 200, T("Can't get memory")); } else { while ((len = websPageReadData(wp, buf, PAGE_READ_BUFSIZE)) > 0) { if ((wrote = websWriteDataNonBlock(wp, buf, len)) < 0) { break; } written += wrote; if (wrote != len) { websPageSeek(wp, - (len - wrote)); break; } } /* * Safety. If we are at EOF, we must be done */ if (len == 0) { a_assert(written >= bytes); written = bytes; } bfree(B_L, buf); } } /* * We're done if an error, or all bytes output */ websSetRequestWritten(wp, written); if (wrote < 0 || written >= bytes) { websDone(wp, 200); } }