mirror of https://gitee.com/bigwinds/arangodb
fixed arangob for batch requests
This commit is contained in:
parent
77bc98cd42
commit
0619c9960c
|
@ -154,17 +154,8 @@ Handler::status_e RestBatchHandler::execute() {
|
||||||
bodyLength = partEnd - bodyStart;
|
bodyLength = partEnd - bodyStart;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// \r\n\r\n not found, try \n\n
|
// no delimiter found, assume we have only a header
|
||||||
p = strstr((char*) headerStart, "\n\n");
|
headerLength = partLength;
|
||||||
if (p != NULL) {
|
|
||||||
headerLength = p - partStart;
|
|
||||||
bodyStart = p + 2;
|
|
||||||
bodyLength = partEnd - bodyStart;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// no delimiter found, assume we have only a header
|
|
||||||
headerLength = partLength;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// set up request object for the part
|
// set up request object for the part
|
||||||
|
@ -251,18 +242,21 @@ bool RestBatchHandler::getBoundary (string* result) {
|
||||||
assert(_request);
|
assert(_request);
|
||||||
|
|
||||||
// extract content type
|
// extract content type
|
||||||
string contentType = StringUtils::tolower(StringUtils::trim(_request->header("content-type")));
|
string contentType = StringUtils::trim(_request->header("content-type"));
|
||||||
|
|
||||||
// content type is expect to contain a boundary like this:
|
// content type is expect to contain a boundary like this:
|
||||||
// "Content-Type: multipart/form-data; boundary=<boundary goes here>"
|
// "Content-Type: multipart/form-data; boundary=<boundary goes here>"
|
||||||
vector<string> parts = StringUtils::split(contentType, ';');
|
vector<string> parts = StringUtils::split(contentType, ';');
|
||||||
if (parts.size() != 2 || parts[0] != "multipart/form-data") {
|
if (parts.size() != 2 || parts[0] != HttpRequest::getMultipartContentType().c_str()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// trim 2nd part
|
// trim 2nd part
|
||||||
StringUtils::trimInPlace(parts[1]);
|
StringUtils::trimInPlace(parts[1]);
|
||||||
if (parts[1].substr(0, 9) != "boundary=") {
|
string p = parts[1].substr(0, 9);
|
||||||
|
StringUtils::tolowerInPlace(&p);
|
||||||
|
|
||||||
|
if (p != "boundary=") {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,6 +324,20 @@ bool RestBatchHandler::extractPart (SearchHelper* helper) {
|
||||||
++found;
|
++found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// look for part content type
|
||||||
|
static const string& expectedPartType = HttpRequest::getPartContentType();
|
||||||
|
|
||||||
|
if (strstr(found, expectedPartType.c_str()) != found) {
|
||||||
|
// part content type not located at expected position. this is an error
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
found += expectedPartType.size();
|
||||||
|
|
||||||
|
if (found >= searchEnd) {
|
||||||
|
// we're outside the buffer. this is an error
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// we're at the start of the body part. set the return value
|
// we're at the start of the body part. set the return value
|
||||||
helper->foundStart = found;
|
helper->foundStart = found;
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ namespace triagens {
|
||||||
/// @brief return the HTTP method of the operation to execute
|
/// @brief return the HTTP method of the operation to execute
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
virtual const SimpleHttpClient::http_method type () = 0;
|
virtual const HttpRequest::HttpRequestType type () = 0;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief return the payload (body) of the HTTP request to execute
|
/// @brief return the payload (body) of the HTTP request to execute
|
||||||
|
|
|
@ -53,6 +53,10 @@ namespace triagens {
|
||||||
// --SECTION-- class BenchmarkThread
|
// --SECTION-- class BenchmarkThread
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- constructors / destructors
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @addtogroup Threading
|
/// @addtogroup Threading
|
||||||
/// @{
|
/// @{
|
||||||
|
@ -62,6 +66,10 @@ namespace triagens {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief construct the benchmark thread
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
BenchmarkThread (BenchmarkOperation* operation,
|
BenchmarkThread (BenchmarkOperation* operation,
|
||||||
ConditionVariable* condition,
|
ConditionVariable* condition,
|
||||||
const unsigned long batchSize,
|
const unsigned long batchSize,
|
||||||
|
@ -81,6 +89,10 @@ namespace triagens {
|
||||||
_connection(0),
|
_connection(0),
|
||||||
_time(0.0) {
|
_time(0.0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief destroy the benchmark thread
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
~BenchmarkThread () {
|
~BenchmarkThread () {
|
||||||
if (_client != 0) {
|
if (_client != 0) {
|
||||||
|
@ -123,7 +135,11 @@ namespace triagens {
|
||||||
_client = new SimpleHttpClient(_connection, 10.0, true);
|
_client = new SimpleHttpClient(_connection, 10.0, true);
|
||||||
_client->setUserNamePassword("/", _username, _password);
|
_client->setUserNamePassword("/", _username, _password);
|
||||||
map<string, string> headerFields;
|
map<string, string> headerFields;
|
||||||
SimpleHttpResult* result = _client->request(SimpleHttpClient::GET, "/_api/version", 0, 0, headerFields);
|
SimpleHttpResult* result = _client->request(HttpRequest::HTTP_REQUEST_GET,
|
||||||
|
"/_api/version",
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
headerFields);
|
||||||
|
|
||||||
if (! result || ! result->isComplete()) {
|
if (! result || ! result->isComplete()) {
|
||||||
if (result) {
|
if (result) {
|
||||||
|
@ -157,20 +173,95 @@ namespace triagens {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- private methods
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @addtogroup V8Client
|
||||||
|
/// @{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief execute a batch request with numOperations parts
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void executeBatchRequest (const unsigned long numOperations) {
|
void executeBatchRequest (const unsigned long numOperations) {
|
||||||
|
const string boundary = "XXXarangob-benchmarkXXX";
|
||||||
|
|
||||||
|
StringBuffer batchPayload(TRI_UNKNOWN_MEM_ZONE);
|
||||||
|
|
||||||
|
for (unsigned long i = 0; i < numOperations; ++i) {
|
||||||
|
// append boundary
|
||||||
|
batchPayload.appendText("--" + boundary + "\r\n");
|
||||||
|
// append content-type, this will also begin the body
|
||||||
|
batchPayload.appendText(HttpRequest::getPartContentType());
|
||||||
|
|
||||||
|
// everything else (i.e. part request header & body) will get into the body
|
||||||
|
const HttpRequest::HttpRequestType type = _operation->type();
|
||||||
|
const string url = _operation->url();
|
||||||
|
size_t payloadLength = 0;
|
||||||
|
const char* payload = _operation->payload(&payloadLength);
|
||||||
|
const map<string, string>& headers = _operation->headers();
|
||||||
|
|
||||||
|
// headline, e.g. POST /... HTTP/1.1
|
||||||
|
HttpRequest::appendMethod(type, &batchPayload);
|
||||||
|
batchPayload.appendText(url + " HTTP/1.1\r\n");
|
||||||
|
// extra headers
|
||||||
|
for (map<string, string>::const_iterator it = headers.begin(); it != headers.end(); ++it) {
|
||||||
|
batchPayload.appendText((*it).first + ": " + (*it).second + "\r\n");
|
||||||
|
}
|
||||||
|
batchPayload.appendText("\r\n");
|
||||||
|
|
||||||
|
// body
|
||||||
|
batchPayload.appendText(payload, payloadLength);
|
||||||
|
batchPayload.appendText("\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// end of MIME
|
||||||
|
batchPayload.appendText("--" + boundary + "--\r\n");
|
||||||
|
|
||||||
|
map<string, string> batchHeaders;
|
||||||
|
batchHeaders["Content-Type"] = HttpRequest::getMultipartContentType() +
|
||||||
|
"; boundary=" + boundary;
|
||||||
|
|
||||||
|
Timing timer(Timing::TI_WALLCLOCK);
|
||||||
|
SimpleHttpResult* result = _client->request(HttpRequest::HTTP_REQUEST_POST,
|
||||||
|
"/_api/batch",
|
||||||
|
batchPayload.c_str(),
|
||||||
|
batchPayload.length(),
|
||||||
|
batchHeaders);
|
||||||
|
_time += ((double) timer.time()) / 1000000.0;
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
_operationsCounter->incFailures();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result->getHttpReturnCode() >= 400) {
|
||||||
|
_operationsCounter->incFailures();
|
||||||
|
}
|
||||||
|
delete result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief execute a single request
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void executeSingleRequest () {
|
void executeSingleRequest () {
|
||||||
Timing timer(Timing::TI_WALLCLOCK);
|
const HttpRequest::HttpRequestType type = _operation->type();
|
||||||
|
|
||||||
const SimpleHttpClient::http_method type = _operation->type();
|
|
||||||
const string url = _operation->url();
|
const string url = _operation->url();
|
||||||
size_t payloadLength = 0;
|
size_t payloadLength = 0;
|
||||||
const char* payload = _operation->payload(&payloadLength);
|
const char* payload = _operation->payload(&payloadLength);
|
||||||
const map<string, string>& headers = _operation->headers();
|
const map<string, string>& headers = _operation->headers();
|
||||||
|
|
||||||
|
Timing timer(Timing::TI_WALLCLOCK);
|
||||||
SimpleHttpResult* result = _client->request(type,
|
SimpleHttpResult* result = _client->request(type,
|
||||||
url,
|
url,
|
||||||
payload,
|
payload,
|
||||||
|
@ -189,9 +280,25 @@ namespace triagens {
|
||||||
delete result;
|
delete result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- public methods
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @addtogroup V8Client
|
||||||
|
/// @{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief return the total time accumulated by the thread
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
double getTime () const {
|
double getTime () const {
|
||||||
return _time;
|
return _time;
|
||||||
}
|
}
|
||||||
|
@ -205,7 +312,7 @@ namespace triagens {
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @addtogroup Threading
|
/// @addtogroup V8Client
|
||||||
/// @{
|
/// @{
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
|
@ -42,11 +42,13 @@
|
||||||
|
|
||||||
#include "Basics/StringUtils.h"
|
#include "Basics/StringUtils.h"
|
||||||
#include "BasicsC/json.h"
|
#include "BasicsC/json.h"
|
||||||
|
#include "Rest/HttpRequest.h"
|
||||||
#include "SimpleHttpClient/SimpleHttpClient.h"
|
#include "SimpleHttpClient/SimpleHttpClient.h"
|
||||||
#include "SimpleHttpClient/SimpleHttpResult.h"
|
#include "SimpleHttpClient/SimpleHttpResult.h"
|
||||||
|
|
||||||
using namespace triagens::basics;
|
using namespace triagens::basics;
|
||||||
using namespace triagens::httpclient;
|
using namespace triagens::httpclient;
|
||||||
|
using namespace triagens::rest;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace triagens {
|
namespace triagens {
|
||||||
|
@ -379,7 +381,7 @@ namespace triagens {
|
||||||
}
|
}
|
||||||
|
|
||||||
map<string, string> headerFields;
|
map<string, string> headerFields;
|
||||||
SimpleHttpResult* result = _client->request(SimpleHttpClient::POST, "/_api/import?" + getCollectionUrlPart(), _outputBuffer.c_str(), _outputBuffer.length(), headerFields);
|
SimpleHttpResult* result = _client->request(HttpRequest::HTTP_REQUEST_POST, "/_api/import?" + getCollectionUrlPart(), _outputBuffer.c_str(), _outputBuffer.length(), headerFields);
|
||||||
|
|
||||||
handleResult(result);
|
handleResult(result);
|
||||||
|
|
||||||
|
@ -392,7 +394,7 @@ namespace triagens {
|
||||||
}
|
}
|
||||||
|
|
||||||
map<string, string> headerFields;
|
map<string, string> headerFields;
|
||||||
SimpleHttpResult* result = _client->request(SimpleHttpClient::POST, "/_api/import?type=documents&" + getCollectionUrlPart(), str, len, headerFields);
|
SimpleHttpResult* result = _client->request(HttpRequest::HTTP_REQUEST_POST, "/_api/import?type=documents&" + getCollectionUrlPart(), str, len, headerFields);
|
||||||
|
|
||||||
handleResult(result);
|
handleResult(result);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include "Basics/StringUtils.h"
|
#include "Basics/StringUtils.h"
|
||||||
#include "BasicsC/json.h"
|
#include "BasicsC/json.h"
|
||||||
#include "BasicsC/strings.h"
|
#include "BasicsC/strings.h"
|
||||||
|
#include "Rest/HttpRequest.h"
|
||||||
#include "SimpleHttpClient/GeneralClientConnection.h"
|
#include "SimpleHttpClient/GeneralClientConnection.h"
|
||||||
#include "SimpleHttpClient/SimpleHttpClient.h"
|
#include "SimpleHttpClient/SimpleHttpClient.h"
|
||||||
#include "SimpleHttpClient/SimpleHttpResult.h"
|
#include "SimpleHttpClient/SimpleHttpResult.h"
|
||||||
|
@ -90,7 +91,7 @@ V8ClientConnection::V8ClientConnection (Endpoint* endpoint,
|
||||||
|
|
||||||
// connect to server and get version number
|
// connect to server and get version number
|
||||||
map<string, string> headerFields;
|
map<string, string> headerFields;
|
||||||
SimpleHttpResult* result = _client->request(SimpleHttpClient::GET, "/_api/version", 0, 0, headerFields);
|
SimpleHttpResult* result = _client->request(HttpRequest::HTTP_REQUEST_GET, "/_api/version", 0, 0, headerFields);
|
||||||
|
|
||||||
if (! result || ! result->isComplete()) {
|
if (! result || ! result->isComplete()) {
|
||||||
// save error message
|
// save error message
|
||||||
|
@ -220,7 +221,7 @@ triagens::httpclient::SimpleHttpClient* V8ClientConnection::getHttpClient() {
|
||||||
|
|
||||||
v8::Handle<v8::Value> V8ClientConnection::getData (std::string const& location,
|
v8::Handle<v8::Value> V8ClientConnection::getData (std::string const& location,
|
||||||
map<string, string> const& headerFields) {
|
map<string, string> const& headerFields) {
|
||||||
return requestData(SimpleHttpClient::GET, location, "", headerFields);
|
return requestData(HttpRequest::HTTP_REQUEST_GET, location, "", headerFields);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -229,7 +230,7 @@ v8::Handle<v8::Value> V8ClientConnection::getData (std::string const& location,
|
||||||
|
|
||||||
v8::Handle<v8::Value> V8ClientConnection::deleteData (std::string const& location,
|
v8::Handle<v8::Value> V8ClientConnection::deleteData (std::string const& location,
|
||||||
map<string, string> const& headerFields) {
|
map<string, string> const& headerFields) {
|
||||||
return requestData(SimpleHttpClient::DELETE, location, "", headerFields);
|
return requestData(HttpRequest::HTTP_REQUEST_DELETE, location, "", headerFields);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -238,7 +239,7 @@ v8::Handle<v8::Value> V8ClientConnection::deleteData (std::string const& locatio
|
||||||
|
|
||||||
v8::Handle<v8::Value> V8ClientConnection::headData (std::string const& location,
|
v8::Handle<v8::Value> V8ClientConnection::headData (std::string const& location,
|
||||||
map<string, string> const& headerFields) {
|
map<string, string> const& headerFields) {
|
||||||
return requestData(SimpleHttpClient::HEAD, location, "", headerFields);
|
return requestData(HttpRequest::HTTP_REQUEST_HEAD, location, "", headerFields);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -248,7 +249,7 @@ v8::Handle<v8::Value> V8ClientConnection::headData (std::string const& location,
|
||||||
v8::Handle<v8::Value> V8ClientConnection::postData (std::string const& location,
|
v8::Handle<v8::Value> V8ClientConnection::postData (std::string const& location,
|
||||||
std::string const& body,
|
std::string const& body,
|
||||||
map<string, string> const& headerFields) {
|
map<string, string> const& headerFields) {
|
||||||
return requestData(SimpleHttpClient::POST, location, body, headerFields);
|
return requestData(HttpRequest::HTTP_REQUEST_POST, location, body, headerFields);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -258,7 +259,7 @@ v8::Handle<v8::Value> V8ClientConnection::postData (std::string const& location,
|
||||||
v8::Handle<v8::Value> V8ClientConnection::putData (std::string const& location,
|
v8::Handle<v8::Value> V8ClientConnection::putData (std::string const& location,
|
||||||
std::string const& body,
|
std::string const& body,
|
||||||
map<string, string> const& headerFields) {
|
map<string, string> const& headerFields) {
|
||||||
return requestData(SimpleHttpClient::PUT, location, body, headerFields);
|
return requestData(HttpRequest::HTTP_REQUEST_PUT, location, body, headerFields);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -268,7 +269,7 @@ v8::Handle<v8::Value> V8ClientConnection::putData (std::string const& location,
|
||||||
v8::Handle<v8::Value> V8ClientConnection::patchData (std::string const& location,
|
v8::Handle<v8::Value> V8ClientConnection::patchData (std::string const& location,
|
||||||
std::string const& body,
|
std::string const& body,
|
||||||
map<string, string> const& headerFields) {
|
map<string, string> const& headerFields) {
|
||||||
return requestData(SimpleHttpClient::PATCH, location, body, headerFields);
|
return requestData(HttpRequest::HTTP_REQUEST_PATCH, location, body, headerFields);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -285,10 +286,10 @@ v8::Handle<v8::Value> V8ClientConnection::patchData (std::string const& location
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief executs a request
|
/// @brief executes a request
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
v8::Handle<v8::Value> V8ClientConnection::requestData (int method,
|
v8::Handle<v8::Value> V8ClientConnection::requestData (HttpRequest::HttpRequestType method,
|
||||||
string const& location,
|
string const& location,
|
||||||
string const& body,
|
string const& body,
|
||||||
map<string, string> const& headerFields) {
|
map<string, string> const& headerFields) {
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#define TRIAGENS_V8_CLIENT_CONNECTION_H 1
|
#define TRIAGENS_V8_CLIENT_CONNECTION_H 1
|
||||||
|
|
||||||
#include <Basics/Common.h>
|
#include <Basics/Common.h>
|
||||||
|
#include "Rest/HttpRequest.h"
|
||||||
|
|
||||||
#include <v8.h>
|
#include <v8.h>
|
||||||
|
|
||||||
|
@ -269,7 +270,7 @@ namespace triagens {
|
||||||
/// @brief executes a request
|
/// @brief executes a request
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
v8::Handle<v8::Value> requestData (int method,
|
v8::Handle<v8::Value> requestData (rest::HttpRequest::HttpRequestType method,
|
||||||
std::string const& location,
|
std::string const& location,
|
||||||
std::string const& body,
|
std::string const& body,
|
||||||
map<string, string> const& headerFields);
|
map<string, string> const& headerFields);
|
||||||
|
|
|
@ -38,9 +38,9 @@
|
||||||
#include "BasicsC/logging.h"
|
#include "BasicsC/logging.h"
|
||||||
#include "BasicsC/strings.h"
|
#include "BasicsC/strings.h"
|
||||||
#include "BasicsC/terminal-utils.h"
|
#include "BasicsC/terminal-utils.h"
|
||||||
#include "ImportHelper.h"
|
|
||||||
#include "Logger/Logger.h"
|
#include "Logger/Logger.h"
|
||||||
#include "Rest/Endpoint.h"
|
#include "Rest/Endpoint.h"
|
||||||
|
#include "Rest/HttpRequest.h"
|
||||||
#include "Rest/Initialise.h"
|
#include "Rest/Initialise.h"
|
||||||
#include "SimpleHttpClient/SimpleHttpClient.h"
|
#include "SimpleHttpClient/SimpleHttpClient.h"
|
||||||
#include "SimpleHttpClient/SimpleHttpResult.h"
|
#include "SimpleHttpClient/SimpleHttpResult.h"
|
||||||
|
@ -107,8 +107,8 @@ struct VersionTest : public BenchmarkOperation {
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SimpleHttpClient::http_method type () {
|
const HttpRequest::HttpRequestType type () {
|
||||||
return SimpleHttpClient::GET;
|
return HttpRequest::HTTP_REQUEST_GET;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* payload (size_t* length) {
|
const char* payload (size_t* length) {
|
||||||
|
|
|
@ -1394,6 +1394,18 @@ namespace triagens {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void tolowerInPlace (string* str) {
|
||||||
|
size_t len = str->length();
|
||||||
|
|
||||||
|
if (len == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (string::iterator i = str->begin(); i != str->end(); ++i) {
|
||||||
|
*i = ::tolower(*i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
string tolower (string const& str) {
|
string tolower (string const& str) {
|
||||||
size_t len = str.length();
|
size_t len = str.length();
|
||||||
|
@ -1417,6 +1429,18 @@ namespace triagens {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void toupperInPlace (string* str) {
|
||||||
|
size_t len = str->length();
|
||||||
|
|
||||||
|
if (len == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (string::iterator i = str->begin(); i != str->end(); ++i) {
|
||||||
|
*i = ::toupper(*i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
string toupper (string const& str) {
|
string toupper (string const& str) {
|
||||||
|
|
|
@ -333,6 +333,13 @@ namespace triagens {
|
||||||
|
|
||||||
string replace (string const& sourceStr, string const& fromString, string const& toString);
|
string replace (string const& sourceStr, string const& fromString, string const& toString);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @ingroup Utilities
|
||||||
|
/// @brief converts string to lower case in place
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void tolowerInPlace (string* str);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @ingroup Utilities
|
/// @ingroup Utilities
|
||||||
/// @brief converts string to lower case
|
/// @brief converts string to lower case
|
||||||
|
@ -340,6 +347,13 @@ namespace triagens {
|
||||||
|
|
||||||
string tolower (string const& str);
|
string tolower (string const& str);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @ingroup Utilities
|
||||||
|
/// @brief converts string to upper case in place
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void toupperInPlace (string* str);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @ingroup Utilities
|
/// @ingroup Utilities
|
||||||
/// @brief converts string to upper case
|
/// @brief converts string to upper case
|
||||||
|
|
|
@ -195,6 +195,70 @@ void HttpRequest::addSuffix (char const* part) {
|
||||||
/// @}
|
/// @}
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- public static methods
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @addtogroup Rest
|
||||||
|
/// @{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief append the request method string to a string buffer
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void HttpRequest::appendMethod (HttpRequestType method, StringBuffer* buffer) {
|
||||||
|
switch (method) {
|
||||||
|
case HTTP_REQUEST_GET:
|
||||||
|
buffer->appendText("GET ");
|
||||||
|
break;
|
||||||
|
case HTTP_REQUEST_POST:
|
||||||
|
buffer->appendText("POST ");
|
||||||
|
break;
|
||||||
|
case HTTP_REQUEST_PUT:
|
||||||
|
buffer->appendText("PUT ");
|
||||||
|
break;
|
||||||
|
case HTTP_REQUEST_DELETE:
|
||||||
|
buffer->appendText("DELETE ");
|
||||||
|
break;
|
||||||
|
case HTTP_REQUEST_PATCH:
|
||||||
|
buffer->appendText("PATCH ");
|
||||||
|
break;
|
||||||
|
case HTTP_REQUEST_HEAD:
|
||||||
|
buffer->appendText("HEAD ");
|
||||||
|
break;
|
||||||
|
case HTTP_REQUEST_ILLEGAL:
|
||||||
|
buffer->appendText("UNKNOWN ");
|
||||||
|
LOGGER_WARNING << "illegal http request method encountered in switch";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief the expected content-type for a subpart
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const string& HttpRequest::getPartContentType () {
|
||||||
|
static const string contentType = "Content-Type: application/x-arango-batchpart\r\n\r\n";
|
||||||
|
|
||||||
|
return contentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief the expected content-type for a multipart message
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const string& HttpRequest::getMultipartContentType () {
|
||||||
|
static const string contentType = "multipart/form-data";
|
||||||
|
|
||||||
|
return contentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- END-OF-FILE
|
// --SECTION-- END-OF-FILE
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
|
|
||||||
#include "BasicsC/json.h"
|
#include "BasicsC/json.h"
|
||||||
#include "BasicsC/string-buffer.h"
|
#include "BasicsC/string-buffer.h"
|
||||||
|
#include "Basics/StringBuffer.h"
|
||||||
#include "Rest/ConnectionInfo.h"
|
#include "Rest/ConnectionInfo.h"
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -392,6 +393,37 @@ namespace triagens {
|
||||||
/// @}
|
/// @}
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- public static methods
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @addtogroup Rest
|
||||||
|
/// @{
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief append the request method string to a string buffer
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static void appendMethod (HttpRequestType, triagens::basics::StringBuffer*);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief the expected content-type for a subpart
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static const string& getPartContentType ();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief the expected content-type for a multipart message
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static const string& getMultipartContentType ();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @}
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- protected variables
|
// --SECTION-- protected variables
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "BasicsC/strings.h"
|
#include "BasicsC/strings.h"
|
||||||
#include "Basics/StringUtils.h"
|
#include "Basics/StringUtils.h"
|
||||||
#include "Logger/Logger.h"
|
#include "Logger/Logger.h"
|
||||||
|
#include "Rest/HttpRequest.h"
|
||||||
|
|
||||||
using namespace triagens::basics;
|
using namespace triagens::basics;
|
||||||
using namespace triagens::rest;
|
using namespace triagens::rest;
|
||||||
|
@ -79,69 +80,10 @@ HttpResponsePart::~HttpResponsePart () {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void HttpResponsePart::writeHeader (StringBuffer* output) {
|
void HttpResponsePart::writeHeader (StringBuffer* output) {
|
||||||
output->appendText("X-Arango-status: ");
|
// content-type: application/x-arango-batchpart\r\n\r\n
|
||||||
output->appendText(responseString(_code));
|
output->appendText(HttpRequest::getPartContentType());
|
||||||
output->appendText("\r\n");
|
|
||||||
|
HttpResponse::writeHeader(output);
|
||||||
basics::Dictionary<char const*>::KeyValue const* begin;
|
|
||||||
basics::Dictionary<char const*>::KeyValue const* end;
|
|
||||||
|
|
||||||
bool seenTransferEncoding = false;
|
|
||||||
string transferEncoding;
|
|
||||||
|
|
||||||
for (_headers.range(begin, end); begin < end; ++begin) {
|
|
||||||
char const* key = begin->_key;
|
|
||||||
|
|
||||||
if (key == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ignore content-length
|
|
||||||
if (*key == 'c' && TRI_EqualString(key, "content-length")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*key == 't' && TRI_EqualString(key, "transfer-encoding")) {
|
|
||||||
seenTransferEncoding = true;
|
|
||||||
transferEncoding = begin->_value;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
char const* value = begin->_value;
|
|
||||||
|
|
||||||
if (! TRI_EqualString(key, "content-type")) {
|
|
||||||
// for all headers but content-type, we'll add the prefix "X-Arango-"
|
|
||||||
output->appendText("X-Arango-");
|
|
||||||
}
|
|
||||||
|
|
||||||
output->appendText(key);
|
|
||||||
output->appendText(": ");
|
|
||||||
output->appendText(value);
|
|
||||||
output->appendText("\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (seenTransferEncoding && transferEncoding == "chunked") {
|
|
||||||
output->appendText("X-Arango-transfer-encoding: chunked\r\n\r\n");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (seenTransferEncoding) {
|
|
||||||
output->appendText("X-Arango-transfer-encoding: ");
|
|
||||||
output->appendText(transferEncoding);
|
|
||||||
output->appendText("\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
output->appendText("X-Arango-content-length: ");
|
|
||||||
|
|
||||||
if (_isHeadResponse) {
|
|
||||||
output->appendInteger(_bodySize);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
output->appendInteger(_body.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
output->appendText("\r\n\r\n");
|
|
||||||
}
|
|
||||||
// end of header, body to follow
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
|
|
||||||
#include "Basics/StringBuffer.h"
|
#include "Basics/StringBuffer.h"
|
||||||
#include "Logger/Logger.h"
|
#include "Logger/Logger.h"
|
||||||
|
#include "Rest/HttpRequest.h"
|
||||||
|
|
||||||
namespace triagens {
|
namespace triagens {
|
||||||
namespace httpclient {
|
namespace httpclient {
|
||||||
|
@ -102,7 +103,7 @@ namespace triagens {
|
||||||
/// the caller has to delete the result object
|
/// the caller has to delete the result object
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
virtual SimpleHttpResult* request (int method,
|
virtual SimpleHttpResult* request (rest::HttpRequest::HttpRequestType method,
|
||||||
const string& location,
|
const string& location,
|
||||||
const char* body,
|
const char* body,
|
||||||
size_t bodyLength,
|
size_t bodyLength,
|
||||||
|
|
|
@ -60,7 +60,7 @@ namespace triagens {
|
||||||
// public methods
|
// public methods
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
SimpleHttpResult* SimpleHttpClient::request (int method,
|
SimpleHttpResult* SimpleHttpClient::request (rest::HttpRequest::HttpRequestType method,
|
||||||
const string& location,
|
const string& location,
|
||||||
const char* body,
|
const char* body,
|
||||||
size_t bodyLength,
|
size_t bodyLength,
|
||||||
|
@ -200,7 +200,7 @@ namespace triagens {
|
||||||
return _result;
|
return _result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleHttpClient::setRequest (int method,
|
void SimpleHttpClient::setRequest (rest::HttpRequest::HttpRequestType method,
|
||||||
const string& location,
|
const string& location,
|
||||||
const char* body,
|
const char* body,
|
||||||
size_t bodyLength,
|
size_t bodyLength,
|
||||||
|
@ -213,29 +213,7 @@ namespace triagens {
|
||||||
///////////////////// fill the write buffer //////////////////////////////
|
///////////////////// fill the write buffer //////////////////////////////
|
||||||
_writeBuffer.clear();
|
_writeBuffer.clear();
|
||||||
|
|
||||||
switch (method) {
|
HttpRequest::appendMethod(method, &_writeBuffer);
|
||||||
case GET:
|
|
||||||
_writeBuffer.appendText("GET ");
|
|
||||||
break;
|
|
||||||
case POST:
|
|
||||||
_writeBuffer.appendText("POST ");
|
|
||||||
break;
|
|
||||||
case PUT:
|
|
||||||
_writeBuffer.appendText("PUT ");
|
|
||||||
break;
|
|
||||||
case DELETE:
|
|
||||||
_writeBuffer.appendText("DELETE ");
|
|
||||||
break;
|
|
||||||
case PATCH:
|
|
||||||
_writeBuffer.appendText("PATCH ");
|
|
||||||
break;
|
|
||||||
case HEAD:
|
|
||||||
_writeBuffer.appendText("HEAD ");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
_writeBuffer.appendText("POST ");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
string l = location;
|
string l = location;
|
||||||
if (location.length() == 0 || location[0] != '/') {
|
if (location.length() == 0 || location[0] != '/') {
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
|
|
||||||
#include "Basics/StringBuffer.h"
|
#include "Basics/StringBuffer.h"
|
||||||
#include "Logger/Logger.h"
|
#include "Logger/Logger.h"
|
||||||
|
#include "Rest/HttpRequest.h"
|
||||||
#include "SimpleHttpClient/SimpleClient.h"
|
#include "SimpleHttpClient/SimpleClient.h"
|
||||||
|
|
||||||
namespace triagens {
|
namespace triagens {
|
||||||
|
@ -53,14 +54,6 @@ namespace triagens {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief supported request methods
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
enum http_method {
|
|
||||||
GET, POST, PUT, DELETE, HEAD, PATCH
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief constructs a new http client
|
/// @brief constructs a new http client
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -80,7 +73,7 @@ namespace triagens {
|
||||||
/// the caller has to delete the result object
|
/// the caller has to delete the result object
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
virtual SimpleHttpResult* request (int method,
|
virtual SimpleHttpResult* request (rest::HttpRequest::HttpRequestType method,
|
||||||
const string& location,
|
const string& location,
|
||||||
const char* body,
|
const char* body,
|
||||||
size_t bodyLength,
|
size_t bodyLength,
|
||||||
|
@ -123,7 +116,7 @@ namespace triagens {
|
||||||
/// @param headerFields list of header fields
|
/// @param headerFields list of header fields
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void setRequest (int method,
|
void setRequest (rest::HttpRequest::HttpRequestType method,
|
||||||
const string& location,
|
const string& location,
|
||||||
const char* body,
|
const char* body,
|
||||||
size_t bodyLength,
|
size_t bodyLength,
|
||||||
|
|
Loading…
Reference in New Issue