MXS-1220: Add versioned URLs

Added versioning to URLs. This should allow somewhat safe modification to
the API after it has been finished.
This commit is contained in:
Markus Mäkelä 2017-05-02 16:34:41 +03:00
parent 0ea58ea6bc
commit b2e94fc73c
5 changed files with 49 additions and 15 deletions

View File

@ -102,7 +102,12 @@ int Client::process(string url, string method, const char* upload_data, size_t *
}
HttpRequest request(m_connection, url, method, json);
HttpResponse reply = resource_handle_request(request);
HttpResponse reply(MHD_HTTP_NOT_FOUND);
if (request.validate_api_version())
{
reply = resource_handle_request(request);
}
string data;

View File

@ -74,20 +74,12 @@ static void process_uri(string& uri, std::deque<string>& uri_parts)
my_uri.erase(my_uri.begin());
}
if (my_uri.length() == 0)
while (my_uri.length() > 0)
{
/** Special handling for the / resource */
uri_parts.push_back("");
}
else
{
while (my_uri.length() > 0)
{
size_t pos = my_uri.find("/");
string part = pos == string::npos ? my_uri : my_uri.substr(0, pos);
my_uri.erase(0, pos == string::npos ? pos : pos + 1);
uri_parts.push_back(part);
}
size_t pos = my_uri.find("/");
string part = pos == string::npos ? my_uri : my_uri.substr(0, pos);
my_uri.erase(0, pos == string::npos ? pos : pos + 1);
uri_parts.push_back(part);
}
}
@ -102,9 +94,29 @@ HttpRequest::HttpRequest(struct MHD_Connection *connection, string url, string m
m_hostname = mxs_admin_https_enabled() ? HttpRequest::HTTPS_PREFIX : HttpRequest::HTTP_PREFIX;
m_hostname += get_header(HTTP_HOST_HEADER);
if (m_hostname[m_hostname.size() - 1] != '/')
{
m_hostname += "/";
}
m_hostname += MXS_REST_API_VERSION;
}
HttpRequest::~HttpRequest()
{
}
bool HttpRequest::validate_api_version()
{
bool rval = false;
if (m_resource_parts.size() > 0 &&
m_resource_parts[0] == MXS_REST_API_VERSION)
{
m_resource_parts.pop_front();
rval = true;
}
return rval;
}

View File

@ -33,6 +33,11 @@ HttpResponse::HttpResponse(int code, json_t* response):
add_header(HTTP_RESPONSE_HEADER_LAST_MODIFIED, http_date);
// This ETag is the base64 encoding of `not-yet-implemented`
add_header(HTTP_RESPONSE_HEADER_ETAG, "bm90LXlldC1pbXBsZW1lbnRlZAo");
if (m_body)
{
add_header(HTTP_RESPONSE_HEADER_CONTENT_TYPE, "application/json");
}
}
HttpResponse::HttpResponse(const HttpResponse& response):

View File

@ -26,6 +26,9 @@
#include "http.hh"
// The API version part of the URL
#define MXS_REST_API_VERSION "v1"
static int value_iterator(void *cls,
enum MHD_ValueKind kind,
const char *key,
@ -160,6 +163,14 @@ public:
{
return m_hostname.c_str();
}
/**
* @brief Drop the API version prefix
*
* @return True if prefix is present and was successfully removed
*/
bool validate_api_version();
private:
/** Constants */
@ -173,5 +184,5 @@ private:
std::deque<std::string> m_resource_parts; /**< @c m_resource split into parts */
std::string m_verb; /**< Request method */
std::string m_hostname; /**< The value of the Host header */
struct MHD_Connection* m_connection;
struct MHD_Connection* m_connection;
};

View File

@ -30,6 +30,7 @@
#define HTTP_RESPONSE_HEADER_LAST_MODIFIED "Last-Modified"
#define HTTP_RESPONSE_HEADER_ETAG "ETag"
#define HTTP_RESPONSE_HEADER_ACCEPT "Accept"
#define HTTP_RESPONSE_HEADER_CONTENT_TYPE "Content-Type"
typedef std::map<std::string, std::string> Headers;