1
0
Fork 0

issue #193: REST API HEAD request returns a message body on 404

This commit is contained in:
Jan Steemann 2012-09-11 00:11:26 +02:00
parent f812c6bd04
commit f8deb40580
5 changed files with 162 additions and 7 deletions

View File

@ -1,8 +1,10 @@
not released yet
----------------
* fixed issue #193: REST API HEAD request returns a message body on 404
* fixed issue #188: intermittent issues with 1.0.0
(server-side cursors not cleaned up in all cases)
(server-side cursors not cleaned up in all cases, pthreads deadlock issue)
* issue #189: key store should use ISO datetime format bug

View File

@ -0,0 +1,122 @@
# coding: utf-8
require 'rspec'
require './arangodb.rb'
describe ArangoDB do
prefix = "api-http"
context "dealing with HTTP methods:" do
################################################################################
## checking HTTP HEAD responses
################################################################################
context "head requests" do
before do
end
after do
end
it "checks whether HEAD returns a body on 2xx" do
cmd = "/_api/version"
doc = ArangoDB.log_head("#{prefix}-head-supported-method", cmd)
doc.code.should eq(200)
doc.response.body.should be_nil
end
it "checks whether HEAD returns a body on 3xx" do
cmd = "/_api/collection"
doc = ArangoDB.log_head("#{prefix}-head-unsupported-method1", cmd)
doc.code.should eq(405)
doc.response.body.should be_nil
end
it "checks whether HEAD returns a body on 4xx" do
cmd = "/_api/cursor"
doc = ArangoDB.log_head("#{prefix}-head-unsupported-method2", cmd)
doc.code.should eq(405)
doc.response.body.should be_nil
end
it "checks whether HEAD returns a body on 5xx" do
cmd = "/_api/non-existing-method"
doc = ArangoDB.log_head("#{prefix}-head-non-existing-method", cmd)
doc.code.should eq(501)
doc.response.body.should be_nil
end
it "checks whether HEAD returns a body on an existing document" do
cn = "UnitTestsCollectionHttp"
ArangoDB.drop_collection(cn)
# create collection with one document
@cid = ArangoDB.create_collection(cn)
cmd = "/_api/document?collection=#{@cid}"
body = "{ \"Hello\" : \"World\" }"
doc = ArangoDB.log_post("#{prefix}", cmd, :body => body)
did = doc.parsed_response['_id']
did.should be_kind_of(String)
# run a HTTP HEAD query on the existing document
cmd = "/_api/document/" + did
doc = ArangoDB.log_head("#{prefix}-head-check-documentq", cmd)
doc.code.should eq(200)
doc.response.body.should be_nil
# run a HTTP HEAD query on the existing document, with wrong precondition
cmd = "/_api/document/" + did
doc = ArangoDB.log_head("#{prefix}-head-check-documentq", cmd, :header => { :"if-match" => "1" })
doc.code.should eq(200)
doc.response.body.should be_nil
ArangoDB.drop_collection(cn)
end
end
################################################################################
## checking HTTP GET responses
################################################################################
context "get requests" do
before do
end
after do
end
it "checks whether GET returns a body" do
cmd = "/_api/non-existing-method"
doc = ArangoDB.log_get("#{prefix}-get-non-existing-method", cmd)
doc.code.should eq(501)
doc.headers['content-type'].should eq("application/json; charset=utf-8")
doc.parsed_response['error'].should eq(true)
doc.parsed_response['errorNum'].should eq(9)
doc.parsed_response['code'].should eq(501)
end
it "checks whether GET returns a body" do
cmd = "/_api/non-allowed-method"
doc = ArangoDB.log_get("#{prefix}-get-non-allowed-method", cmd)
doc.code.should eq(501)
doc.headers['content-type'].should eq("application/json; charset=utf-8")
doc.parsed_response['error'].should eq(true)
doc.parsed_response['errorNum'].should eq(9)
doc.parsed_response['code'].should eq(501)
end
end
end
end

View File

@ -2,6 +2,7 @@
test -d logs || mkdir logs
rspec --format d \
api-http-spec.rb \
api-collection-spec.rb \
rest-create-document-spec.rb \
rest-read-document-spec.rb \

View File

@ -89,7 +89,8 @@ namespace triagens {
ConnectionInfo const& info,
double keepAliveTimeout)
: Task("HttpCommTask"),
GeneralCommTask<S, HttpHandlerFactory>(server, fd, info, keepAliveTimeout) {
GeneralCommTask<S, HttpHandlerFactory>(server, fd, info, keepAliveTimeout),
_requestType(HttpRequest::HTTP_REQUEST_ILLEGAL) {
ConnectionStatisticsAgentSetHttp(this);
ConnectionStatisticsAgent::release();
@ -180,8 +181,12 @@ namespace triagens {
// set body start to current position
this->_bodyPosition = this->_readPosition;
// and different methods
switch (this->_request->requestType()) {
// store the original request's type. we need it later when responding
// (original request objects gets deleted before responding)
this->_requestType = this->_request->requestType();
// handle different HTTP methods
switch (this->_requestType) {
case HttpRequest::HTTP_REQUEST_GET:
case HttpRequest::HTTP_REQUEST_DELETE:
case HttpRequest::HTTP_REQUEST_HEAD:
@ -359,10 +364,17 @@ namespace triagens {
// keep-alive is the default
response->setHeader("connection", strlen("connection"), "Keep-Alive");
}
if (this->_requestType == HttpRequest::HTTP_REQUEST_HEAD) {
// clear body if this is an HTTP HEAD request
// HEAD must not return a body
response->headResponse(response->bodySize());
}
// save header
buffer = new triagens::basics::StringBuffer(TRI_UNKNOWN_MEM_ZONE);
response->writeHeader(buffer);
buffer->appendText(response->body());
this->_writeBuffers.push_back(buffer);
@ -381,6 +393,23 @@ namespace triagens {
// start output
this->fillWriteBuffer();
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- private variables
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup HttpServer
/// @{
////////////////////////////////////////////////////////////////////////////////
private:
HttpRequest::HttpRequestType _requestType;
};
}
}

View File

@ -28,6 +28,7 @@
#include "HttpResponse.h"
#include "BasicsC/strings.h"
#include "Basics/StringUtils.h"
#include "Logger/Logger.h"
#include "ProtocolBuffers/arangodb.pb.h"
@ -532,11 +533,11 @@ void HttpResponse::writeHeader (StringBuffer* output) {
}
// ignore content-length
if (*key == 'c' && (strcmp(key, "content-length") == 0)) {
if (*key == 'c' && TRI_EqualString(key, "content-length")) {
continue;
}
if (*key == 't' && (strcmp(key, "transfer-encoding") == 0)) {
if (*key == 't' && TRI_EqualString(key, "transfer-encoding")) {
seenTransferEncoding = true;
transferEncoding = begin->_value;
continue;
@ -559,7 +560,7 @@ void HttpResponse::writeHeader (StringBuffer* output) {
output->appendText(transferEncoding);
output->appendText("\r\n");
}
output->appendText("content-length: ");
if (_isHeadResponse) {