void Response::_writeCB(int r) { if (r <= 0) closed = true; _writing = false; if (_doWrite) flush(); else if (flushCB) flushCB(*this); }
void Response::flush(bool finalize) { //printf("flush\n"); if (closed) throw runtime_error("connection has already been closed by the client"); if (_writing) { _doWrite = true; return; } _doWrite = false; _writing = true; if (finalize && sendChunked) output.write("\r\n0\r\n"); output.flush(); if (!headersWritten) { headersWritten = true; int bufferL = buffer.length(); if (!sendChunked) { char* tmps = sp->beginAdd(16); int l = itoa(buffer.length(), tmps); sp->endAdd(l); this->headers.insert( { "Content-Length", { tmps, l } }); } else { output.write("\r\n"); output.flush(); } { CP::StreamWriter sw(buffer); Response_doWriteHeaders(this, sw); } iov[0]= {buffer.data()+bufferL, (size_t)(buffer.length()-bufferL)}; if (sendChunked) { int l2 = buffer.length(); output.writeF("%x\r\n", finalize ? bufferL - 5 : bufferL); output.flush(); iov[1]= {buffer.data()+l2,size_t(buffer.length()-l2)}; iov[2]= {buffer.data(),(size_t)(bufferL+2)}; outputStream->writevAll(iov, 3, { &Response::_writeCB, this }); } else { iov[1]= {buffer.data(), (size_t)bufferL}; outputStream->writevAll(iov, 2, {&Response::_writeCB, this}); } _bufferPos = buffer.length(); return; } else { if (_bufferPos >= buffer.length()) { _writing = false; if (flushCB) flushCB(*this); return; } if (sendChunked) { int _len = buffer.length(); int l = _len - _bufferPos; output.writeF("\r\n%x\r\n", finalize ? l - 5 : l); output.flush(); iov[0]= {buffer.data()+_len+2,size_t(buffer.length()-_len-2)}; iov[1]= {buffer.data() + _bufferPos,(size_t)(l+2)}; _bufferPos = buffer.length(); outputStream->writevAll(iov, 2, { &Response::_writeCB, this }); } } }
void initCB(struct CircularBuffer* cb, uint8_t* buffer, uint8_t size) { cb->buffer = buffer; cb->size = size; cb->front = 0; flushCB(cb); }
void Page::_flushCB(Response& r) { flushCB(); }