iwhd.init.in | 8 +--
rest.c | 119 +++++++++++++++++++++++++++++++++++++++--------------------
t/basic | 3 +
template.c | 45 ++++++++++++++--------
template.h | 3 -
5 files changed, 117 insertions(+), 61 deletions(-)
New commits:
commit 25ef441355c4033adbb36e2780cd5d1795e3458a
Author: Jim Meyering <meyering(a)redhat.com>
Date: Fri Mar 11 21:26:00 2011 +0100
move many decls "down" to where used; no semantic change
diff --git a/rest.c b/rest.c
index dfe3f76..4a74dde 100644
--- a/rest.c
+++ b/rest.c
@@ -200,7 +200,6 @@ proxy_get_cons (void *ctx, uint64_t pos, char *buf, size_t max)
pipe_shared *ps = pp->shared;
my_state *ms = ps->owner;
ssize_t done;
- void *child_res;
(void)pos;
@@ -232,7 +231,7 @@ proxy_get_cons (void *ctx, uint64_t pos, char *buf, size_t max)
}
if (done == (-1)) {
- child_res = NULL;
+ void *child_res = NULL;
pthread_join(ms->backend_th,&child_res);
if (child_res == THREAD_FAILED) {
DPRINTF("GET producer failed\n");
@@ -258,7 +257,6 @@ proxy_get_data (void *cctx, struct MHD_Connection *conn, const char
*url,
pipe_private *pp2;
char *my_etag;
const char *user_etag;
- int rc;
(void)cctx;
(void)method;
@@ -331,7 +329,7 @@ proxy_get_data (void *cctx, struct MHD_Connection *conn, const char
*url,
pp2 = NULL;
}
- rc = pipe_cons_wait_init(&ms->pipe);
+ int rc = pipe_cons_wait_init(&ms->pipe);
ms->rc = (rc == 0) ? MHD_HTTP_OK : MHD_HTTP_INTERNAL_SERVER_ERROR;
resp = MHD_create_response_from_callback(MHD_SIZE_UNKNOWN,
@@ -353,8 +351,7 @@ proxy_get_data (void *cctx, struct MHD_Connection *conn, const char
*url,
static void
recheck_replication (my_state * ms, char *policy)
{
- int rc;
- char fixed[MAX_FIELD_LEN];
+ int rc; /* FIXME: set but never used */
if (is_reserved(ms->key,reserved_name)) {
DPRINTF("declining to replicate reserved object %s\n",ms->key);
@@ -378,6 +375,7 @@ recheck_replication (my_state * ms, char *policy)
}
if (policy) {
+ char fixed[MAX_FIELD_LEN];
DPRINTF(" implementing policy %s\n",policy);
/*
* Can't use ms->url here because it might be a bucket POST
@@ -398,10 +396,7 @@ proxy_put_data (void *cctx, struct MHD_Connection *conn, const char
*url,
{
struct MHD_Response *resp;
my_state *ms = *rctx;
- pipe_private *pp;
int rc;
- char *etag = NULL;
- void *child_res;
(void)cctx;
(void)method;
@@ -428,7 +423,7 @@ proxy_put_data (void *cctx, struct MHD_Connection *conn, const char
*url,
}
ms->size = 0;
pipe_init_shared(&ms->pipe,ms,1);
- pp = pipe_init_private(&ms->pipe);
+ pipe_private *pp = pipe_init_private(&ms->pipe);
if (!pp) {
return MHD_NO;
}
@@ -484,6 +479,8 @@ proxy_put_data (void *cctx, struct MHD_Connection *conn, const char
*url,
*data_size = 0;
}
else {
+ char *etag = NULL;
+ void *child_res;
pipe_prod_finish(&ms->pipe);
pthread_join(ms->backend_th,&child_res);
if (child_res == THREAD_FAILED) {
@@ -502,7 +499,7 @@ proxy_put_data (void *cctx, struct MHD_Connection *conn, const char
*url,
}
else {
etag = meta_did_put(ms->bucket,ms->key,me,
- ms->size);
+ ms->size);
}
DPRINTF("rereplicate (obj PUT)\n");
recheck_replication(ms,NULL);
@@ -856,7 +853,6 @@ proxy_query (void *cctx, struct MHD_Connection *conn, const char
*url,
{
struct MHD_Response *resp;
my_state *ms = *rctx;
- int rc;
(void)cctx;
(void)method;
@@ -898,7 +894,7 @@ proxy_query (void *cctx, struct MHD_Connection *conn, const char
*url,
if (!ms->pipe.data_ptr) {
return MHD_NO;
}
- rc = proxy_query_init(ms, ms->pipe.data_ptr);
+ int rc = proxy_query_init(ms, ms->pipe.data_ptr);
if (rc != MHD_HTTP_OK) {
resp = MHD_create_response_from_data(0,NULL,
MHD_NO,MHD_NO);
@@ -927,7 +923,6 @@ proxy_list_objs (void *cctx, struct MHD_Connection *conn, const char
*url,
{
my_state *ms = *rctx;
struct MHD_Response *resp;
- int rc;
(void)cctx;
(void)url;
@@ -936,7 +931,7 @@ proxy_list_objs (void *cctx, struct MHD_Connection *conn, const char
*url,
(void)data;
(void)data_size;
- rc = proxy_query_init(ms, NULL);
+ int rc = proxy_query_init(ms, NULL);
if (rc != MHD_HTTP_OK) {
resp = MHD_create_response_from_data(0,NULL, MHD_NO,MHD_NO);
MHD_queue_response(conn,rc,resp);
@@ -967,7 +962,6 @@ proxy_delete (void *cctx, struct MHD_Connection *conn, const char
*url,
char *bucket;
char *key;
char *stctx = NULL;
- int rc;
(void)cctx;
(void)method;
@@ -980,8 +974,8 @@ proxy_delete (void *cctx, struct MHD_Connection *conn, const char
*url,
provider_t *main_prov = get_main_provider();
ms->thunk.parent = ms;
ms->thunk.prov = main_prov;
- rc = ms->thunk.prov->func_tbl->delete_func(main_prov,
- ms->bucket,ms->key,url);
+ int rc = ms->thunk.prov->func_tbl->delete_func(main_prov,
+ ms->bucket,ms->key,url);
if (rc == MHD_HTTP_OK) {
copied_url = strdup(url);
assert (copied_url);
@@ -1202,7 +1196,6 @@ post_foreach (void *kvv, void *ms_v)
static int
create_bucket (char *name, my_state *ms)
{
- int rc;
if (is_reserved(name, reserved_name)
|| is_reserved(name, reserved_bucket_name)) {
@@ -1210,7 +1203,7 @@ create_bucket (char *name, my_state *ms)
}
provider_t *main_prov = get_main_provider();
- rc = main_prov->func_tbl->bcreate_func(main_prov,name);
+ int rc = main_prov->func_tbl->bcreate_func(main_prov,name);
if (rc == MHD_HTTP_OK) {
if (meta_set_value(name,"_default", "_policy","0") != 0)
{
DPRINTF("default-policy " "create failed\n");
@@ -1240,7 +1233,6 @@ control_api_root (void *cctx, struct MHD_Connection *conn, const
char *url,
{
struct MHD_Response *resp;
my_state *ms = *rctx;
- int rc;
char *op;
char buf[80];
int len;
@@ -1272,7 +1264,7 @@ control_api_root (void *cctx, struct MHD_Connection *conn, const
char *url,
return MHD_YES;
}
- rc = MHD_HTTP_BAD_REQUEST;
+ int rc = MHD_HTTP_BAD_REQUEST;
op = kv_hash_lookup(ms->dict,"op");
if (op) {
@@ -1312,7 +1304,6 @@ proxy_bucket_post (void *cctx, struct MHD_Connection *conn, const
char *url,
{
struct MHD_Response *resp;
my_state *ms = *rctx;
- int rc;
char *key;
(void)cctx;
@@ -1339,7 +1330,7 @@ proxy_bucket_post (void *cctx, struct MHD_Connection *conn, const
char *url,
*data_size = 0;
}
else {
- rc = MHD_HTTP_BAD_REQUEST;
+ int rc = MHD_HTTP_BAD_REQUEST;
key = kv_hash_lookup(ms->dict,"_key");
if (key) {
strncpy(ms->key,key,MAX_FIELD_LEN-1);
@@ -1518,7 +1509,6 @@ proxy_object_post (void *cctx, struct MHD_Connection *conn, const
char *url,
{
struct MHD_Response *resp;
my_state *ms = *rctx;
- int rc;
char *op;
(void)cctx;
@@ -1545,7 +1535,7 @@ proxy_object_post (void *cctx, struct MHD_Connection *conn, const
char *url,
*data_size = 0;
}
else {
- rc = MHD_HTTP_BAD_REQUEST;
+ int rc = MHD_HTTP_BAD_REQUEST;
if (!kv_find_val(ms->dict,post_find,NULL)) {
op = kv_hash_lookup(ms->dict,"op");
if (op) {
@@ -2035,9 +2025,7 @@ proxy_create_bucket (void *cctx, struct MHD_Connection *conn, const
char *url,
const char *method, const char *version, const char *data,
size_t *data_size, void **rctx)
{
- struct MHD_Response *resp;
my_state *ms = *rctx;
- int rc;
(void)cctx;
(void)method;
@@ -2047,9 +2035,10 @@ proxy_create_bucket (void *cctx, struct MHD_Connection *conn, const
char *url,
(void)url;
/* curl -T moo.empty
http://localhost:9090/_new by accident */
- rc = create_bucket(ms->bucket,ms);
+ int rc = create_bucket(ms->bucket,ms);
- resp = MHD_create_response_from_data(0,NULL,MHD_NO,MHD_NO);
+ struct MHD_Response *resp
+ = MHD_create_response_from_data(0,NULL, MHD_NO,MHD_NO);
if (!resp) {
fprintf(stderr,"MHD_crfd failed\n");
return MHD_NO;
commit 2b7b1b79af54eebdfbb51d80d7094521b20fbbd1
Author: Pete Zaitcev <zaitcev(a)redhat.com>
Date: Thu Mar 10 15:21:19 2011 -0700
Return 404 from non-existing bucket
Maros found that a GET on non-existing bucket returns an empty list
of objects, thus making it impossible to distinguish between a non-exsting
bucket and an empty bucket. This occurs because there is no object that
describes "bucket" as such in database.
However in reality we always have "special" objects, such as the
default replication policy. Therefore, we can distinguish buckets
that do not exist, and have no objects of any kind, and those that
are empty, but actually have "_default" object.
One small difficulty is that the HTTP code has to be known before
the data transfer begins. For this to work, this patch starts the
query before MicroHTTPd response is set up. If we find any keys,
including hidden ones, the bucket is considered existing. Then,
the just-found key is saved for the proxy_query_func to return.
If the query returns nothing, we return 404 to the user.
diff --git a/rest.c b/rest.c
index 84757e9..dfe3f76 100644
--- a/rest.c
+++ b/rest.c
@@ -722,16 +722,18 @@ query_iterator (void *ctx, enum MHD_ValueKind kind, const char
*key,
return MHD_YES;
}
-/* MHD reader function during queries. Return -1 for EOF. */
-static ssize_t
-proxy_query_func (void *ctx, uint64_t pos, char *buf, size_t max)
+static int
+proxy_query_init (my_state *ms, const char *expr)
{
- my_state *ms = ctx;
size_t len;
char *bucket;
char *key;
- (void)pos;
+ ms->query = meta_query_new(ms->bucket,NULL,expr);
+ if (!ms->query) {
+ DPRINTF("failed query\n");
+ return MHD_HTTP_INTERNAL_SERVER_ERROR;
+ }
if (!ms->gen_ctx) {
const char *accept_hdr
@@ -739,23 +741,55 @@ proxy_query_func (void *ctx, uint64_t pos, char *buf, size_t max)
"Accept");
ms->gen_ctx = tmpl_get_ctx(accept_hdr);
if (!ms->gen_ctx) {
- return -1;
+ DPRINTF("failed context\n");
+ return MHD_HTTP_INTERNAL_SERVER_ERROR;
}
len = tmpl_list_header(ms->gen_ctx);
if (!len) {
- return -1;
+ DPRINTF("failed header\n");
+ return MHD_HTTP_INTERNAL_SERVER_ERROR;
}
+ }
+
+ if (!meta_query_next(ms->query,&bucket,&key)) {
+ return MHD_HTTP_NOT_FOUND;
+ }
+ if (is_reserved(key,reserved_name)) {
+ return MHD_HTTP_OK;
+ }
+ len = tmpl_list_entry(ms->gen_ctx,bucket,key);
+ if (!len) {
+ DPRINTF("failed key save\n");
+ return MHD_HTTP_INTERNAL_SERVER_ERROR;
+ }
+ return MHD_HTTP_OK;
+}
+
+/* MHD reader function during queries. Return -1 for EOF. */
+static ssize_t
+proxy_query_func (void *ctx, uint64_t pos, char *buf, size_t max)
+{
+ my_state *ms = ctx;
+ size_t len;
+ char *bucket;
+ char *key;
+
+ (void)pos;
+
+ if (ms->gen_ctx == TMPL_CTX_DONE) {
+ return -1;
+ }
+ if (ms->gen_ctx->len) {
+ len = ms->gen_ctx->len;
if (len > max) {
len = max;
}
memcpy(buf,ms->gen_ctx->buf,len);
+ ms->gen_ctx->buf += len;
+ ms->gen_ctx->len -= len;
return len;
}
- if (ms->gen_ctx == TMPL_CTX_DONE) {
- return -1;
- }
-
for(;;) {
if (!meta_query_next(ms->query,&bucket,&key)) {
break;
@@ -771,6 +805,8 @@ proxy_query_func (void *ctx, uint64_t pos, char *buf, size_t max)
len = max;
}
memcpy(buf,ms->gen_ctx->buf,len);
+ ms->gen_ctx->buf += len;
+ ms->gen_ctx->len -= len;
return len;
}
@@ -820,6 +856,7 @@ proxy_query (void *cctx, struct MHD_Connection *conn, const char
*url,
{
struct MHD_Response *resp;
my_state *ms = *rctx;
+ int rc;
(void)cctx;
(void)method;
@@ -861,7 +898,14 @@ proxy_query (void *cctx, struct MHD_Connection *conn, const char
*url,
if (!ms->pipe.data_ptr) {
return MHD_NO;
}
- ms->query = meta_query_new(ms->bucket,NULL,ms->pipe.data_ptr);
+ rc = proxy_query_init(ms, ms->pipe.data_ptr);
+ if (rc != MHD_HTTP_OK) {
+ resp = MHD_create_response_from_data(0,NULL,
+ MHD_NO,MHD_NO);
+ MHD_queue_response(conn,rc,resp);
+ MHD_destroy_response(resp);
+ return MHD_YES;
+ }
resp = MHD_create_response_from_callback(MHD_SIZE_UNKNOWN,
CB_BLOCK_SIZE, proxy_query_func, ms, simple_closer);
if (!resp) {
@@ -883,6 +927,7 @@ proxy_list_objs (void *cctx, struct MHD_Connection *conn, const char
*url,
{
my_state *ms = *rctx;
struct MHD_Response *resp;
+ int rc;
(void)cctx;
(void)url;
@@ -891,8 +936,13 @@ proxy_list_objs (void *cctx, struct MHD_Connection *conn, const char
*url,
(void)data;
(void)data_size;
- ms->query = meta_query_new((char *)ms->bucket,NULL,NULL);
-
+ rc = proxy_query_init(ms, NULL);
+ if (rc != MHD_HTTP_OK) {
+ resp = MHD_create_response_from_data(0,NULL, MHD_NO,MHD_NO);
+ MHD_queue_response(conn,rc,resp);
+ MHD_destroy_response(resp);
+ return MHD_YES;
+ }
resp = MHD_create_response_from_callback(MHD_SIZE_UNKNOWN,
CB_BLOCK_SIZE, proxy_query_func, ms, simple_closer);
if (!resp) {
diff --git a/t/basic b/t/basic
index e524909..010a1a7 100644
--- a/t/basic
+++ b/t/basic
@@ -88,6 +88,9 @@ test "$(cat FS/b1/obj_test)" = foo || fail=1
curl $bucket/obj_test > f1copy
test "$(cat f1copy)" = foo || fail=1
+# Test that non-existing bucket gives 404 and not 500 or even 200 as before.
+curl -f
http://localhost:$port/no_bucket 2> no_bucket.err
+grep ' 404$' no_bucket.err || fail=1
# Get root; default, then Accept: XML & JSON:
curl
http://localhost:$port > root || fail=1
diff --git a/template.c b/template.c
index 4e2f315..f8fb27a 100644
--- a/template.c
+++ b/template.c
@@ -209,6 +209,7 @@ tmpl_get_ctx (const char *type)
tmp->format = &xml_format;
}
tmp->index = 0;
+ tmp->len = 0;
}
return tmp;
}
@@ -225,6 +226,7 @@ tmpl_root_header (tmpl_ctx_t *ctx, const char *name, const char
*version)
return 0;
}
ctx->buf = ctx->raw_buf;
+ ctx->len = size;
return size;
}
@@ -241,14 +243,15 @@ tmpl_root_entry (tmpl_ctx_t *ctx, const char *rel, const char
*link)
return 0;
}
ctx->buf = ctx->raw_buf;
+ ctx->len = size;
if (size && (ctx->index == 0)) {
ctx->buf += fmt->z_offset;
- size -= fmt->z_offset;
+ ctx->len -= fmt->z_offset;
}
++(ctx->index);
- return size;
+ return ctx->len;
}
size_t
@@ -299,8 +302,10 @@ tmpl_prov_footer (tmpl_ctx_t *ctx)
size_t
tmpl_list_header (tmpl_ctx_t *ctx)
{
- ctx->buf = ctx->format->list_header;
- return strlen(ctx->buf);
+ strcpy(ctx->raw_buf, ctx->format->list_header);
+ ctx->buf = ctx->raw_buf;
+ ctx->len = strlen(ctx->buf);
+ return ctx->len;
}
size_t
@@ -308,20 +313,26 @@ tmpl_list_entry (tmpl_ctx_t *ctx, const char *bucket, const char
*key)
{
int size;
const tmpl_format_t *fmt = ctx->format;
-
- size = snprintf(ctx->raw_buf,TMPL_BUF_SIZE,fmt->list_entry,bucket,key);
- if (size >= TMPL_BUF_SIZE || size < 0) {
+ char *ptr;
+ const char *fmtstr;
+ int max;
+
+ /* tmpl_list_entry is the only thing maybe called on non-empty buf */
+ ptr = ctx->raw_buf + ctx->len;
+ max = TMPL_BUF_SIZE - ctx->len;
+ if (max <= 0) {
return 0;
}
- ctx->buf = ctx->raw_buf;
-
- if (size && (ctx->index == 0)) {
- ctx->buf += fmt->z_offset;
- size -= fmt->z_offset;
+ fmtstr = fmt->list_entry + (ctx->index == 0)*fmt->z_offset;
+ size = snprintf(ptr,max,fmtstr,bucket,key);
+ if (size >= max || size < 0) {
+ return 0;
}
+ ctx->buf = ctx->raw_buf;
+ ctx->len += size;
++(ctx->index);
- return size;
+ return ctx->len;
}
size_t
@@ -344,9 +355,10 @@ tmpl_obj_header (tmpl_ctx_t *ctx, const char *bucket, const char
*key)
return 0;
}
ctx->buf = ctx->raw_buf;
+ ctx->len = size;
++(ctx->index);
- return size;
+ return ctx->len;
}
size_t
@@ -362,14 +374,15 @@ tmpl_obj_entry (tmpl_ctx_t *ctx, const char *bucket, const char
*key,
return 0;
}
ctx->buf = ctx->raw_buf;
+ ctx->len = size;
if (size && (ctx->index == 0)) {
ctx->buf += fmt->z_offset;
- size -= fmt->z_offset;
+ ctx->len -= fmt->z_offset;
}
++(ctx->index);
- return size;
+ return ctx->len;
}
size_t
diff --git a/template.h b/template.h
index b45eb95..4398a60 100644
--- a/template.h
+++ b/template.h
@@ -39,7 +39,8 @@ typedef struct {
const char *base;
unsigned int index;
char raw_buf[TMPL_BUF_SIZE];
- const char *buf;
+ const char *buf;
+ int len;
} tmpl_ctx_t;
#define TMPL_CTX_DONE ((tmpl_ctx_t *)(-1))
commit 88ee0f0dfc5607fed45d7a8ca294503335044696
Author: Jim Meyering <meyering(a)redhat.com>
Date: Fri Mar 11 19:05:12 2011 +0100
maint: avoid new syntax-check failure
* iwhd.init.in: Use "printf %s" in place of "echo -n".
Technically, echo -n is fine, since we know we're using bash,
but it's easier/cleaner to make this change than to exempt
this single file from the failing "make syntax-check".
diff --git a/iwhd.init.in b/iwhd.init.in
index bf57662..59d4032 100644
--- a/iwhd.init.in
+++ b/iwhd.init.in
@@ -68,15 +68,15 @@ start() {
# This is a bit kludgey. We'll use the standard daemon
# framework once iwhd knows how to daemonize itself.
test -f $PIDFILE && kill -0 $(cat $PIDFILE) 2>/dev/null \
- && { echo -n $"$PROCESS appears to already be running"
+ && { printf %s $"$PROCESS appears to already be running"
echo_failure; echo; return 1; }
mkdir -p @localstatedir@/cache/iwhd
rm -rf @localstatedir@/cache/iwhd/*
- echo -n $"waiting for mongod to listen on $MONGOD_SERVER_SPEC"
+ printf %s $"waiting for mongod to listen on $MONGOD_SERVER_SPEC"
wait_for_mongod $MONGOD_N_SECONDS && echo_success || echo_failure
echo
- echo -n $"Starting $SERVICE daemon: "
+ printf %s $"Starting $SERVICE daemon: "
$PROCESS -c "$CONFIG_JS" $IWHD_ARGS > /var/log/iwhd.log 2>&1
&
pid=$!
RETVAL=$?
@@ -106,7 +106,7 @@ restart() {
}
reload() {
- echo -n $"Reloading $SERVICE configuration: "
+ printf %s $"Reloading $SERVICE configuration: "
killproc -p $PIDFILE $PROCESS -HUP
RETVAL=$?