in host/cxpslib/requesthandler.cpp [663:852]
bool RequestHandler::parsePutFileParams(boost::system::error_code const & error, size_t bytesTransferred)
{
cancelTimeout();
// putfile post params have following format
//
// token=value[&token=value]*&data=
//
// data= must be the last parameter (well it will be treated as if it were last even if it is not)
// set up things that might need to be done on exit
ON_BLOCK_EXIT(boost::bind(&RequestHandler::clearAsyncQueued, this));
SCOPE_GUARD sessionLogoutGuard = MAKE_SCOPE_GUARD(boost::bind(&RequestHandler::sessionLogout, this));
SCOPE_GUARD logXferGuard = MAKE_SCOPE_GUARD(boost::bind(&RequestHandler::logXferPutFile, this, (char const*)0));
SCOPE_GUARD resetGuard = MAKE_SCOPE_GUARD(boost::bind(&RequestHandler::reset, this));
SCOPE_GUARD replyAbortGuard = MAKE_SCOPE_GUARD(boost::bind(&HttpTraits::reply_t::abort, m_reply.get()));
SCOPE_GUARD logRequestFailedGuard = MAKE_SCOPE_GUARD(boost::bind(&RequestHandler::logRequestFailed, this));
bool wasSessionGuardDismissed = false;
try {
timeStop();
if (m_connection->isTimedOut()) {
return false;
}
if (!error) {
m_requestTelemetryData.CompletingNwRead(bytesTransferred);
m_requestInfo.m_bufferLen = bytesTransferred;
m_putFileInfo.m_totalBytesLeftToRead -= m_requestInfo.m_bufferLen;
m_putFileInfo.m_bytesProcessed += m_putFileInfo.m_idx;
m_putFileInfo.m_idx = 0;
while (m_putFileInfo.m_bytesProcessed < m_requestInfo.m_dataSize) {
if (m_putFileInfo.m_idx < m_requestInfo.m_bufferLen) {
if (m_putFileInfo.m_readingToken) {
while (m_putFileInfo.m_idx < m_requestInfo.m_bufferLen && '=' != m_putFileInfo.m_buffer[m_putFileInfo.m_idx]
&& m_putFileInfo.m_bytesChecked < MAX_TOKEN_BYTES_TO_CHECK) {
m_putFileInfo.m_token += m_putFileInfo.m_buffer[m_putFileInfo.m_idx];
++m_putFileInfo.m_idx;
++m_putFileInfo.m_bytesChecked;
}
if (m_putFileInfo.m_bytesChecked >= MAX_TOKEN_BYTES_TO_CHECK) {
m_requestTelemetryData.SetRequestFailure(RequestFailure_PutFileNoParam);
std::string msg("did not find parameter with in check range ");
msg += boost::lexical_cast<std::string>(MAX_TOKEN_BYTES_TO_CHECK);
badRequest(AT_LOC, msg.c_str());
return false;
}
if (m_putFileInfo.m_idx < m_requestInfo.m_bufferLen) {
if ('=' == m_putFileInfo.m_buffer[m_putFileInfo.m_idx]) {
++m_putFileInfo.m_idx;
m_putFileInfo.m_bytesChecked = 0;
m_putFileInfo.m_readingToken = false;
if (HTTP_PARAM_TAG_DATA == m_putFileInfo.m_token) {
// have all params dimiss all guards and get file data portion
logXferGuard.dismiss();
resetGuard.dismiss();
replyAbortGuard.dismiss();
logRequestFailedGuard.dismiss();
sessionLogoutGuard.dismiss();
wasSessionGuardDismissed = true;
putFileGetData();
return true;
}
}
}
} else {
while (m_putFileInfo.m_idx < m_requestInfo.m_bufferLen && '&' != m_putFileInfo.m_buffer[m_putFileInfo.m_idx]
&& m_putFileInfo.m_bytesChecked < MAX_VALUE_BYTES_TO_CHECK) {
m_putFileInfo.m_value += m_putFileInfo.m_buffer[m_putFileInfo.m_idx];
++m_putFileInfo.m_idx;
++m_putFileInfo.m_bytesChecked;
}
if (m_putFileInfo.m_bytesChecked >= MAX_VALUE_BYTES_TO_CHECK) {
m_requestTelemetryData.SetRequestFailure(RequestFailure_PutFileNoParamVal);
std::string msg("did not find value for ");
msg += m_putFileInfo.m_token;
msg += " with in check range ";
msg += boost::lexical_cast<std::string>(MAX_VALUE_BYTES_TO_CHECK);
badRequest(AT_LOC, msg.c_str());
return false;
}
if (m_putFileInfo.m_idx < m_requestInfo.m_bufferLen) {
if ('&' == m_putFileInfo.m_buffer[m_putFileInfo.m_idx]) {
++m_putFileInfo.m_idx;
m_putFileInfo.m_bytesChecked = 0;
m_requestInfo.m_params.insert(std::make_pair(m_putFileInfo.m_token, urlDecode(m_putFileInfo.m_value)));
m_putFileInfo.m_token.clear();
m_putFileInfo.m_value.clear();
m_putFileInfo.m_readingToken = true;
}
}
}
} else {
if (m_putFileInfo.m_totalBytesLeftToRead > 0) {
try {
// still working on params dismiss all guards
CXPS_LOG_MONITOR(MONITOR_LOG_LEVEL_2,
"PARSING POST PARAMS\t"
<< "(sid: " << m_sessionId << ")\t"
<< m_hostId << '\t'
<< m_connection->endpointInfoAsString() << '\t'
<< getRequestInfoAsString(true)
<< ": need to read more data from socket");
logXferGuard.dismiss();
resetGuard.dismiss();
replyAbortGuard.dismiss();
logRequestFailedGuard.dismiss();
sessionLogoutGuard.dismiss();
m_putFileInfo.m_buffer = &m_buffer[0];
if (!m_connection->isTimedOut()) {
timeStart();
setTimeout();
m_requestTelemetryData.StartingNwRead();
m_connection->asyncRead(&m_buffer[0],
(m_putFileInfo.m_totalBytesLeftToRead < m_buffer.size() ? m_putFileInfo.m_totalBytesLeftToRead : m_buffer.size()),
boost::bind(&RequestHandler::parsePutFileParams,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
return true;
}
} catch (std::exception const& e) {
m_requestTelemetryData.SetRequestFailure(RequestFailure_PutFileParamsReadTimedOut);
CXPS_LOG_ERROR(AT_LOC << "(sid: " << m_sessionId << ") "
<< m_connection->endpointInfoAsString()
<< ": timed out reading putfile parameters\n");
badRequest(AT_LOC, "timed out reading putfile parameters\n");
return false;
}
} else {
m_requestTelemetryData.SetRequestFailure(RequestFailure_PutFileInvalidParams);
badRequest(AT_LOC, "invalid parameters\n");
return false;
}
}
}
} else {
m_requestTelemetryData.SetRequestFailure(RequestFailure_NwReadFailure);
std::stringstream errStr;
errStr << m_putFileInfo.m_name.string() << " socket error: " << error;
CXPS_LOG_ERROR(AT_LOC << "(sid: " << m_sessionId << ") "
<< m_connection->endpointInfoAsString()
<< ": " << errStr.str());
}
} catch (std::exception const& e) {
if (!wasSessionGuardDismissed)
{
// Otherwise, set and also logged by SessionLogOut() at the putFileGetData().
m_requestTelemetryData.SetRequestFailure(RequestFailure_PutFileParamsFailed);
}
std::stringstream errStr;
errStr << m_putFileInfo.m_name.string() << " error: " << e.what();
CXPS_LOG_ERROR(AT_LOC << "(sid: " << m_sessionId << ") "
<< m_connection->endpointInfoAsString() << ": "
<< errStr.str());
sendError(ResponseCode::RESPONSE_INTERNAL_ERROR, errStr.str().c_str(), errStr.str().size());
logRequestDone("(failed)");
m_connection->disconnect();
} catch (...) {
if (!wasSessionGuardDismissed)
{
// Otherwise, set and also logged by SessionLogOut() at the putFileGetData().
m_requestTelemetryData.SetRequestFailure(RequestFailure_PutFileParamsFailed);
}
std::stringstream errStr;
errStr << m_putFileInfo.m_name.string() << " unknown exception";
CXPS_LOG_ERROR(AT_LOC << "(sid: " << m_sessionId << ") "
<< m_connection->endpointInfoAsString() << ": "
<< errStr.str());
sendError(ResponseCode::RESPONSE_INTERNAL_ERROR, errStr.str().c_str(), errStr.str().size());
logRequestDone("(failed)");
m_connection->disconnect();
}
return false;
}