Casablanca webserver gives seemingly random error - c++

I am using the Casablanca REST SDK to make a webservice. The webservice has the client pass JSON through the URL and processes it. However in some cases if I send JSON that contains an array, it will crash the service. The strange part is the handler method that actually handles the JSON runs all the way through and ends before the error is given. My main function is:
int main()
{
std::string ip;
std::string port;
std::ifstream inputStream;
inputStream.open("ip_port.config");
while(!inputStream.eof())
{
inputStream >> ip;
inputStream >> port;
}
inputStream.close();
std::string uri = "http://"+ip+":"+port+"/";
//set up URL
web::http::uri u(U(uri));
//set up listener for URL
web::http::experimental::listener::http_listener listener(u);
listener.support(methods::GET, handle_get);
try
{
pplx::task<void> l = listener.open();
while(true)
{
l.wait();
sleep(1);
}
listener.close().wait();
}
catch(int e)
{
std::stringstream errorMessage;
errorMessage << "Error: " << e;
logRequest(errorMessage.str(), "Error Message");
}
return 0;
}
I have put two prints: "Beginning of Handler" and "End of Handler" in the handle_get function, which are both printed, leading me to beleive that the cause of the error has something to do with the while loop with the listener, but the error it gives has nothing to do with the listener:
terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::substr
Im trying to wrap my head around what about the listener could return that error.

Related

How to Fix the exception received from poco library?

When client create an instant on SenderThread. It can send data to and from.
But when client goes for suspend mode and come back from suspend. The last created threads get exception on
resume. and no data is sent.
Exception Details received :
displayText = Exception
message =
name = Exception
className = N4Poco9ExceptionE
Here is the code:
class SenderThread: public Poco::Runnable
{
public:
MyThread(const std::string& msg):
Msg(msg);
{
}
void run()
{
try {
SendData(msg);
} catch(Exception exp) {
std::cout<<"displayText = "<<e.displayText()<<std::endl;
std::cout<<"message = "<<e.message()<<std::endl;
std::cout<<"name = "<<e.name()<<std::endl;
std::cout<<"className = "<<e.className()<<std::endl;
}
}
private:
std::string Msg;
};
How can I get more details on the exception and how to handle this exception?.
Edited After Günter Obiltschnig comment:
I am able to catch the proper exception.
displayText = Invalid argument
name = Invalid argument
Some time i see socket closed exception. When system goes to suspend mode then all the socket is closed by system(os). Now upon resume application tries to open the socket again it throw error in the Poco::Net::Socket::Socket(Poco::Net::Socket const&). any help on this please
You have to catch the exception by (const) reference in order to get useful information out of it.
catch (const Poco::Exception& exc)
{
std::cerr << exc.displayText() << std::endl;
}

curlpp response is doubled

I'm just new to curlpp but I can't see what's wrong here with my code, so I hope someone can help me out.
I'm using curlpp in C++ to make Facebook Graph queries. That means the Facebook server will return Json data as result.
My code looks as follows:
#include <curlpp/cURLpp.hpp>
#include <curlpp/Easy.hpp>
#include <curlpp/Options.hpp>
#include <curlpp/Exception.hpp>
...
curlpp::Easy myRequest;
bool error = false;
QString result = "";
try {
// Setting the URL to the Facebook server with the query
curlpp::options::Url myUrl(request->getURL().toStdString());
// Creating stream for the result
std::ostringstream os;
curlpp::options::WriteStream ws(&os);
// setting my opts: url and output stream
myRequest.setOpt(myUrl);
myRequest.setOpt(ws);
// perform the request
myRequest.perform();
// stream the result into my stream
os << myRequest;
result = QString::fromStdString(os.str());
} catch (curlpp::RuntimeError &e) {
error = true;
qWarning() << "Error in HttpRequest execution:" << e.what();
} catch (curlpp::LogicError &e) {
error = true;
qWarning() << "Error in HttpRequest execution:" << e.what();
} catch (...) {
error = true;
qWarning() << "Unknown error in HttpRequest execution.";
}
My problem now is that the resulting stream (and thus my result QString) do contain the Json object sent by the Facebook Graph server, but twice.
That means, directly two times the same object, one after the other. And that makes it invalid Json.
But that can not be what the server delivers. And it's not what I get when I do check it with the openssl command line tool and make a HTTP Get request on my own.
What's wrong with my code?
Best, Michael

boost::asio::ip::tcp::resolver::iterator Check if values are null

I've got a block of code that throws an Access Violation when executed. It is the async_connect handler for boost::asio.
//------------------------------------------------------------------------------
void MyClient::OnConnect(const boost::system::error_code & errorCode, boost::asio::ip::tcp::resolver::iterator endpoint)
{
if (errorCode || endpoint == boost::asio::ip::tcp::resolver::iterator())
{
// Error - An error occured while attempting to connect
// Most likely these error codes correspond to https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx
std::ostringstream msg;
msg << "An error occured while attempting to connect to " << endpoint->host_name()
<< ". Error code: " << errorCode
<< ". Error Message: " << ErrorCodeToString(errorCode);
LogError(msg.str().c_str(), __FUNCSIG__, __FILE__, __LINE__);
return;
}
// We connected to an endpoint
m_connectionState |= CONNECTED;
In the debugger it looks like the problem is inside endpoint->host_name(), because it tried to get values_[0] while values_ are null.
This is a common Connection Refused scenario. I thought the handler got the endpoint so that it knew who it was trying to connect to! Is there some manner of check I can do on the iterator before I try to call a method on it?
It seems to pass and still throw access violation on
if( endpoint != boost::asio::ip::tcp::resolver::iterator() )
{
std::string blah = endpoint->host_name();
}
Probably you've figured this out by now, but I'll post a few lines in case someone else happens upon it.
This problem looks similar to one I had.
This will not work, and will give similar results to what you're describing.
void establish_connection() {
tcp::resolver resolver(get_asio_io_service()); // this is a problem
tcp::resolver::query q{server_name, "https"};
resolver.async_resolve(q,
[&](asio::error_code ec,
tcp::resolver::iterator it) {
this->handle_resolve(ec, it);
});
}
where establish_connection() is a method in the object that deals with communication to the server.
The resolver object disappears after the establish_connection() exits. You have to find a way to make it stick around. The various demos on the web have it as an attribute of the client object.
Please share your experience with this problem.

POCO json POST_METHOD returns results but gives I/O exception and ends program

Hi im havng a problem with poco under linux, im making a https json post to a webserver and im getting the response as i expected.
The problem is that i get an error after the response is printed and it ends the execution of my program.
Here is what i get on console:
200 OK
"{\"test_results\": ["result1", "result2", "result3", "result4"]}"
terminate called after throwing an instance of 'Poco::IOException' what(): I/O error
Here is the code that make the above result to be printed:
int posTry(){
try
{
// prepare session
Poco::Net::Context::Ptr context = new Poco::Net::Context(Poco::Net::Context::CLIENT_USE, "", "", "", Poco::Net::Context::VERIFY_NONE, 9, false, "ALL:!ADH:!LOW:!EXP:!MD5:#STRENGTH");
Poco::URI uri("https://someURL/somePATH");
Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort(), context);
// prepare path
std::string path(uri.getPathAndQuery());
if (path.empty()) path = "/";
// send request
std::string test = "{Some json code to get results that is already working}";
Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_POST, path, Poco::Net::HTTPMessage::HTTP_1_1);
req.setContentType("application/json");
req.setKeepAlive(true);
req.setContentLength( test.length() );
session.sendRequest(req) << test;
// get response
Poco::Net::HTTPResponse res;
std::cout << res.getStatus() << " " << res.getReason() << std::endl;
// print response
std::istream &is = session.receiveResponse(res);
Poco::StreamCopier::copyStream(is, std::cout);
std::vector<Poco::Net::HTTPCookie> cookies;
res.getCookies( cookies );
}
catch( const Poco::Exception& e )
{
std::cerr << e.displayText() << std::endl;
}
catch (...)
{
std::cout << "error";
return -1;
}
return 0;
}
I don't know what is this error about and I can't even catch the error in (...) and make the program continue. Can someone help me?
The exception comes from the destructor of Poco::Net::HTTPSClientSession,
This is a known bug fixed in POCO release 1.4.2.
source: http://pocoproject.org/docs/99100-ReleaseNotes.html
If you cannot upgrade, you should be able to get rid of the exception by adding a specific catch for it.

TCP client in Boost asio

Im building a TCP client using Boost::asio Libs. My program has a write() thread that sends a command to the server
write(*_socket,boost::asio::buffer("sspi l1\n\n",sizeof("sspi l1\n\n")));
Then a read thread is started that reads from the buffer all the time, as there can be messages broadcasted from the server due to any other client
void TCP_IP_Connection::readTCP()
{
size_t l=0;
this->len=0;
boost::system::error_code error;
try
{//loop reading all values from router
while(1)
{
//wait for reply??
l=_socket->read_some(boost::asio::buffer(this->reply,sizeof(this->reply)),error);
if(error)
throw boost::system::system_error(error);
if(l>0)
{
this->dataProcess(l);
}
else
boost::this_thread::sleep(boost::posix_time::milliseconds(5000));
_io.run();
if(error==boost::asio::error::eof) //connection closed by router
std::cout<<"connection closed by router";
_io.reset();
}
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
}
This thread runs al time in a while(1) loop and is supposed to sleep when the received data length is less than zero. It reads all the data and calls the data parser function. After that the write thread is used to send another command, with read thread running. But instead of the required response the server sends back
? ""
ERROR: Unknown command
I tried using the wireshark. I can see the command being send properly. What can be mistake I'm doing here?
sizeof("sspi l1\n\n") returns 10, but I can only count 9 characters in that string.
Try this instead:
const std::string cmd("sspi l1\n\n");
write(*_socket,boost::asio::buffer(cmd, cmd.length()));
Or when you have it as a string it is enough to do
const std::string cmd("sspi l1\n\n");
write(*_socket,boost::asio::buffer(cmd));
The second argument specifies a maximum length of the string to use. But since it is a constant string, the second argument is not strictly necessary.