From 0ed8a2275a3a6cda553b82e9e0222b9d3b8b3ff2 Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Fri, 23 Jan 2015 12:45:51 +0200 Subject: Implement HTTP POST * NEWS: Update. * doc/eclat.conf.5: Document http-method. Reorganize description of endpoints and regions. * lib/libeclat.h (ec2_request) : New member (eclat_request_finalize): New proto. * lib/req2url.c (eclat_request_to_url): Remove second argument. All uses changed. (eclat_request_finalize): New function. * lib/reqfree.c: Free postdata. * lib/reqsign.c (requestsign4): Implement post. * src/config.c: New configuration statement http-method. * src/eclat.c (use_post): New variable. * src/eclat.h (use_post): New extern. * src/util.c (eclat_send_request): Implement post. --- lib/libeclat.h | 12 +++++++----- lib/req2url.c | 52 ++++++++++++++++++++++++++++------------------------ lib/reqfree.c | 1 + lib/reqsign.c | 4 +--- 4 files changed, 37 insertions(+), 32 deletions(-) (limited to 'lib') diff --git a/lib/libeclat.h b/lib/libeclat.h index a5c8c79..b33f0a2 100644 --- a/lib/libeclat.h +++ b/lib/libeclat.h @@ -94,6 +94,7 @@ struct ec2_request { char *uri; /* URI without parameters */ struct grecs_symtab *params; /* Query parameters */ struct grecs_list *headers; /* Query headers */ + char *postdata; char *region; char *access_key; char *token; @@ -104,18 +105,19 @@ struct ec2_request *eclat_request_create(int flags, const char *endpoint, const char *uri, char const *region, char const *access_key, char const *token); void eclat_request_free(struct ec2_request *); -void eclat_request_add_param(struct ec2_request *q, const char *name, +void eclat_request_add_param(struct ec2_request *req, const char *name, const char *value); -void eclat_request_add_param_encoded(struct ec2_request *q, const char *name, +void eclat_request_add_param_encoded(struct ec2_request *req, const char *name, const char *value); -void eclat_request_add_header(struct ec2_request *q, const char *name, +void eclat_request_add_header(struct ec2_request *req, const char *name, const char *value); void eclat_request_sign(struct ec2_request *req, char *secret, char *version); -char *eclat_request_to_url(struct ec2_request *req, char **post_params); +char *eclat_request_to_url(struct ec2_request *req); -void eclat_request_encode(struct ec2_request *q); +void eclat_request_encode(struct ec2_request *req); +void eclat_request_finalize(struct ec2_request *req); typedef struct eclat_partial_tree *eclat_partial_tree_t; diff --git a/lib/req2url.c b/lib/req2url.c index 25277a2..b9d7512 100644 --- a/lib/req2url.c +++ b/lib/req2url.c @@ -21,7 +21,7 @@ struct param_closure { struct grecs_txtacc *acc; - int count; + int delim; }; static int @@ -30,23 +30,22 @@ add_param(void *sym, void *data) struct ec2_param *p = sym; struct param_closure *pc = data; - if (pc->count) - grecs_txtacc_grow_char(pc->acc, '&'); - ++pc->count; + if (pc->delim) + grecs_txtacc_grow_char(pc->acc, pc->delim); + pc->delim = '&'; grecs_txtacc_grow_string(pc->acc, p->name); if (p->value) { grecs_txtacc_grow_char(pc->acc, '='); grecs_txtacc_grow_string(pc->acc, p->value); - } - + } return 0; } char * -eclat_request_to_url(struct ec2_request *req, char **post_params) +eclat_request_to_url(struct ec2_request *req) { struct grecs_txtacc *acc; - char *ret = NULL, *p; + char *url = NULL; struct param_closure pc; acc = grecs_txtacc_create(); @@ -58,27 +57,32 @@ eclat_request_to_url(struct ec2_request *req, char **post_params) grecs_txtacc_grow(acc, req->endpoint, strlen(req->endpoint)); grecs_txtacc_grow(acc, req->uri, strlen(req->uri)); - if (req->flags & EC2_RF_POST) { - grecs_txtacc_grow_char(acc, 0); - ret = grecs_txtacc_finish(acc, 1); - } else { - grecs_txtacc_grow_char(acc, '?'); - } - - /* Add other parameters */ + /* Add parameters */ pc.acc = acc; - pc.count = 0; + pc.delim = '?'; grecs_symtab_enumerate(req->params, add_param, &pc); grecs_txtacc_grow_char(acc, 0); - - if (!ret) - ret = grecs_txtacc_finish(acc, 1); - else - *post_params = grecs_txtacc_finish(acc, 1); - + url = grecs_txtacc_finish(acc, 1); grecs_txtacc_free(acc); - return ret; + return url; } +void +eclat_request_finalize(struct ec2_request *req) +{ + struct param_closure pc; + + if (!(req->flags & EC2_RF_POST) || req->postdata) + return; + + eclat_request_encode(req); + pc.acc = grecs_txtacc_create(); + pc.delim = 0; + grecs_symtab_enumerate(req->params, add_param, &pc); + grecs_txtacc_grow_char(pc.acc, 0); + req->postdata = grecs_txtacc_finish(pc.acc, 1); + grecs_txtacc_free(pc.acc); + grecs_symtab_clear(req->params); +} diff --git a/lib/reqfree.c b/lib/reqfree.c index f5145a4..ee0611e 100644 --- a/lib/reqfree.c +++ b/lib/reqfree.c @@ -23,6 +23,7 @@ eclat_request_free(struct ec2_request *req) { free(req->endpoint); free(req->uri); + free(req->postdata); grecs_symtab_free(req->params); free(req); } diff --git a/lib/reqsign.c b/lib/reqsign.c index f3083c6..9572961 100644 --- a/lib/reqsign.c +++ b/lib/reqsign.c @@ -252,9 +252,7 @@ requestsign4(struct ec2_request *req, char *secret) grecs_txtacc_grow_char(acc, '\n'); /* Payload hash */ if (req->flags & EC2_RF_POST) { - /* FIXME: payload = req->request */ - err("%s:%d: POST is not yet implemented", __FILE__, __LINE__); - abort(); + payload = req->postdata; } else payload = ""; -- cgit v1.2.1