1
0
Fork 0

Merge branch 'devel' of https://github.com/arangodb/arangodb into devel

This commit is contained in:
Jan Steemann 2016-04-12 18:27:53 +02:00
commit d0296b38e9
4 changed files with 84 additions and 63 deletions

View File

@ -43,16 +43,17 @@ void RestBaseHandler::handleError(Exception const& ex) {
generateError(GeneralResponse::responseCode(ex.code()), ex.code(), ex.what());
}
////////////////////////////////////////////////////////////////////////////////
/// @brief generates a result from VelocyPack
////////////////////////////////////////////////////////////////////////////////
void RestBaseHandler::generateResult(GeneralResponse::ResponseCode code,
VPackSlice const& slice) {
createResponse(code);
_response->setContentType("application/json; charset=utf-8");
dumpResponse(slice, &VPackOptions::Defaults);
createResponse(code);
writeResult(slice, VPackOptions::Defaults);
}
////////////////////////////////////////////////////////////////////////////////
@ -63,9 +64,7 @@ void RestBaseHandler::generateResult(GeneralResponse::ResponseCode code,
VPackSlice const& slice,
std::shared_ptr<TransactionContext> context) {
createResponse(code);
_response->setContentType("application/json; charset=utf-8");
dumpResponse(slice, context->getVPackOptions());
writeResult(slice,*(context->getVPackOptions()));
}
////////////////////////////////////////////////////////////////////////////////
@ -90,7 +89,6 @@ void RestBaseHandler::generateError(GeneralResponse::ResponseCode code,
void RestBaseHandler::generateError(GeneralResponse::ResponseCode code,
int errorCode, std::string const& message) {
createResponse(code);
_response->setContentType("application/json; charset=utf-8");
VPackBuilder builder;
try {
@ -106,7 +104,7 @@ void RestBaseHandler::generateError(GeneralResponse::ResponseCode code,
builder.add("errorNum", VPackValue(errorCode));
builder.close();
dumpResponse(builder.slice(), &VPackOptions::Defaults);
writeResult(builder.slice(), VPackOptions::Defaults);
} catch (...) {
// Building the error response failed
}
@ -147,3 +145,28 @@ void RestBaseHandler::dumpResponse(VPackSlice const& slice,
}
}
//////////////////////////////////////////////////////////////////////////////
/// @brief checks if velocypack is expected as answer
//////////////////////////////////////////////////////////////////////////////
bool RestBaseHandler::returnVelocypack() const {
auto accept = std::string(_request->header("accept"));
if (std::string::npos == accept.find("application/x-velocypack")) {
return false;
}
return true;
}
//////////////////////////////////////////////////////////////////////////////
/// @brief writes volocypack or json to response
//////////////////////////////////////////////////////////////////////////////
void RestBaseHandler::writeResult(arangodb::velocypack::Slice const& slice, VPackOptions const& options){
if(returnVelocypack()) {
_response->setContentType("application/x-velocypack");
_response->body().appendText(slice.startAs<const char>(),slice.byteSize());
} else {
_response->setContentType("application/json; charset=utf-8");
dumpResponse(slice, &options);
}
}

View File

@ -44,18 +44,15 @@ class RestBaseHandler : public rest::HttpHandler {
public:
explicit RestBaseHandler(HttpRequest* request);
public:
void handleError(basics::Exception const&) override;
public:
//////////////////////////////////////////////////////////////////////////////
/// @brief generates a result from VelocyPack
//////////////////////////////////////////////////////////////////////////////
void generateResult(GeneralResponse::ResponseCode,
arangodb::velocypack::Slice const& slice);
//////////////////////////////////////////////////////////////////////////////
/// @brief generates a result from VelocyPack
//////////////////////////////////////////////////////////////////////////////
@ -81,7 +78,7 @@ class RestBaseHandler : public rest::HttpHandler {
//////////////////////////////////////////////////////////////////////////////
void generateOOMError();
//////////////////////////////////////////////////////////////////////////////
/// @brief generates a canceled message
//////////////////////////////////////////////////////////////////////////////
@ -92,6 +89,19 @@ class RestBaseHandler : public rest::HttpHandler {
/// @brief dumps the response as JSON into the response string buffer
//////////////////////////////////////////////////////////////////////////////
protected:
//////////////////////////////////////////////////////////////////////////////
/// @brief checks if velocypack is expected as answer
//////////////////////////////////////////////////////////////////////////////
bool returnVelocypack() const;
//////////////////////////////////////////////////////////////////////////////
/// @brief write result back to client
//////////////////////////////////////////////////////////////////////////////
void writeResult(arangodb::velocypack::Slice const& slice, VPackOptions const& options);
private:
void dumpResponse(arangodb::velocypack::Slice const& slice,
arangodb::velocypack::Options const* options);
};

View File

@ -236,7 +236,6 @@ void RestVocbaseBaseHandler::generate20x(
VPackSlice slice = result.slice();
TRI_ASSERT(slice.isObject() || slice.isArray());
_response->setContentType("application/json; charset=utf-8");
if (slice.isObject()) {
_response->setHeaderNC("etag", "\"" + slice.get(TRI_VOC_ATTRIBUTE_REV).copyString() + "\"");
// pre 1.4 location headers withdrawn for >= 3.0
@ -246,14 +245,9 @@ void RestVocbaseBaseHandler::generate20x(
std::string("/_db/" + _request->databaseName() +
DOCUMENT_PATH + "/" + escapedHandle));
}
VPackStringBufferAdapter buffer(_response->body().stringBuffer());
VPackDumper dumper(&buffer, options);
try {
dumper.dump(slice);
} catch (...) {
generateError(GeneralResponse::ResponseCode::SERVER_ERROR, TRI_ERROR_INTERNAL,
"cannot generate output");
}
writeResult(slice, *options);
}
////////////////////////////////////////////////////////////////////////////////
@ -282,8 +276,7 @@ void RestVocbaseBaseHandler::generatePreconditionFailed(
VPackSlice const& slice) {
createResponse(GeneralResponse::ResponseCode::PRECONDITION_FAILED);
_response->setContentType("application/json; charset=utf-8");
if (slice.isObject()) { // single document case
std::string const rev = VelocyPackHelper::getStringValue(slice, TRI_VOC_ATTRIBUTE_REV, "");
_response->setHeaderNC("etag", "\"" + rev + "\"");
@ -306,16 +299,8 @@ void RestVocbaseBaseHandler::generatePreconditionFailed(
}
}
VPackStringBufferAdapter buffer(_response->body().stringBuffer());
auto transactionContext(StandaloneTransactionContext::Create(_vocbase));
VPackDumper dumper(&buffer, transactionContext->getVPackOptions());
try {
dumper.dump(builder.slice());
} catch (...) {
generateError(GeneralResponse::ResponseCode::SERVER_ERROR, TRI_ERROR_INTERNAL,
"cannot generate output");
}
writeResult(builder.slice(), *(transactionContext->getVPackOptions()));
}
////////////////////////////////////////////////////////////////////////////////
@ -362,34 +347,37 @@ void RestVocbaseBaseHandler::generateDocument(VPackSlice const& document,
// and generate a response
createResponse(GeneralResponse::ResponseCode::OK);
_response->setContentType("application/json; charset=utf-8");
if (!rev.empty()) {
_response->setHeaderNC("etag", "\"" + rev + "\"");
}
if (generateBody) {
VPackStringBufferAdapter buffer(_response->body().stringBuffer());
VPackDumper dumper(&buffer, options);
try {
dumper.dump(document);
} catch (...) {
generateError(GeneralResponse::ResponseCode::SERVER_ERROR, TRI_ERROR_INTERNAL,
"cannot generate output");
}
writeResult(document, *options);
} else {
// TODO can we optimize this?
// Just dump some where else to find real length
StringBuffer tmp(TRI_UNKNOWN_MEM_ZONE);
// convert object to string
VPackStringBufferAdapter buffer(tmp.stringBuffer());
VPackDumper dumper(&buffer, options);
try {
dumper.dump(document);
} catch (...) {
generateError(GeneralResponse::ResponseCode::SERVER_ERROR, TRI_ERROR_INTERNAL,
"cannot generate output");
if(returnVelocypack()){
//TODO REVIEW
_response->setContentType("application/x-velocypack");
_response->headResponse(document.byteSize());
} else {
_response->setContentType("application/json; charset=utf-8");
// TODO can we optimize this?
// Just dump some where else to find real length
StringBuffer tmp(TRI_UNKNOWN_MEM_ZONE);
// convert object to string
VPackStringBufferAdapter buffer(tmp.stringBuffer());
//usual dumping - but not to the response body
VPackDumper dumper(&buffer, options);
try {
dumper.dump(document);
} catch (...) {
generateError(GeneralResponse::ResponseCode::SERVER_ERROR, TRI_ERROR_INTERNAL,
"cannot generate output");
}
// set the length of what would have been written
_response->headResponse(tmp.length());
}
_response->headResponse(tmp.length());
}
}
@ -489,9 +477,9 @@ void RestVocbaseBaseHandler::generateTransactionError(
generateError(GeneralResponse::ResponseCode::FORBIDDEN, res);
return;
}
case TRI_ERROR_OUT_OF_MEMORY:
case TRI_ERROR_LOCK_TIMEOUT:
case TRI_ERROR_OUT_OF_MEMORY:
case TRI_ERROR_LOCK_TIMEOUT:
case TRI_ERROR_DEBUG:
case TRI_ERROR_LOCKED:
case TRI_ERROR_DEADLOCK: {
@ -517,7 +505,7 @@ void RestVocbaseBaseHandler::generateTransactionError(
generateError(GeneralResponse::ResponseCode::FORBIDDEN, result.code,
"collection is read-only");
return;
case TRI_ERROR_ARANGO_UNIQUE_CONSTRAINT_VIOLATED:
generateError(GeneralResponse::ResponseCode::CONFLICT, result.code,
"cannot create document, unique constraint violated");
@ -576,14 +564,14 @@ void RestVocbaseBaseHandler::generateTransactionError(
generateError(GeneralResponse::ResponseCode::NOT_IMPLEMENTED, result.code);
return;
}
case TRI_ERROR_FORBIDDEN: {
generateError(GeneralResponse::ResponseCode::FORBIDDEN, result.code);
return;
}
case TRI_ERROR_OUT_OF_MEMORY:
case TRI_ERROR_LOCK_TIMEOUT:
case TRI_ERROR_OUT_OF_MEMORY:
case TRI_ERROR_LOCK_TIMEOUT:
case TRI_ERROR_DEBUG:
case TRI_ERROR_LOCKED:
case TRI_ERROR_DEADLOCK: {

View File

@ -249,7 +249,7 @@ class RestVocbaseBaseHandler : public RestBaseHandler {
//////////////////////////////////////////////////////////////////////////////
/// @brief generate an error message for a transaction error
//////////////////////////////////////////////////////////////////////////////
void generateTransactionError(OperationResult const&);
//////////////////////////////////////////////////////////////////////////////