void RpcClientImpl::onOutput(StreamBuffer& sb) { try { _exceptionPending = false; sb.endWrite(); if (sb.out_avail() > 0) sb.beginWrite(); else sb.beginRead(); } catch (const std::exception&) { IRemoteProcedure* proc = _proc; cancel(); if (!proc) throw; _exceptionPending = true; proc->onFinished(); if (_exceptionPending) throw; } }
bool Socket::onOutput(StreamBuffer& sb) { log_trace("onOutput"); log_debug("send data to " << getPeerAddr()); try { sb.endWrite(); if ( sb.out_avail() ) { sb.beginWrite(); } else { if (sb.in_avail()) onInput(sb); else sb.beginRead(); } } catch (const std::exception& e) { log_warn("exception occured when processing request: " << e.what()); close(); return false; } return true; }
void Socket::onInput(StreamBuffer& sb) { log_debug("onInput"); sb.endRead(); if (sb.in_avail() == 0 || sb.device()->eof()) { close(); return; } while (sb.in_avail() > 0) { if (_responder.advance(sb.sbumpc())) { _responder.finalize(_stream); buffer().beginWrite(); onOutput(sb); return; } } sb.beginRead(); }
void ClientImpl::onOutput(StreamBuffer& sb) { log_trace("ClientImpl::onOutput; out_avail=" << sb.out_avail()); try { try { _errorPending = false; sb.endWrite(); if( sb.out_avail() > 0 ) { sb.beginWrite(); } else { sb.beginRead(); _client->requestSent(*_client); _parser.reset(true); _readHeader = true; } } catch (const IOError& e) { if (_reconnectOnError && _request != 0) { log_debug("reconnect on error"); _socket.close(); _reconnectOnError = false; reexecuteBegin(*_request); return; } throw; } } catch (const std::exception& e) { log_warn("error of type " << typeid(e).name() << " occured: " << e.what()); _errorPending = true; _client->replyFinished(*_client); if (_errorPending) throw; } }
void RpcClientImpl::onInput(StreamBuffer& sb) { try { _exceptionPending = false; sb.endRead(); if (sb.device()->eof()) throw IOError("end of input"); while (_stream.buffer().in_avail()) { char ch = StreamBuffer::traits_type::to_char_type(_stream.buffer().sbumpc()); if (_scanner.advance(ch)) { _scanner.finish(); IRemoteProcedure* proc = _proc; _proc = 0; proc->onFinished(); return; } } if (!_stream) { close(); throw std::runtime_error("reading result failed"); } sb.beginRead(); } catch (const std::exception&) { IRemoteProcedure* proc = _proc; cancel(); if (!proc) throw; _exceptionPending = true; proc->onFinished(); if (_exceptionPending) throw; } }
void Socket::onInput(StreamBuffer& sb) { log_debug("onInput"); sb.endRead(); if (sb.in_avail() == 0 || sb.device()->eof()) { close(); return; } if (_responder.onInput(_stream)) { sb.beginWrite(); onOutput(sb); } else { sb.beginRead(); } }
void ClientImpl::processBodyAvailable(StreamBuffer& sb) { log_trace("processBodyAvailable"); if (_chunkedEncoding) { if (_chunkedIStream.rdbuf()->in_avail() > 0) { if (!_chunkedIStream.eod()) { log_debug("read chunked encoding body"); while (_chunkedIStream.good() && _chunkedIStream.rdbuf()->in_avail() > 0 && !_chunkedIStream.eod()) { log_debug("bodyAvailable"); _client->bodyAvailable(*_client); } log_debug("in_avail=" << _chunkedIStream.rdbuf()->in_avail() << " eod=" << _chunkedIStream.eod()); if (_chunkedIStream.eod()) { _parser.readHeader(); } } if (_chunkedIStream.eod() && sb.in_avail() > 0) { log_debug("read chunked encoding post headers"); _parser.advance(sb); if (_parser.fail()) throw std::runtime_error("http parser failed"); // TODO define exception class if( _parser.end() ) { log_debug("reply finished"); if (!_replyHeader.keepAlive()) { log_debug("close socket - no keep alive"); _socket.close(); } _client->replyFinished(*_client); } } if (_chunkedIStream.fail()) throw IOError("error reading HTTP reply body"); } else if( _chunkedIStream.eod() ) { if( _replyHeader.hasHeader("Trailer") ) _parser.readHeader(); else _client->replyFinished(*_client); } if (_socket.enabled()) { if ((!_chunkedIStream.eod() || !_parser.end())) { log_debug("call beginRead"); sb.beginRead(); } } else { cancel(); } } else { log_debug("content-length(pre)=" << _contentLength); while (_stream.good() && _contentLength > 0 && sb.in_avail() > 0) { _contentLength -= _client->bodyAvailable(*_client); // TODO: may throw exception log_debug("content-length(post)=" << _contentLength); } if (_stream.fail()) throw IOError("error reading HTTP reply body"); if( _contentLength <= 0 ) { log_debug("reply finished"); if (!_replyHeader.keepAlive()) { log_debug("close socket - no keep alive"); _socket.close(); } _client->replyFinished(*_client); } else if (_socket.enabled() && _stream.good()) { sb.beginRead(); } else { cancel(); } } }
void ClientImpl::processHeaderAvailable(StreamBuffer& sb) { _parser.advance(sb); if (_parser.fail()) throw std::runtime_error("http parser failed"); // TODO define exception class if( _parser.end() ) { _chunkedEncoding = _replyHeader.chunkedTransferEncoding(); _client->headerReceived(*_client); _readHeader = false; if (_chunkedEncoding) { log_debug("chunked transfer encoding used"); _chunkedIStream.reset(); if( sb.in_avail() > 0 ) { processBodyAvailable(sb); } else { sb.beginRead(); } } else { _contentLength = _replyHeader.contentLength(); log_debug("header received - content-length=" << _contentLength); if (_contentLength > 0) { if( sb.in_avail() > 0 ) { processBodyAvailable(sb); } else { sb.beginRead(); } } else { if (!_replyHeader.keepAlive()) { log_debug("close socket - no keep alive"); _socket.close(); } _client->replyFinished(*_client); } } } else { sb.beginRead(); } }
void Socket::onInput(StreamBuffer& sb) { log_debug("onInput"); sb.endRead(); if (sb.in_avail() == 0 || sb.device()->eof()) { close(); return; } _timer.start(_server.readTimeout()); if ( _responder == 0 ) { _parser.advance(sb); if (_parser.fail()) { _responder = _server.getDefaultResponder(_request); _responder->replyError(_reply.body(), _request, _reply, std::runtime_error("invalid http header")); _responder->release(); _responder = 0; sendReply(); onOutput(sb); return; } if (_parser.end()) { log_info("request " << _request.method() << ' ' << _request.header().query() << " from client " << getPeerAddr()); _responder = _server.getResponder(_request); try { _responder->beginRequest(_stream, _request); } catch (const std::exception& e) { _reply.setHeader("Connection", "close"); _responder->replyError(_reply.body(), _request, _reply, e); _responder->release(); _responder = 0; sendReply(); onOutput(sb); return; } _contentLength = _request.header().contentLength(); log_debug("content length of request is " << _contentLength); if (_contentLength == 0) { _timer.stop(); doReply(); return; } } else { sb.beginRead(); } } if (_responder) { if (sb.in_avail() > 0) { try { std::size_t s = _responder->readBody(_stream); assert(s > 0); _contentLength -= s; } catch (const std::exception& e) { _reply.setHeader("Connection", "close"); _responder->replyError(_reply.body(), _request, _reply, e); _responder->release(); _responder = 0; sendReply(); onOutput(sb); return; } } if (_contentLength <= 0) { _timer.stop(); doReply(); } else { sb.beginRead(); } } }