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;
|
||||
}
|
||||
else {
|
||||
// \r\n\r\n not found, try \n\n
|
||||
p = strstr((char*) headerStart, "\n\n");
|
||||
if (p != NULL) {
|
||||
headerLength = p - partStart;
|
||||
bodyStart = p + 2;
|
||||
bodyLength = partEnd - bodyStart;
|
||||
}
|
||||
else {
|
||||
// no delimiter found, assume we have only a header
|
||||
headerLength = partLength;
|
||||
}
|
||||
// no delimiter found, assume we have only a header
|
||||
headerLength = partLength;
|
||||
}
|
||||
|
||||
// set up request object for the part
|
||||
|
@ -251,18 +242,21 @@ bool RestBatchHandler::getBoundary (string* result) {
|
|||
assert(_request);
|
||||
|
||||
// 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: multipart/form-data; boundary=<boundary goes here>"
|
||||
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;
|
||||
}
|
||||
|
||||
// trim 2nd part
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -330,6 +324,20 @@ bool RestBatchHandler::extractPart (SearchHelper* helper) {
|
|||
++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
|
||||
helper->foundStart = found;
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ namespace triagens {
|
|||
/// @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
|
||||
|
|
|
@ -53,6 +53,10 @@ namespace triagens {
|
|||
// --SECTION-- class BenchmarkThread
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- constructors / destructors
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup Threading
|
||||
/// @{
|
||||
|
@ -62,6 +66,10 @@ namespace triagens {
|
|||
|
||||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief construct the benchmark thread
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BenchmarkThread (BenchmarkOperation* operation,
|
||||
ConditionVariable* condition,
|
||||
const unsigned long batchSize,
|
||||
|
@ -81,6 +89,10 @@ namespace triagens {
|
|||
_connection(0),
|
||||
_time(0.0) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief destroy the benchmark thread
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
~BenchmarkThread () {
|
||||
if (_client != 0) {
|
||||
|
@ -123,7 +135,11 @@ namespace triagens {
|
|||
_client = new SimpleHttpClient(_connection, 10.0, true);
|
||||
_client->setUserNamePassword("/", _username, _password);
|
||||
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) {
|
||||
|
@ -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) {
|
||||
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 () {
|
||||
Timing timer(Timing::TI_WALLCLOCK);
|
||||
|
||||
const SimpleHttpClient::http_method type = _operation->type();
|
||||
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();
|
||||
|
||||
Timing timer(Timing::TI_WALLCLOCK);
|
||||
SimpleHttpResult* result = _client->request(type,
|
||||
url,
|
||||
payload,
|
||||
|
@ -189,9 +280,25 @@ namespace triagens {
|
|||
delete result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup V8Client
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return the total time accumulated by the thread
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
double getTime () const {
|
||||
return _time;
|
||||
}
|
||||
|
@ -205,7 +312,7 @@ namespace triagens {
|
|||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup Threading
|
||||
/// @addtogroup V8Client
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
|
@ -42,11 +42,13 @@
|
|||
|
||||
#include "Basics/StringUtils.h"
|
||||
#include "BasicsC/json.h"
|
||||
#include "Rest/HttpRequest.h"
|
||||
#include "SimpleHttpClient/SimpleHttpClient.h"
|
||||
#include "SimpleHttpClient/SimpleHttpResult.h"
|
||||
|
||||
using namespace triagens::basics;
|
||||
using namespace triagens::httpclient;
|
||||
using namespace triagens::rest;
|
||||
using namespace std;
|
||||
|
||||
namespace triagens {
|
||||
|
@ -379,7 +381,7 @@ namespace triagens {
|
|||
}
|
||||
|
||||
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);
|
||||
|
||||
|
@ -392,7 +394,7 @@ namespace triagens {
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "Basics/StringUtils.h"
|
||||
#include "BasicsC/json.h"
|
||||
#include "BasicsC/strings.h"
|
||||
#include "Rest/HttpRequest.h"
|
||||
#include "SimpleHttpClient/GeneralClientConnection.h"
|
||||
#include "SimpleHttpClient/SimpleHttpClient.h"
|
||||
#include "SimpleHttpClient/SimpleHttpResult.h"
|
||||
|
@ -90,7 +91,7 @@ V8ClientConnection::V8ClientConnection (Endpoint* endpoint,
|
|||
|
||||
// connect to server and get version number
|
||||
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()) {
|
||||
// save error message
|
||||
|
@ -220,7 +221,7 @@ triagens::httpclient::SimpleHttpClient* V8ClientConnection::getHttpClient() {
|
|||
|
||||
v8::Handle<v8::Value> V8ClientConnection::getData (std::string const& location,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
std::string const& body,
|
||||
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,
|
||||
std::string const& body,
|
||||
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,
|
||||
std::string const& body,
|
||||
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& body,
|
||||
map<string, string> const& headerFields) {
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#define TRIAGENS_V8_CLIENT_CONNECTION_H 1
|
||||
|
||||
#include <Basics/Common.h>
|
||||
#include "Rest/HttpRequest.h"
|
||||
|
||||
#include <v8.h>
|
||||
|
||||
|
@ -269,7 +270,7 @@ namespace triagens {
|
|||
/// @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& body,
|
||||
map<string, string> const& headerFields);
|
||||
|
|
|
@ -38,9 +38,9 @@
|
|||
#include "BasicsC/logging.h"
|
||||
#include "BasicsC/strings.h"
|
||||
#include "BasicsC/terminal-utils.h"
|
||||
#include "ImportHelper.h"
|
||||
#include "Logger/Logger.h"
|
||||
#include "Rest/Endpoint.h"
|
||||
#include "Rest/HttpRequest.h"
|
||||
#include "Rest/Initialise.h"
|
||||
#include "SimpleHttpClient/SimpleHttpClient.h"
|
||||
#include "SimpleHttpClient/SimpleHttpResult.h"
|
||||
|
@ -107,8 +107,8 @@ struct VersionTest : public BenchmarkOperation {
|
|||
return url;
|
||||
}
|
||||
|
||||
const SimpleHttpClient::http_method type () {
|
||||
return SimpleHttpClient::GET;
|
||||
const HttpRequest::HttpRequestType type () {
|
||||
return HttpRequest::HTTP_REQUEST_GET;
|
||||
}
|
||||
|
||||
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) {
|
||||
size_t len = str.length();
|
||||
|
@ -1417,6 +1429,18 @@ namespace triagens {
|
|||
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) {
|
||||
|
|
|
@ -333,6 +333,13 @@ namespace triagens {
|
|||
|
||||
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
|
||||
/// @brief converts string to lower case
|
||||
|
@ -340,6 +347,13 @@ namespace triagens {
|
|||
|
||||
string tolower (string const& str);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @ingroup Utilities
|
||||
/// @brief converts string to upper case in place
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void toupperInPlace (string* str);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @ingroup Utilities
|
||||
/// @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
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include "BasicsC/json.h"
|
||||
#include "BasicsC/string-buffer.h"
|
||||
#include "Basics/StringBuffer.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
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "BasicsC/strings.h"
|
||||
#include "Basics/StringUtils.h"
|
||||
#include "Logger/Logger.h"
|
||||
#include "Rest/HttpRequest.h"
|
||||
|
||||
using namespace triagens::basics;
|
||||
using namespace triagens::rest;
|
||||
|
@ -79,69 +80,10 @@ HttpResponsePart::~HttpResponsePart () {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void HttpResponsePart::writeHeader (StringBuffer* output) {
|
||||
output->appendText("X-Arango-status: ");
|
||||
output->appendText(responseString(_code));
|
||||
output->appendText("\r\n");
|
||||
|
||||
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
|
||||
// content-type: application/x-arango-batchpart\r\n\r\n
|
||||
output->appendText(HttpRequest::getPartContentType());
|
||||
|
||||
HttpResponse::writeHeader(output);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include "Basics/StringBuffer.h"
|
||||
#include "Logger/Logger.h"
|
||||
#include "Rest/HttpRequest.h"
|
||||
|
||||
namespace triagens {
|
||||
namespace httpclient {
|
||||
|
@ -102,7 +103,7 @@ namespace triagens {
|
|||
/// the caller has to delete the result object
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual SimpleHttpResult* request (int method,
|
||||
virtual SimpleHttpResult* request (rest::HttpRequest::HttpRequestType method,
|
||||
const string& location,
|
||||
const char* body,
|
||||
size_t bodyLength,
|
||||
|
|
|
@ -60,7 +60,7 @@ namespace triagens {
|
|||
// public methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
SimpleHttpResult* SimpleHttpClient::request (int method,
|
||||
SimpleHttpResult* SimpleHttpClient::request (rest::HttpRequest::HttpRequestType method,
|
||||
const string& location,
|
||||
const char* body,
|
||||
size_t bodyLength,
|
||||
|
@ -200,7 +200,7 @@ namespace triagens {
|
|||
return _result;
|
||||
}
|
||||
|
||||
void SimpleHttpClient::setRequest (int method,
|
||||
void SimpleHttpClient::setRequest (rest::HttpRequest::HttpRequestType method,
|
||||
const string& location,
|
||||
const char* body,
|
||||
size_t bodyLength,
|
||||
|
@ -213,29 +213,7 @@ namespace triagens {
|
|||
///////////////////// fill the write buffer //////////////////////////////
|
||||
_writeBuffer.clear();
|
||||
|
||||
switch (method) {
|
||||
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;
|
||||
}
|
||||
HttpRequest::appendMethod(method, &_writeBuffer);
|
||||
|
||||
string l = location;
|
||||
if (location.length() == 0 || location[0] != '/') {
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include "Basics/StringBuffer.h"
|
||||
#include "Logger/Logger.h"
|
||||
#include "Rest/HttpRequest.h"
|
||||
#include "SimpleHttpClient/SimpleClient.h"
|
||||
|
||||
namespace triagens {
|
||||
|
@ -53,14 +54,6 @@ namespace triagens {
|
|||
|
||||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief supported request methods
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
enum http_method {
|
||||
GET, POST, PUT, DELETE, HEAD, PATCH
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief constructs a new http client
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -80,7 +73,7 @@ namespace triagens {
|
|||
/// the caller has to delete the result object
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual SimpleHttpResult* request (int method,
|
||||
virtual SimpleHttpResult* request (rest::HttpRequest::HttpRequestType method,
|
||||
const string& location,
|
||||
const char* body,
|
||||
size_t bodyLength,
|
||||
|
@ -123,7 +116,7 @@ namespace triagens {
|
|||
/// @param headerFields list of header fields
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void setRequest (int method,
|
||||
void setRequest (rest::HttpRequest::HttpRequestType method,
|
||||
const string& location,
|
||||
const char* body,
|
||||
size_t bodyLength,
|
||||
|
|
Loading…
Reference in New Issue