1
0
Fork 0

Merge pull request #1798 from ObiWahn/devel

optional velocypack response
This commit is contained in:
Jan 2016-04-12 18:27:08 +02:00
commit 7cd428c367
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()); generateError(GeneralResponse::responseCode(ex.code()), ex.code(), ex.what());
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief generates a result from VelocyPack /// @brief generates a result from VelocyPack
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void RestBaseHandler::generateResult(GeneralResponse::ResponseCode code, void RestBaseHandler::generateResult(GeneralResponse::ResponseCode code,
VPackSlice const& slice) { 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, VPackSlice const& slice,
std::shared_ptr<TransactionContext> context) { std::shared_ptr<TransactionContext> context) {
createResponse(code); createResponse(code);
_response->setContentType("application/json; charset=utf-8"); writeResult(slice,*(context->getVPackOptions()));
dumpResponse(slice, context->getVPackOptions());
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -90,7 +89,6 @@ void RestBaseHandler::generateError(GeneralResponse::ResponseCode code,
void RestBaseHandler::generateError(GeneralResponse::ResponseCode code, void RestBaseHandler::generateError(GeneralResponse::ResponseCode code,
int errorCode, std::string const& message) { int errorCode, std::string const& message) {
createResponse(code); createResponse(code);
_response->setContentType("application/json; charset=utf-8");
VPackBuilder builder; VPackBuilder builder;
try { try {
@ -106,7 +104,7 @@ void RestBaseHandler::generateError(GeneralResponse::ResponseCode code,
builder.add("errorNum", VPackValue(errorCode)); builder.add("errorNum", VPackValue(errorCode));
builder.close(); builder.close();
dumpResponse(builder.slice(), &VPackOptions::Defaults); writeResult(builder.slice(), VPackOptions::Defaults);
} catch (...) { } catch (...) {
// Building the error response failed // 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,11 +44,8 @@ class RestBaseHandler : public rest::HttpHandler {
public: public:
explicit RestBaseHandler(HttpRequest* request); explicit RestBaseHandler(HttpRequest* request);
public:
void handleError(basics::Exception const&) override; void handleError(basics::Exception const&) override;
public:
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
/// @brief generates a result from VelocyPack /// @brief generates a result from VelocyPack
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -92,6 +89,19 @@ class RestBaseHandler : public rest::HttpHandler {
/// @brief dumps the response as JSON into the response string buffer /// @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, void dumpResponse(arangodb::velocypack::Slice const& slice,
arangodb::velocypack::Options const* options); arangodb::velocypack::Options const* options);
}; };

View File

@ -236,7 +236,6 @@ void RestVocbaseBaseHandler::generate20x(
VPackSlice slice = result.slice(); VPackSlice slice = result.slice();
TRI_ASSERT(slice.isObject() || slice.isArray()); TRI_ASSERT(slice.isObject() || slice.isArray());
_response->setContentType("application/json; charset=utf-8");
if (slice.isObject()) { if (slice.isObject()) {
_response->setHeaderNC("etag", "\"" + slice.get(TRI_VOC_ATTRIBUTE_REV).copyString() + "\""); _response->setHeaderNC("etag", "\"" + slice.get(TRI_VOC_ATTRIBUTE_REV).copyString() + "\"");
// pre 1.4 location headers withdrawn for >= 3.0 // pre 1.4 location headers withdrawn for >= 3.0
@ -246,14 +245,9 @@ void RestVocbaseBaseHandler::generate20x(
std::string("/_db/" + _request->databaseName() + std::string("/_db/" + _request->databaseName() +
DOCUMENT_PATH + "/" + escapedHandle)); DOCUMENT_PATH + "/" + escapedHandle));
} }
VPackStringBufferAdapter buffer(_response->body().stringBuffer());
VPackDumper dumper(&buffer, options); writeResult(slice, *options);
try {
dumper.dump(slice);
} catch (...) {
generateError(GeneralResponse::ResponseCode::SERVER_ERROR, TRI_ERROR_INTERNAL,
"cannot generate output");
}
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -282,7 +276,6 @@ void RestVocbaseBaseHandler::generatePreconditionFailed(
VPackSlice const& slice) { VPackSlice const& slice) {
createResponse(GeneralResponse::ResponseCode::PRECONDITION_FAILED); createResponse(GeneralResponse::ResponseCode::PRECONDITION_FAILED);
_response->setContentType("application/json; charset=utf-8");
if (slice.isObject()) { // single document case if (slice.isObject()) { // single document case
std::string const rev = VelocyPackHelper::getStringValue(slice, TRI_VOC_ATTRIBUTE_REV, ""); std::string const rev = VelocyPackHelper::getStringValue(slice, TRI_VOC_ATTRIBUTE_REV, "");
@ -306,16 +299,8 @@ void RestVocbaseBaseHandler::generatePreconditionFailed(
} }
} }
VPackStringBufferAdapter buffer(_response->body().stringBuffer());
auto transactionContext(StandaloneTransactionContext::Create(_vocbase)); auto transactionContext(StandaloneTransactionContext::Create(_vocbase));
VPackDumper dumper(&buffer, transactionContext->getVPackOptions()); writeResult(builder.slice(), *(transactionContext->getVPackOptions()));
try {
dumper.dump(builder.slice());
} catch (...) {
generateError(GeneralResponse::ResponseCode::SERVER_ERROR, TRI_ERROR_INTERNAL,
"cannot generate output");
}
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -362,26 +347,27 @@ void RestVocbaseBaseHandler::generateDocument(VPackSlice const& document,
// and generate a response // and generate a response
createResponse(GeneralResponse::ResponseCode::OK); createResponse(GeneralResponse::ResponseCode::OK);
_response->setContentType("application/json; charset=utf-8");
if (!rev.empty()) { if (!rev.empty()) {
_response->setHeaderNC("etag", "\"" + rev + "\""); _response->setHeaderNC("etag", "\"" + rev + "\"");
} }
if (generateBody) { if (generateBody) {
VPackStringBufferAdapter buffer(_response->body().stringBuffer()); writeResult(document, *options);
VPackDumper dumper(&buffer, options);
try {
dumper.dump(document);
} catch (...) {
generateError(GeneralResponse::ResponseCode::SERVER_ERROR, TRI_ERROR_INTERNAL,
"cannot generate output");
}
} else { } else {
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? // TODO can we optimize this?
// Just dump some where else to find real length // Just dump some where else to find real length
StringBuffer tmp(TRI_UNKNOWN_MEM_ZONE); StringBuffer tmp(TRI_UNKNOWN_MEM_ZONE);
// convert object to string // convert object to string
VPackStringBufferAdapter buffer(tmp.stringBuffer()); VPackStringBufferAdapter buffer(tmp.stringBuffer());
//usual dumping - but not to the response body
VPackDumper dumper(&buffer, options); VPackDumper dumper(&buffer, options);
try { try {
dumper.dump(document); dumper.dump(document);
@ -389,9 +375,11 @@ void RestVocbaseBaseHandler::generateDocument(VPackSlice const& document,
generateError(GeneralResponse::ResponseCode::SERVER_ERROR, TRI_ERROR_INTERNAL, generateError(GeneralResponse::ResponseCode::SERVER_ERROR, TRI_ERROR_INTERNAL,
"cannot generate output"); "cannot generate output");
} }
// set the length of what would have been written
_response->headResponse(tmp.length()); _response->headResponse(tmp.length());
} }
} }
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief generate an error message for a transaction error /// @brief generate an error message for a transaction error