TError TClient::ReadRequest(rpc::TContainerRequest &request) { TScopedLock lock(Mutex); if (Processing) { L_WRN() << "Client request before response: " << *this << std::endl; return TError::Success(); } if (Fd < 0) return TError(EError::Unknown, "Connection closed"); if (Offset >= Buffer.size()) Buffer.resize(Offset + 4096); ssize_t len = recv(Fd, &Buffer[Offset], Buffer.size() - Offset, MSG_DONTWAIT); if (len > 0) Offset += len; else if (len == 0) return TError(EError::Unknown, "recv return zero"); else if (errno != EAGAIN && errno != EWOULDBLOCK) return TError(EError::Unknown, errno, "recv request failed"); if (Length && Offset < Length) return TError::Queued(); google::protobuf::io::CodedInputStream input(&Buffer[0], Offset); uint32_t length; if (!input.ReadVarint32(&length)) return TError::Queued(); if (!Length) { if (length > config().daemon().max_msg_len()) return TError(EError::Unknown, "oversized request: " + std::to_string(length)); Length = length + google::protobuf::io::CodedOutputStream::VarintSize32(length); if (Buffer.size() < Length) Buffer.resize(Length + 4096); if (Offset < Length) return TError::Queued(); } if (!request.ParseFromCodedStream(&input)) return TError(EError::Unknown, "cannot parse request"); if (Offset > Length) return TError(EError::Unknown, "garbage after request"); Processing = true; return EpollLoop->StopInput(Fd); }
TError TClient::ReadRequest(rpc::TContainerRequest &request) { if (config().daemon().blocking_read()) { InterruptibleInputStream InputStream(Fd); ReadDelimitedFrom(&InputStream, &request); return TError::Success(); } if (Offset >= Buffer.size()) Buffer.resize(Offset + 4096); ssize_t len = recv(Fd, &Buffer[Offset], Buffer.size() - Offset, MSG_DONTWAIT); if (len > 0) Offset += len; else if (len == 0 || (errno != EAGAIN && errno != EWOULDBLOCK)) return TError(EError::Unknown, len ? errno : EIO, "recv request failed"); if (Length && Offset < Length) return TError::Queued(); google::protobuf::io::CodedInputStream input(&Buffer[0], Offset); uint32_t length; if (!input.ReadVarint32(&length)) return TError::Queued(); if (!Length) { if (length > config().daemon().max_msg_len()) return TError(EError::Unknown, "oversized request: " + std::to_string(length)); Length = length + google::protobuf::io::CodedOutputStream::VarintSize32(length); if (Buffer.size() < Length) Buffer.resize(Length); if (Offset < Length) return TError::Queued(); } if (!request.ParseFromCodedStream(&input)) return TError(EError::Unknown, "cannot parse request"); if (Offset > Length) return TError(EError::Unknown, "garbage after request"); return EpollLoop->StopInput(Fd); }