Files
MaxScale/server/core/adminclient.cc
Markus Mäkelä c937457738 MXS-1220: Add request body parsing
The HTTP request body is expected to be a valid JSON object. All other
requests are considered malformed requests and result in a HTTP 400 error.

Added the Jansson license to the LICENSE-THIRDPARTY.TXT file. Imported
some of the tests from the Jansson test suite to the HttpParser test.
2017-05-04 09:10:32 +03:00

111 lines
2.3 KiB
C++

/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file and at www.mariadb.com/bsl11.
*
* Change Date: 2019-07-01
*
* On the date above, in accordance with the Business Source License, use
* of this software will be governed by version 2 or later of the General
* Public License.
*/
#include "maxscale/adminclient.hh"
#include "maxscale/httprequest.hh"
#include <string>
#include <sstream>
#include <maxscale/atomic.h>
#include <maxscale/hk_heartbeat.h>
#include <maxscale/log_manager.h>
#include <maxscale/thread.h>
#include <maxscale/spinlock.hh>
using std::string;
using std::stringstream;
using mxs::SpinLockGuard;
AdminClient::AdminClient(int fd, const struct sockaddr_storage& addr, int timeout):
m_fd(fd),
m_last_activity(atomic_read_int64(&hkheartbeat)),
m_addr(addr)
{
}
void AdminClient::close_connection()
{
SpinLockGuard guard(m_lock);
if (m_fd != -1)
{
close(m_fd);
m_fd = -1;
}
}
AdminClient::~AdminClient()
{
close_connection();
}
static bool read_request(int fd, string& output)
{
while (true)
{
char buf[1024];
int bufsize = sizeof(buf) - 1;
int rc = read(fd, buf, bufsize);
if (rc == -1)
{
return false;
}
buf[rc] = '\0';
output += buf;
if (rc < bufsize)
{
/** Complete request read */
break;
}
}
return true;
}
static bool write_response(int fd, enum http_code code, const string& body)
{
string payload = "HTTP/1.1 ";
payload += http_code_to_string(code);
payload += "\r\n\r\n";
payload += body;
return write(fd, payload.c_str(), payload.length()) != -1;
}
void AdminClient::process()
{
string request;
atomic_write_int64(&m_last_activity, hkheartbeat);
if (read_request(m_fd, request))
{
SHttpRequest parser(HttpRequest::parse(request));
enum http_code status = parser.get() ? HTTP_200_OK : HTTP_400_BAD_REQUEST;
atomic_write_int64(&m_last_activity, hkheartbeat);
/** Echo the request body back */
write_response(m_fd, HTTP_200_OK, parser->get_json_str());
}
else
{
MXS_ERROR("Failed to read client request: %d, %s", errno, mxs_strerror(errno));
}
}