1
0
Fork 0

Fix SimpleHttpClient for the n+1 time.

Still with debugging output.
This commit is contained in:
Max Neunhoeffer 2014-12-03 23:31:20 +01:00
parent e4b51f616c
commit 0fb6ef1968
8 changed files with 55 additions and 31 deletions

View File

@ -174,6 +174,7 @@ bool ClientConnection::prepare (const double timeout, const bool isWrite) const
int sockn = (int) (TRI_get_fd_or_handle_of_socket(_socket) + 1);
int res = select(sockn, readFds, writeFds, NULL, &tv);
std::cout << "select: " << res << " " << errno << std::endl;
if (res > 0) {
return true;
@ -233,14 +234,17 @@ bool ClientConnection::writeClientConnection (void* buffer, size_t length, size_
/// @brief read data from the connection
////////////////////////////////////////////////////////////////////////////////
bool ClientConnection::readClientConnection (StringBuffer& stringBuffer, bool& progress) {
bool ClientConnection::readClientConnection (StringBuffer& stringBuffer,
bool& connectionClosed) {
if (! checkSocket()) {
std::cout << "checkSocket was false\n";
connectionClosed = true;
return false;
}
TRI_ASSERT(TRI_isvalidsocket(_socket));
progress = false;
connectionClosed = false;
do {
@ -256,15 +260,17 @@ bool ClientConnection::readClientConnection (StringBuffer& stringBuffer, bool& p
if (lenRead == -1) {
// error occurred
std::cout << "An error occurred!" << std::endl;
connectionClosed = true;
return false;
}
if (lenRead == 0) {
std::cout << "length 0 received!" << std::endl;
connectionClosed = true;
disconnect();
return true;
}
progress = true;
stringBuffer.increaseLength(lenRead);
}
while (readable());

View File

@ -118,7 +118,8 @@ namespace triagens {
/// @brief read data from the connection
////////////////////////////////////////////////////////////////////////////////
bool readClientConnection (triagens::basics::StringBuffer&, bool& progress);
bool readClientConnection (triagens::basics::StringBuffer&,
bool& connectionClosed);
////////////////////////////////////////////////////////////////////////////////
/// @brief return whether the connection is readable

View File

@ -137,7 +137,7 @@ void GeneralClientConnection::disconnect () {
/// (regardless of whether there was an error or not). The return value
/// indicates, whether an error has happened. Note that the other side
/// closing the connection is not considered to be an error! The call to
/// prepare() does a select and the call to readClientCollection does
/// prepare() does a select and the call to readClientConnection does
/// what is described here.
////////////////////////////////////////////////////////////////////////////////
@ -156,9 +156,9 @@ bool GeneralClientConnection::handleWrite (const double timeout, void* buffer, s
/// Read data from endpoint, this uses select to block until some
/// data has arrived. Then it reads as much as it can without further
/// blocking, using select multiple times. What has happened is
/// indicated by two flags, the return value and the progress flag,
/// which is always set by this method. The progress flag indicates
/// whether or not at least one byte has been appended to the buffer
/// indicated by two flags, the return value and the connectionClosed flag,
/// which is always set by this method. The connectionClosed flag indicates
/// whether or not the connection has been closed by the other side
/// (regardless of whether there was an error or not). The return value
/// indicates, whether an error has happened. Note that the other side
/// closing the connection is not considered to be an error! The call to
@ -166,13 +166,14 @@ bool GeneralClientConnection::handleWrite (const double timeout, void* buffer, s
/// what is described here.
////////////////////////////////////////////////////////////////////////////////
bool GeneralClientConnection::handleRead (double timeout, StringBuffer& buffer, bool& progress) {
progress = false;
bool GeneralClientConnection::handleRead (double timeout, StringBuffer& buffer, bool& connectionClosed) {
connectionClosed = false;
if (prepare(timeout, false)) {
return this->readClientConnection(buffer, progress);
return this->readClientConnection(buffer, connectionClosed);
}
connectionClosed = true;
return false;
}

View File

@ -164,7 +164,8 @@ namespace triagens {
/// @brief read data from endpoint
////////////////////////////////////////////////////////////////////////////////
bool handleRead (double, triagens::basics::StringBuffer&, bool& progress);
bool handleRead (double, triagens::basics::StringBuffer&,
bool& connectionClosed);
// -----------------------------------------------------------------------------
// --SECTION-- protected virtual methods

View File

@ -148,7 +148,7 @@ namespace triagens {
// but the following read runs into an error. In that case we try
// to reconnect one and then give up if this does not work.
std::cout << "Simple: Main loop, state " << _state << " remaining time "
<< remainingTime << std::endl;
<< remainingTime << " code:" << _result->getHttpReturnCode() << std::endl;
switch (_state) {
case (IN_CONNECT): {
handleConnect();
@ -173,7 +173,7 @@ namespace triagens {
setErrorMessage(TRI_last_error(), false);
}
this->close(); // this sets _state to IN_CONNECT for a retry
this->close(); // this sets _state to IN_CONNECT for a retry
}
else {
_written += bytesWritten;
@ -192,13 +192,14 @@ namespace triagens {
case (IN_READ_CHUNKED_BODY): {
TRI_set_errno(TRI_ERROR_NO_ERROR);
// we need to read a at least one byte to make progress
bool progress;
// we need to notice if the other side has closed the connection:
bool connectionClosed;
std::cout << "ReadBufV:" << (unsigned long) _readBuffer.c_str() << " "
<< _readBuffer.length() << " "
<< _readBufferOffset << std::endl;
bool res = _connection->handleRead(remainingTime, _readBuffer, progress);
bool res = _connection->handleRead(remainingTime, _readBuffer,
connectionClosed);
std::cout << "ReadBufN:" << (unsigned long) _readBuffer.c_str() << " "
<< _readBuffer.length() << " "
@ -207,17 +208,17 @@ namespace triagens {
// If there was an error, then we are doomed:
if (! res) {
std::cout << "doomed\n";
this->close(); // this sets the state to IN_CONNECT for a retry
this->close(); // this sets the state to IN_CONNECT for a retry
break;
}
if (! progress) {
std::cout << "no progress\n";
if (connectionClosed) {
std::cout << "connection closed\n";
// write might have succeeded even if the server has closed
// the connection, this will then show up here with us being
// in state IN_READ_HEADER but nothing read.
if (_state == IN_READ_HEADER && 0 == _readBuffer.length()) {
this->close(); // sets _state to IN_CONNECT again for a retry
this->close(); // sets _state to IN_CONNECT again for a retry
continue;
}
@ -228,24 +229,25 @@ namespace triagens {
// that the server has closed the connection and we must
// process the body one more time:
_result->setContentLength(_readBuffer.length() - _readBufferOffset);
std::cout << "SetContentLength: " << _readBuffer.length() - _readBufferOffset << std::endl;
processBody();
if (_state != FINISHED) {
// If the body was not fully found we give up:
this->close(); // this sets the state to retry
this->close(); // this sets the state IN_CONNECT to retry
}
break;
}
else {
// In all other cases of no progress, we are doomed:
this->close(); // this sets the state to retry
// In all other cases of closed connection, we are doomed:
this->close(); // this sets the state to IN_CONNECT retry
break;
}
}
// we made progress, we process whatever we are in progress to do
// the connection is still alive:
switch (_state) {
case (IN_READ_HEADER):
processHeader();

View File

@ -64,6 +64,7 @@ namespace triagens {
_returnMessage = "";
_contentLength = 0;
_returnCode = 0;
_foundHeader = false;
_hasContentLength = false;
_chunked = false;
_deflated = false;
@ -130,6 +131,7 @@ namespace triagens {
--valueLength;
}
std::cout << "Header: " << keyString << ": " << std::string(value, valueLength) << std::endl;
if (keyString[0] == 'h') {
if (! _foundHeader &&
(keyString == "http/1.1" || keyString == "http/1.0")) {
@ -142,6 +144,7 @@ namespace triagens {
(value[2] >= '0' && value[2] <= '9')) {
// set response code
setHttpReturnCode(100 * (value[0] - '0') + 10 * (value[1] - '0') + (value[2] - '0'));
std::cout << "setHttpReturnCode: " << getHttpReturnCode() << "\n";
}
if (valueLength >= 4) {

View File

@ -217,7 +217,9 @@ bool SslClientConnection::prepare (const double timeout, const bool isWrite) con
}
int sockn = (int) (TRI_get_fd_or_handle_of_socket(_socket) + 1);
if (select(sockn, readFds, writeFds, NULL, &tv) > 0) {
int res = select(sockn, readFds, writeFds, NULL, &tv);
std::cout << "selectSSL " << res << " " << errno << std::endl;
if (res > 0) {
return true;
}
@ -262,12 +264,17 @@ bool SslClientConnection::writeClientConnection (void* buffer, size_t length, si
/// @brief read data from the connection
////////////////////////////////////////////////////////////////////////////////
bool SslClientConnection::readClientConnection (StringBuffer& stringBuffer, bool& progress) {
if (_ssl == nullptr || ! _isConnected) {
bool SslClientConnection::readClientConnection (StringBuffer& stringBuffer,
bool& connectionClosed) {
connectionClosed = true;
if (_ssl == nullptr) {
return false;
}
if (! _isConnected) {
return true;
}
progress = false;
connectionClosed = false;
do {
@ -283,11 +290,12 @@ again:
switch (SSL_get_error(_ssl, lenRead)) {
case SSL_ERROR_NONE:
progress = true;
stringBuffer.increaseLength(lenRead);
break;
case SSL_ERROR_ZERO_RETURN:
std::cout << "SSL_ERROR_ZERO_RETURN\n";
connectionClosed = true;
SSL_shutdown(_ssl);
_isConnected = false;
return true;
@ -300,6 +308,7 @@ again:
case SSL_ERROR_SYSCALL:
default:
/* unexpected */
connectionClosed = true;
return false;
}
}

View File

@ -113,7 +113,8 @@ namespace triagens {
/// @brief read data from the connection
////////////////////////////////////////////////////////////////////////////////
bool readClientConnection (triagens::basics::StringBuffer&, bool& progress);
bool readClientConnection (triagens::basics::StringBuffer&,
bool& connectionClosed);
////////////////////////////////////////////////////////////////////////////////
/// @brief return whether the connection is readable