From: Jeff Garzik <jeff@garzik.org>
To: hail-devel@vger.kernel.org
Subject: [PATCH] tabled: use httpstor API from libhail
Date: Wed, 7 Jul 2010 18:38:22 -0400 [thread overview]
Message-ID: <20100707223822.GA25328@havoc.gtf.org> (raw)
Just committed the following to tabled.git on my local laptop, on a side
branch. This won't be pushed onto the main tabled branch until Friday,
to give people time to convert as zaitcev suggested in the 'new hail
repository' thread.
As a side note, this requires a couple hail.git commits that will be
pushed to upstream hail.git from my local laptop in a couple hours
(movement of uri_parse from tabled's libhttpstor into libhail), so
you'll need to update hail.git before being able to use the patch below.
commit d4cfbcac3f00088cf38df2834a880f7e75ca6f0b
Author: Jeff Garzik <jgarzik@pobox.com>
Date: Wed Jul 7 18:29:26 2010 -0400
Link with libhail, eliminating much local code.
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
.gitignore | 9
autogen.sh | 6
configure.ac | 32 -
include/Makefile.am | 2
include/httpstor.h | 100 ----
include/httputil.h | 84 ---
lib/.gitignore | 10
lib/Makefile.am | 23
lib/httpstor.c | 944 --------------------------------------
lib/httputil.c | 366 --------------
lib/libhttpstor-uninstalled.pc.in | 12
lib/libhttpstor.pc.in | 13
lib/uri.c | 289 -----------
server/.gitignore | 4
server/Makefile.am | 2
server/bucket.c | 18
server/object.c | 34 -
server/server.c | 30 -
server/status.c | 6
server/tabled.h | 2
test/Makefile.am | 9
test/basic-bucket.c | 29 -
test/basic-object.c | 19
test/hdr-content-type.c | 23
test/hdr-meta.c | 23
test/it-works.c | 17
test/large-object.c | 27 -
test/libtest.c | 36 +
test/test.h | 3
test/wait-for-listen.c | 1
30 files changed, 165 insertions(+), 2008 deletions(-)
diff --git a/.gitignore b/.gitignore
index f9d8404..704329c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,15 +19,6 @@ install-sh
missing
push
stamp-h1
-libtool
-ltmain.sh
-
-# app-specific
-tabled
-tdbadm
-
-libtabled.a
-libtdb.a
tabled*.tar.gz
tabled-config.h*
diff --git a/autogen.sh b/autogen.sh
index 949dbd3..989604a 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -5,12 +5,8 @@
set -e
-# libtoolize needs to be run twice, for some reason
-# to avoid errors relating to ltmain.sh installation
-
-libtoolize --force
aclocal
autoheader
automake --gnu --add-missing --copy
autoconf
-libtoolize --force
+
diff --git a/configure.ac b/configure.ac
index 6112a6b..dbd438d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -17,21 +17,6 @@ dnl You should have received a copy of the GNU General Public License
dnl along with this program; if not, write to the Free Software
dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-m4_define([libhttpstor_major_version], [1])
-m4_define([libhttpstor_minor_version], [1])
-m4_define([libhttpstor_micro_version], [1])
-m4_define([libhttpstor_interface_age], [1])
-# If you need a modifier for the version number.
-# Normally empty, but can be used to make "fixup" releases.
-m4_define([libhttpstor_extraversion], [])
-
-dnl libtool versioning from libhttpstor
-m4_define([libhttpstor_current], [m4_eval(100 * libhttpstor_minor_version + libhttpstor_micro_version - libhttpstor_interface_age)])
-m4_define([libhttpstor_binary_age], [m4_eval(100 * libhttpstor_minor_version + libhttpstor_micro_version)])
-m4_define([libhttpstor_revision], [libhttpstor_interface_age])
-m4_define([libhttpstor_age], [m4_eval(libhttpstor_binary_age - libhttpstor_interface_age)])
-m4_define([libhttpstor_version], [libhttpstor_major_version().libhttpstor_minor_version().libhttpstor_micro_version()libhttpstor_extraversion()])
-
AC_INIT([tabled], [0.5],
[http://hail.wiki.kernel.org/])
@@ -40,26 +25,13 @@ AC_CONFIG_SRCDIR([server/server.c])
AM_INIT_AUTOMAKE([gnu])
AC_CONFIG_HEADERS([tabled-config.h])
-LIBHTTPSTOR_MAJOR_VERSION=libhttpstor_major_version
-LIBHTTPSTOR_MINOR_VERSION=libhttpstor_minor_version
-LIBHTTPSTOR_MICRO_VERSION=libhttpstor_micro_version
-LIBHTTPSTOR_INTERFACE_AGE=libhttpstor_interface_age
-
-LIBHTTPSTOR_CURRENT=libhttpstor_current
-LIBHTTPSTOR_REVISION=libhttpstor_revision
-LIBHTTPSTOR_AGE=libhttpstor_age
-
-AC_SUBST(LIBHTTPSTOR_CURRENT)
-AC_SUBST(LIBHTTPSTOR_REVISION)
-AC_SUBST(LIBHTTPSTOR_AGE)
-
dnl Make sure anyone changing configure.ac/Makefile.am has a clue
AM_MAINTAINER_MODE
dnl Checks for programs
AC_PROG_CC
AC_PROG_GCC_TRADITIONAL
-AM_PROG_LIBTOOL
+AC_PROG_RANLIB
PKG_PROG_PKG_CONFIG
dnl Checks for header files.
@@ -119,8 +91,6 @@ dnl AC_SUBST(CHUNKDC_LIBS)
AC_CONFIG_FILES([doc/Makefile
lib/Makefile
- lib/libhttpstor.pc
- lib/libhttpstor-uninstalled.pc
include/Makefile
server/Makefile
test/Makefile
diff --git a/include/Makefile.am b/include/Makefile.am
index 163f7f8..4613c6f 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -1,5 +1,3 @@
-include_HEADERS = httpstor.h
-
EXTRA_DIST = elist.h httputil.h tdb.h
diff --git a/include/httpstor.h b/include/httpstor.h
deleted file mode 100644
index 07a0111..0000000
--- a/include/httpstor.h
+++ /dev/null
@@ -1,100 +0,0 @@
-#ifndef __HTTPSTOR_H__
-#define __HTTPSTOR_H__
-
-/*
- * Copyright 2008-2009 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-
-#include <stdbool.h>
-#include <stdint.h>
-#include <curl/curl.h>
-#include <glib.h>
-
-struct httpstor_client {
- CURL *curl;
- char *acc;
- char *host;
- char *user;
- char *key;
- bool verbose;
-};
-
-struct httpstor_bucket {
- char *name;
- char *time_create;
-};
-
-struct httpstor_blist {
- char *own_id; /* ID */
- char *own_name; /* DisplayName */
- GList *list; /* list of httpstor_bucket */
-};
-
-struct httpstor_object {
- char *key;
- char *time_mod;
- char *etag;
- uint64_t size;
- char *storage;
- char *own_id;
- char *own_name;
-};
-
-struct httpstor_keylist {
- char *name;
- char *prefix;
- char *marker;
- char *delim;
- unsigned int max_keys;
- bool trunc;
- GList *contents;
- GList *common_pfx;
-};
-
-extern void httpstor_free(struct httpstor_client *httpstor);
-extern void httpstor_free_blist(struct httpstor_blist *blist);
-extern void httpstor_free_bucket(struct httpstor_bucket *buck);
-extern void httpstor_free_object(struct httpstor_object *obj);
-extern void httpstor_free_keylist(struct httpstor_keylist *keylist);
-
-extern struct httpstor_client *httpstor_new(const char *service_acc,
- const char *service_host, const char *user, const char *secret_key);
-
-extern bool httpstor_add_bucket(struct httpstor_client *httpstor, const char *name);
-extern bool httpstor_del_bucket(struct httpstor_client *httpstor, const char *name);
-
-extern struct httpstor_blist *httpstor_list_buckets(struct httpstor_client *httpstor);
-
-extern bool httpstor_get(struct httpstor_client *httpstor, const char *bucket, const char *key,
- size_t (*write_cb)(void *, size_t, size_t, void *),
- void *user_data, bool want_headers);
-extern void *httpstor_get_inline(struct httpstor_client *httpstor, const char *bucket,
- const char *key, bool want_headers, size_t *len);
-extern bool httpstor_put(struct httpstor_client *httpstor, const char *bucket, const char *key,
- size_t (*read_cb)(void *, size_t, size_t, void *),
- uint64_t len, void *user_data, char **user_hdrs);
-extern bool httpstor_put_inline(struct httpstor_client *httpstor, const char *bucket,
- const char *key, void *data, uint64_t len,
- char **user_hdrs);
-extern bool httpstor_del(struct httpstor_client *httpstor, const char *bucket, const char *key);
-
-extern struct httpstor_keylist *httpstor_keys(struct httpstor_client *httpstor, const char *bucket,
- const char *prefix, const char *marker,
- const char *delim, unsigned int max_keys);
-
-#endif /* __HTTPSTOR_H__ */
diff --git a/include/httputil.h b/include/httputil.h
index b2e8f30..dfbdd4b 100644
--- a/include/httputil.h
+++ b/include/httputil.h
@@ -26,91 +26,7 @@
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif
-#define PATH_ESCAPE_MASK 0x02
-#define QUERY_ESCAPE_MASK 0x04
-
-enum {
- REQ_MAX_HDR = 128, /* max hdrs per req */
-};
-
-struct uri {
- char *scheme;
- unsigned int scheme_len;
- char *userinfo;
- unsigned int userinfo_len;
- char *hostname;
- unsigned int hostname_len;
-
- unsigned int port;
-
- char *path;
- unsigned int path_len;
- char *query;
- unsigned int query_len;
- char *fragment;
- unsigned int fragment_len; /* see FIXME in uri.c */
-};
-
-struct http_hdr {
- char *key;
- char *val;
-};
-
-struct http_req {
- char *method; /* GET, POST, etc. */
- struct uri uri; /* URI */
- int major; /* HTTP version */
- int minor;
-
- char *orig_path;
-
- unsigned int n_hdr; /* list of headers */
- struct http_hdr hdr[REQ_MAX_HDR];
-};
-
-enum ReqQ {
- URIQ_ACL,
- URIQ_LOCATION,
- URIQ_LOGGING,
- URIQ_TORRENT,
- URIQNUM
-};
-
-enum ReqACLC {
- ACLC_PRIV,
- ACLC_PUB_R,
- ACLC_PUB_RW,
- ACLC_AUTH_R,
- ACLCNUM
-};
-
-/* httputil.c */
-extern char *time2str(char *buf, int len, time_t time);
-extern time_t str2time(const char *timestr);
-extern int req_hdr_push(struct http_req *req, char *key, char *val);
-extern char *req_hdr(struct http_req *req, const char *key);
-extern void req_sign(struct http_req *req, const char *bucket, const char *key,
- char *b64hmac_out);
-extern GHashTable *req_query(struct http_req *req);
-extern int req_is_query(struct http_req *req);
-extern void req_free(struct http_req *req);
-extern int req_acl_canned(struct http_req *req);
-
-/* uri.c */
-extern struct uri *uri_parse(struct uri *uri_dest, char *uri_src_text);
-extern int field_unescape(char *s, int s_len);
-extern char* field_escape (char *signed_str, unsigned char mask);
-
/* readport.c */
extern int tb_readport(const char *fname, char *buf, size_t len);
-static inline bool http11(struct http_req *req)
-{
- if (req->major > 1)
- return true;
- if (req->major == 1 && req->minor > 0)
- return true;
- return false;
-}
-
#endif /* __HTTPUTIL_H__ */
diff --git a/lib/.gitignore b/lib/.gitignore
index 43107ca..aa396d7 100644
--- a/lib/.gitignore
+++ b/lib/.gitignore
@@ -1,7 +1,3 @@
-*.lo
-*.la
-.libs
-libhttputil.a
-libhttpstor.a
-libhttpstor-uninstalled.pc
-libhttpstor.pc
+
+libtdb.a
+
diff --git a/lib/Makefile.am b/lib/Makefile.am
index e22a490..12ee6c1 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -1,27 +1,8 @@
INCLUDES = -I$(top_srcdir)/include \
- @LIBCURL_CPPFLAGS@ @GLIB_CFLAGS@ @XML_CPPFLAGS@
+ @GLIB_CFLAGS@
-noinst_LIBRARIES = libhttputil.a libtdb.a
-
-libhttputil_a_SOURCES = httputil.c uri.c readport.c
+noinst_LIBRARIES = libtdb.a
libtdb_a_SOURCES = tdb.c
-EXTRA_DIST =
- libhttpstor.pc.in libhttpstor-uninstalled.pc.in
-
-LINK = $(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(LDFLAGS) -o $@
-
-lib_LTLIBRARIES = libhttpstor.la
-
-libhttpstor_la_SOURCES = httpstor.c
-
-libhttpstor_la_LDFLAGS = \
- -version-info $(LIBHTTPSTOR_CURRENT):$(LIBHTTPSTOR_REVISION):$(LIBHTTPSTOR_AGE) \
- -no-undefined \
- -export-symbols-regex "^[^_].*"
-
-pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = libhttpstor.pc
-
diff --git a/lib/httpstor.c b/lib/httpstor.c
deleted file mode 100644
index b024cad..0000000
--- a/lib/httpstor.c
+++ /dev/null
@@ -1,944 +0,0 @@
-
-/*
- * Copyright 2008-2009 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#define _GNU_SOURCE
-#include "tabled-config.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <curl/curl.h>
-#include <openssl/hmac.h>
-#include <libxml/tree.h>
-#include <glib.h>
-#include <httpstor.h>
-#include <httputil.h>
-
-static int _strcasecmp(const unsigned char *a, const char *b)
-{
- return xmlStrcasecmp(a, (const unsigned char *) b);
-}
-
-static int _strcmp(const unsigned char *a, const char *b)
-{
- return xmlStrcmp(a, (const unsigned char *) b);
-}
-
-void httpstor_free(struct httpstor_client *httpstor)
-{
- if (httpstor->curl)
- curl_easy_cleanup(httpstor->curl);
- free(httpstor->acc);
- free(httpstor->host);
- free(httpstor->user);
- free(httpstor->key);
- free(httpstor);
-}
-
-/*
- * The service accessor is a "host:port" string that gets resolved to IP
- * address and then create a TCP connection to the server. The service host,
- * however, is used to form the "Host: host" HTTP header. The host of the
- * accessor should be the same on the sane installations, but whatever.
- */
-struct httpstor_client *httpstor_new(const char *service_acc,
- const char *service_host, const char *user, const char *secret_key)
-{
- struct httpstor_client *httpstor;
-
- httpstor = calloc(1, sizeof(struct httpstor_client));
- if (!httpstor)
- return NULL;
-
- httpstor->acc = strdup(service_acc);
- httpstor->host = strdup(service_host);
- httpstor->user = strdup(user);
- httpstor->key = strdup(secret_key);
- if (!httpstor->acc || !httpstor->host || !httpstor->user || !httpstor->key)
- goto err_out;
-
- if (curl_global_init(CURL_GLOBAL_ALL))
- goto err_out;
-
- httpstor->curl = curl_easy_init();
- if (!httpstor->curl)
- goto err_out;
-
- return httpstor;
-
-err_out:
- httpstor_free(httpstor);
- return NULL;
-}
-
-static size_t all_data_cb(void *ptr, size_t size, size_t nmemb, void *user_data)
-{
- GByteArray *all_data = user_data;
- int len = size * nmemb;
-
- g_byte_array_append(all_data, ptr, len);
-
- return len;
-}
-
-void httpstor_free_bucket(struct httpstor_bucket *buck)
-{
- if (!buck)
- return;
-
- free(buck->name);
- free(buck->time_create);
- free(buck);
-}
-
-void httpstor_free_blist(struct httpstor_blist *blist)
-{
- GList *tmp;
-
- if (!blist)
- return;
-
- free(blist->own_id);
- free(blist->own_name);
-
- tmp = blist->list;
- while (tmp) {
- struct httpstor_bucket *buck;
-
- buck = tmp->data;
- httpstor_free_bucket(buck);
-
- tmp = tmp->next;
- }
-
- g_list_free(blist->list);
-
- free(blist);
-}
-
-static void httpstor_parse_buckets(xmlDocPtr doc, xmlNode *node,
- struct httpstor_blist *blist)
-{
- struct httpstor_bucket *buck;
- xmlNode *tmp;
-
- while (node) {
- if (node->type != XML_ELEMENT_NODE)
- goto next;
-
- if (_strcmp(node->name, "Bucket"))
- goto next;
-
- buck = calloc(1, sizeof(*buck));
- if (!buck)
- goto next;
-
- tmp = node->children;
- while (tmp) {
- if (tmp->type != XML_ELEMENT_NODE)
- goto next_tmp;
-
- if (!_strcmp(tmp->name, "Name"))
- buck->name = (char *) xmlNodeListGetString(doc,
- tmp->children, 1);
-
- else if (!_strcmp(tmp->name, "CreationDate"))
- buck->time_create = (char *)
- xmlNodeListGetString(doc,
- tmp->children, 1);
-
-next_tmp:
- tmp = tmp->next;
- }
-
- if (!buck->name)
- httpstor_free_bucket(buck);
- else
- blist->list = g_list_append(blist->list, buck);
-
-next:
- node = node->next;
- }
-}
-
-struct httpstor_blist *httpstor_list_buckets(struct httpstor_client *httpstor)
-{
- struct http_req req;
- char datestr[80], timestr[64], hmac[64], auth[128], host[80], url[80];
- struct curl_slist *headers = NULL;
- struct httpstor_blist *blist;
- xmlDocPtr doc;
- xmlNode *node;
- xmlChar *xs;
- GByteArray *all_data;
- int rc;
-
- all_data = g_byte_array_new();
- if (!all_data)
- return NULL;
-
- memset(&req, 0, sizeof(req));
- req.method = "GET";
- req.orig_path = "/";
-
- sprintf(datestr, "Date: %s",
- time2str(timestr, sizeof(timestr), time(NULL)));
-
- req_hdr_push(&req, "Date", timestr);
-
- req_sign(&req, NULL, httpstor->key, hmac);
-
- sprintf(auth, "Authorization: AWS %s:%s", httpstor->user, hmac);
- sprintf(host, "Host: %s", httpstor->host);
-
- headers = curl_slist_append(headers, host);
- headers = curl_slist_append(headers, datestr);
- headers = curl_slist_append(headers, auth);
-
- snprintf(url, sizeof(url), "http://%s/", httpstor->acc);
-
- curl_easy_reset(httpstor->curl);
- if (httpstor->verbose)
- curl_easy_setopt(httpstor->curl, CURLOPT_VERBOSE, 1);
- curl_easy_setopt(httpstor->curl, CURLOPT_URL, url);
- curl_easy_setopt(httpstor->curl, CURLOPT_HTTPHEADER, headers);
- curl_easy_setopt(httpstor->curl, CURLOPT_ENCODING, "");
- curl_easy_setopt(httpstor->curl, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt(httpstor->curl, CURLOPT_WRITEFUNCTION, all_data_cb);
- curl_easy_setopt(httpstor->curl, CURLOPT_WRITEDATA, all_data);
- curl_easy_setopt(httpstor->curl, CURLOPT_TCP_NODELAY, 1);
-
- rc = curl_easy_perform(httpstor->curl);
-
- curl_slist_free_all(headers);
-
- if (rc)
- goto err_out;
-
- doc = xmlReadMemory((char *) all_data->data, all_data->len,
- "foo.xml", NULL, 0);
- if (!doc)
- goto err_out;
-
- node = xmlDocGetRootElement(doc);
- if (!node)
- goto err_out_doc;
-
- if (_strcmp(node->name, "ListAllMyBucketsResult"))
- goto err_out_doc;
-
- blist = calloc(1, sizeof(*blist));
- if (!blist)
- goto err_out_doc;
-
- node = node->children;
- while (node) {
- if (node->type != XML_ELEMENT_NODE) {
- node = node->next;
- continue;
- }
-
- if (!_strcmp(node->name, "Owner")) {
- xmlNode *tmp;
-
- tmp = node->children;
- while (tmp) {
- if (tmp->type != XML_ELEMENT_NODE) {
- tmp = tmp->next;
- continue;
- }
-
- if (!_strcmp(tmp->name, "ID")) {
- xs = xmlNodeListGetString(doc,
- tmp->children, 1);
- blist->own_id = strdup((char *)xs);
- xmlFree(xs);
- }
-
- else if (!_strcmp(tmp->name, "DisplayName")) {
- xs = xmlNodeListGetString(doc,
- tmp->children, 1);
- blist->own_name = strdup((char *)xs);
- xmlFree(xs);
- }
-
- tmp = tmp->next;
- }
- }
-
- else if (!_strcmp(node->name, "Buckets"))
- httpstor_parse_buckets(doc, node->children, blist);
-
- node = node->next;
- }
-
- xmlFreeDoc(doc);
- g_byte_array_free(all_data, TRUE);
- all_data = NULL;
-
- return blist;
-
-err_out_doc:
- xmlFreeDoc(doc);
-err_out:
- g_byte_array_free(all_data, TRUE);
- all_data = NULL;
- return NULL;
-}
-
-static bool __httpstor_ad_bucket(struct httpstor_client *httpstor, const char *name,
- bool delete)
-{
- struct http_req req;
- char datestr[80], timestr[64], hmac[64], auth[128], host[80],
- url[80], orig_path[80];
- struct curl_slist *headers = NULL;
- int rc;
-
- sprintf(orig_path, "/%s/", name);
-
- memset(&req, 0, sizeof(req));
- req.method = delete ? "DELETE" : "PUT";
- req.orig_path = orig_path;
-
- sprintf(datestr, "Date: %s",
- time2str(timestr, sizeof(timestr), time(NULL)));
-
- req_hdr_push(&req, "Date", timestr);
-
- req_sign(&req, NULL, httpstor->key, hmac);
-
- sprintf(auth, "Authorization: AWS %s:%s", httpstor->user, hmac);
- sprintf(host, "Host: %s", httpstor->host);
- snprintf(url, sizeof(url), "http://%s/%s/", httpstor->acc, name);
-
- headers = curl_slist_append(headers, host);
- headers = curl_slist_append(headers, datestr);
- headers = curl_slist_append(headers, auth);
-
- curl_easy_reset(httpstor->curl);
- if (httpstor->verbose)
- curl_easy_setopt(httpstor->curl, CURLOPT_VERBOSE, 1);
- curl_easy_setopt(httpstor->curl, CURLOPT_URL, url);
- curl_easy_setopt(httpstor->curl, CURLOPT_HTTPHEADER, headers);
- curl_easy_setopt(httpstor->curl, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt(httpstor->curl, CURLOPT_CUSTOMREQUEST, req.method);
- curl_easy_setopt(httpstor->curl, CURLOPT_TCP_NODELAY, 1);
-
- rc = curl_easy_perform(httpstor->curl);
-
- curl_slist_free_all(headers);
-
- return (rc == 0);
-}
-
-bool httpstor_add_bucket(struct httpstor_client *httpstor, const char *name)
-{
- return __httpstor_ad_bucket(httpstor, name, false);
-}
-
-bool httpstor_del_bucket(struct httpstor_client *httpstor, const char *name)
-{
- return __httpstor_ad_bucket(httpstor, name, true);
-}
-
-bool httpstor_get(struct httpstor_client *httpstor, const char *bucket, const char *key,
- size_t (*write_cb)(void *, size_t, size_t, void *),
- void *user_data, bool want_headers)
-{
- struct http_req req;
- char datestr[80], timestr[64], hmac[64], auth[128], host[80],
- url[80], *orig_path, *stmp;
- struct curl_slist *headers = NULL;
- int rc;
-
- if (asprintf(&stmp, "/%s/%s", bucket, key) < 0)
- return false;
-
- orig_path = field_escape(stmp, PATH_ESCAPE_MASK);
-
- memset(&req, 0, sizeof(req));
- req.method = "GET";
- req.orig_path = orig_path;
-
- sprintf(datestr, "Date: %s",
- time2str(timestr, sizeof(timestr), time(NULL)));
-
- req_hdr_push(&req, "Date", timestr);
-
- req_sign(&req, NULL, httpstor->key, hmac);
-
- sprintf(auth, "Authorization: AWS %s:%s", httpstor->user, hmac);
- sprintf(host, "Host: %s", httpstor->host);
- snprintf(url, sizeof(url), "http://%s%s", httpstor->acc, orig_path);
-
- headers = curl_slist_append(headers, host);
- headers = curl_slist_append(headers, datestr);
- headers = curl_slist_append(headers, auth);
-
- curl_easy_reset(httpstor->curl);
- if (httpstor->verbose)
- curl_easy_setopt(httpstor->curl, CURLOPT_VERBOSE, 1);
- curl_easy_setopt(httpstor->curl, CURLOPT_URL, url);
- curl_easy_setopt(httpstor->curl, CURLOPT_HEADER, want_headers ? 1 : 0);
- curl_easy_setopt(httpstor->curl, CURLOPT_HTTPHEADER, headers);
- curl_easy_setopt(httpstor->curl, CURLOPT_ENCODING, "");
- curl_easy_setopt(httpstor->curl, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt(httpstor->curl, CURLOPT_WRITEFUNCTION, write_cb);
- curl_easy_setopt(httpstor->curl, CURLOPT_WRITEDATA, user_data);
- curl_easy_setopt(httpstor->curl, CURLOPT_TCP_NODELAY, 1);
-
- rc = curl_easy_perform(httpstor->curl);
-
- curl_slist_free_all(headers);
- free(orig_path);
-
- return (rc == 0);
-}
-
-void *httpstor_get_inline(struct httpstor_client *httpstor, const char *bucket, const char *key,
- bool want_headers, size_t *len)
-{
- bool rcb;
- void *mem;
- GByteArray *all_data;
-
- all_data = g_byte_array_new();
- if (!all_data)
- return NULL;
-
- rcb = httpstor_get(httpstor, bucket, key, all_data_cb, all_data, want_headers);
- if (!rcb) {
- g_byte_array_free(all_data, TRUE);
- return NULL;
- }
-
- if (len)
- *len = all_data->len;
-
- mem = all_data->data;
-
- g_byte_array_free(all_data, FALSE);
- return mem;
-}
-
-bool httpstor_put(struct httpstor_client *httpstor, const char *bucket, const char *key,
- size_t (*read_cb)(void *, size_t, size_t, void *),
- uint64_t len, void *user_data, char **user_hdrs)
-{
- struct http_req req;
- char datestr[80], timestr[64], hmac[64], auth[128], host[80],
- url[80], *orig_path, *stmp, *uhdr_buf = NULL;
- struct curl_slist *headers = NULL;
- int rc = -1;
-
- if (asprintf(&stmp, "/%s/%s", bucket, key) < 0)
- return false;
-
- orig_path = field_escape(stmp, PATH_ESCAPE_MASK);
-
- memset(&req, 0, sizeof(req));
- req.method = "PUT";
- req.orig_path = orig_path;
-
- sprintf(datestr, "Date: %s",
- time2str(timestr, sizeof(timestr), time(NULL)));
-
- req_hdr_push(&req, "Date", timestr);
-
- if (user_hdrs) {
- int idx = 0;
- size_t uhdr_len = 0, ukey_len;
- void *p;
- char *colon, *ukey, *uval;
-
- /* 1. add to curl hdr list. 2. count hdr byte size */
- while (user_hdrs[idx]) {
- headers = curl_slist_append(headers, user_hdrs[idx]);
- uhdr_len += strlen(user_hdrs[idx]) + 2;
- idx++;
- }
-
- /* alloc buf to hold all hdr strings */
- uhdr_buf = calloc(1, uhdr_len);
- if (!uhdr_buf)
- goto out;
-
- /* copy and nul-terminate hdr keys and values for signing */
- idx = 0;
- p = uhdr_buf;
- while (user_hdrs[idx]) {
- ukey = p;
- colon = strchr(user_hdrs[idx], ':');
- if (colon) {
- ukey_len = colon - user_hdrs[idx];
- memcpy(ukey, user_hdrs[idx], ukey_len);
- ukey[ukey_len] = 0;
-
- p += ukey_len + 1;
-
- colon++;
- while (*colon && isspace(*colon))
- colon++;
-
- uval = p;
- strcpy(uval, colon);
- p += strlen(uval) + 1;
-
- req_hdr_push(&req, ukey, uval);
- }
- idx++;
- }
- }
-
- req_sign(&req, NULL, httpstor->key, hmac);
-
- sprintf(auth, "Authorization: AWS %s:%s", httpstor->user, hmac);
- sprintf(host, "Host: %s", httpstor->host);
- snprintf(url, sizeof(url), "http://%s%s", httpstor->acc, orig_path);
-
- headers = curl_slist_append(headers, host);
- headers = curl_slist_append(headers, datestr);
- headers = curl_slist_append(headers, auth);
-
- curl_easy_reset(httpstor->curl);
- if (httpstor->verbose)
- curl_easy_setopt(httpstor->curl, CURLOPT_VERBOSE, 1);
- curl_easy_setopt(httpstor->curl, CURLOPT_URL, url);
- curl_easy_setopt(httpstor->curl, CURLOPT_HTTPHEADER, headers);
- curl_easy_setopt(httpstor->curl, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt(httpstor->curl, CURLOPT_READFUNCTION, read_cb);
- curl_easy_setopt(httpstor->curl, CURLOPT_READDATA, user_data);
- curl_easy_setopt(httpstor->curl, CURLOPT_CUSTOMREQUEST, req.method);
- curl_easy_setopt(httpstor->curl, CURLOPT_UPLOAD, 1);
- curl_easy_setopt(httpstor->curl, CURLOPT_INFILESIZE_LARGE,
- (curl_off_t)len);
- curl_easy_setopt(httpstor->curl, CURLOPT_TCP_NODELAY, 1);
-
- rc = curl_easy_perform(httpstor->curl);
-
- curl_slist_free_all(headers);
- free(orig_path);
-
-out:
- free(uhdr_buf);
- return (rc == 0);
-}
-
-struct httpstor_put_info {
- void *data;
- uint64_t len;
-};
-
-static size_t read_inline_cb(void *ptr, size_t size, size_t nmemb,
- void *user_data)
-{
- struct httpstor_put_info *spi = user_data;
- int len = size * nmemb;
-
- len = MIN(len, spi->len);
- if (len) {
- memcpy(ptr, spi->data, len);
- spi->data += len;
- spi->len -= len;
- }
-
- return len;
-}
-
-bool httpstor_put_inline(struct httpstor_client *httpstor, const char *bucket, const char *key,
- void *data, uint64_t len, char **user_hdrs)
-{
- struct httpstor_put_info spi = { data, len };
-
- return httpstor_put(httpstor, bucket, key, read_inline_cb, len, &spi, user_hdrs);
-}
-
-bool httpstor_del(struct httpstor_client *httpstor, const char *bucket, const char *key)
-{
- struct http_req req;
- char datestr[80], timestr[64], hmac[64], auth[128], host[80],
- url[80], *orig_path, *stmp;
- struct curl_slist *headers = NULL;
- int rc;
-
- if (asprintf(&stmp, "/%s/%s", bucket, key) < 0)
- return false;
-
- orig_path = field_escape(stmp, PATH_ESCAPE_MASK);
-
- memset(&req, 0, sizeof(req));
- req.method = "DELETE";
- req.orig_path = orig_path;
-
- sprintf(datestr, "Date: %s",
- time2str(timestr, sizeof(timestr), time(NULL)));
-
- req_hdr_push(&req, "Date", timestr);
-
- req_sign(&req, NULL, httpstor->key, hmac);
-
- sprintf(auth, "Authorization: AWS %s:%s", httpstor->user, hmac);
- sprintf(host, "Host: %s", httpstor->host);
- snprintf(url, sizeof(url), "http://%s%s", httpstor->acc, orig_path);
-
- headers = curl_slist_append(headers, host);
- headers = curl_slist_append(headers, datestr);
- headers = curl_slist_append(headers, auth);
-
- curl_easy_reset(httpstor->curl);
- if (httpstor->verbose)
- curl_easy_setopt(httpstor->curl, CURLOPT_VERBOSE, 1);
- curl_easy_setopt(httpstor->curl, CURLOPT_URL, url);
- curl_easy_setopt(httpstor->curl, CURLOPT_HTTPHEADER, headers);
- curl_easy_setopt(httpstor->curl, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt(httpstor->curl, CURLOPT_CUSTOMREQUEST, req.method);
- curl_easy_setopt(httpstor->curl, CURLOPT_TCP_NODELAY, 1);
-
- rc = curl_easy_perform(httpstor->curl);
-
- curl_slist_free_all(headers);
- free(orig_path);
-
- return (rc == 0);
-}
-
-GString *append_qparam(GString *str, const char *key, const char *val,
- char *arg_char)
-{
- char *stmp, s[32];
-
- str = g_string_append(str, arg_char);
- arg_char[0] = '&';
-
- sprintf(s, "%s=", key);
- str = g_string_append(str, key);
-
- stmp = field_escape(strdup(val), QUERY_ESCAPE_MASK);
- str = g_string_append(str, stmp);
- free(stmp);
-
- return str;
-}
-
-void httpstor_free_object(struct httpstor_object *obj)
-{
- if (!obj)
- return;
-
- free(obj->key);
- free(obj->time_mod);
- free(obj->etag);
- free(obj->storage);
- free(obj->own_id);
- free(obj->own_name);
- free(obj);
-}
-
-void httpstor_free_keylist(struct httpstor_keylist *keylist)
-{
- GList *tmp;
-
- if (!keylist)
- return;
-
- free(keylist->name);
- free(keylist->prefix);
- free(keylist->marker);
- free(keylist->delim);
-
- tmp = keylist->common_pfx;
- while (tmp) {
- free(tmp->data);
- tmp = tmp->next;
- }
-
- tmp = keylist->contents;
- while (tmp) {
- httpstor_free_object(tmp->data);
- tmp = tmp->next;
- }
- g_list_free(keylist->contents);
-
- free(keylist);
-}
-
-static void httpstor_parse_key(xmlDocPtr doc, xmlNode *node,
- struct httpstor_keylist *keylist)
-{
- struct httpstor_object *obj = calloc(1, sizeof(*obj));
- xmlChar *xs;
-
- obj = calloc(1, sizeof(*obj));
- if (!obj)
- return;
-
- while (node) {
- if (node->type != XML_ELEMENT_NODE) {
- node = node->next;
- continue;
- }
-
- if (!_strcmp(node->name, "Key")) {
- xs = xmlNodeListGetString(doc, node->children, 1);
- obj->key = strdup((char *)xs);
- xmlFree(xs);
- }
- else if (!_strcmp(node->name, "LastModified")) {
- xs = xmlNodeListGetString(doc, node->children, 1);
- obj->time_mod = strdup((char *)xs);
- xmlFree(xs);
- }
- else if (!_strcmp(node->name, "ETag")) {
- xs = xmlNodeListGetString(doc, node->children, 1);
- obj->etag = strdup((char *)xs);
- xmlFree(xs);
- }
- else if (!_strcmp(node->name, "Size")) {
- xs = xmlNodeListGetString(doc, node->children, 1);
- obj->size = atoll((char *) xs);
- xmlFree(xs);
- }
- else if (!_strcmp(node->name, "StorageClass")) {
- xs = xmlNodeListGetString(doc, node->children, 1);
- obj->storage = strdup((char *)xs);
- xmlFree(xs);
- }
- else if (!_strcmp(node->name, "Owner")) {
- xmlNode *tmp;
-
- tmp = node->children;
- while (tmp) {
- if (tmp->type != XML_ELEMENT_NODE) {
- tmp = tmp->next;
- continue;
- }
-
- if (!_strcmp(tmp->name, "ID")) {
- xs = xmlNodeListGetString(doc,
- tmp->children, 1);
- obj->own_id = strdup((char *)xs);
- xmlFree(xs);
- }
-
- else if (!_strcmp(tmp->name, "DisplayName")) {
- xs = xmlNodeListGetString(doc,
- tmp->children, 1);
- obj->own_name = strdup((char *)xs);
- xmlFree(xs);
- }
-
- tmp = tmp->next;
- }
- }
-
- node = node->next;
- }
-
- if (obj->key)
- keylist->contents = g_list_append(keylist->contents, obj);
- else
- httpstor_free_object(obj);
-}
-
-struct httpstor_keylist *httpstor_keys(struct httpstor_client *httpstor, const char *bucket,
- const char *prefix, const char *marker,
- const char *delim, unsigned int max_keys)
-{
- struct http_req req;
- char datestr[80], timestr[64], hmac[64], auth[128], host[80];
- char orig_path[strlen(bucket) + 8];
- struct curl_slist *headers = NULL;
- struct httpstor_keylist *keylist;
- xmlDocPtr doc;
- xmlNode *node;
- xmlChar *xs;
- GByteArray *all_data;
- GString *url;
- int rc;
- char arg_char[2] = "?";
-
- all_data = g_byte_array_new();
- if (!all_data)
- return NULL;
-
- sprintf(orig_path, "/%s/", bucket);
-
- memset(&req, 0, sizeof(req));
- req.method = "GET";
- req.orig_path = orig_path;
-
- sprintf(datestr, "Date: %s",
- time2str(timestr, sizeof(timestr), time(NULL)));
-
- req_hdr_push(&req, "Date", timestr);
-
- req_sign(&req, NULL, httpstor->key, hmac);
-
- sprintf(auth, "Authorization: AWS %s:%s", httpstor->user, hmac);
- sprintf(host, "Host: %s", httpstor->host);
-
- headers = curl_slist_append(headers, host);
- headers = curl_slist_append(headers, datestr);
- headers = curl_slist_append(headers, auth);
-
- url = g_string_sized_new(256);
- if (!url) {
- curl_slist_free_all(headers);
- goto err_out;
- }
-
- url = g_string_append(url, "http://");
- url = g_string_append(url, httpstor->acc);
- url = g_string_append(url, orig_path);
-
- if (prefix)
- url = append_qparam(url, "prefix", prefix, arg_char);
- if (marker)
- url = append_qparam(url, "marker", marker, arg_char);
- if (delim)
- url = append_qparam(url, "delimiter", delim, arg_char);
- if (max_keys) {
- char mk[32];
- sprintf(mk, "%smax-keys=%u", arg_char, max_keys);
- url = g_string_append(url, mk);
- }
-
- curl_easy_reset(httpstor->curl);
- if (httpstor->verbose)
- curl_easy_setopt(httpstor->curl, CURLOPT_VERBOSE, 1);
- curl_easy_setopt(httpstor->curl, CURLOPT_URL, url->str);
- curl_easy_setopt(httpstor->curl, CURLOPT_HTTPHEADER, headers);
- curl_easy_setopt(httpstor->curl, CURLOPT_ENCODING, "");
- curl_easy_setopt(httpstor->curl, CURLOPT_FAILONERROR, 1);
- curl_easy_setopt(httpstor->curl, CURLOPT_WRITEFUNCTION, all_data_cb);
- curl_easy_setopt(httpstor->curl, CURLOPT_WRITEDATA, all_data);
- curl_easy_setopt(httpstor->curl, CURLOPT_TCP_NODELAY, 1);
-
- rc = curl_easy_perform(httpstor->curl);
-
- g_string_free(url, TRUE);
- curl_slist_free_all(headers);
-
- if (rc)
- goto err_out;
-
- doc = xmlReadMemory((char *) all_data->data, all_data->len,
- "foo.xml", NULL, 0);
- if (!doc)
- goto err_out;
-
- node = xmlDocGetRootElement(doc);
- if (!node)
- goto err_out_doc;
-
- if (_strcmp(node->name, "ListBucketResult"))
- goto err_out_doc;
-
- keylist = calloc(1, sizeof(*keylist));
- if (!keylist)
- goto err_out_doc;
-
- node = node->children;
- while (node) {
- if (node->type != XML_ELEMENT_NODE) {
- node = node->next;
- continue;
- }
-
- if (!_strcmp(node->name, "Name")) {
- xs = xmlNodeListGetString(doc, node->children, 1);
- keylist->name = strdup((char *)xs);
- xmlFree(xs);
- }
- else if (!_strcmp(node->name, "Prefix")) {
- xs = xmlNodeListGetString(doc, node->children, 1);
- keylist->prefix = strdup((char *)xs);
- xmlFree(xs);
- }
- else if (!_strcmp(node->name, "Marker")) {
- xs = xmlNodeListGetString(doc, node->children, 1);
- keylist->marker = strdup((char *)xs);
- xmlFree(xs);
- }
- else if (!_strcmp(node->name, "Delimiter")) {
- xs = xmlNodeListGetString(doc, node->children, 1);
- keylist->delim = strdup((char *)xs);
- xmlFree(xs);
- }
- else if (!_strcmp(node->name, "MaxKeys")) {
- xs = xmlNodeListGetString(doc, node->children, 1);
- keylist->max_keys = (unsigned int) atoi((char *)xs);
- xmlFree(xs);
- }
- else if (!_strcmp(node->name, "IsTruncated")) {
- xs = xmlNodeListGetString(doc, node->children, 1);
-
- if (!_strcasecmp(xs, "true"))
- keylist->trunc = true;
- else if (!_strcasecmp(xs, "1"))
- keylist->trunc = true;
- else
- keylist->trunc = false;
-
- xmlFree(xs);
- }
- else if (!_strcmp(node->name, "CommonPrefixes")) {
- xmlNode *tmp;
-
- tmp = node->children;
- while (tmp) {
- if (tmp->type != XML_ELEMENT_NODE) {
- tmp = tmp->next;
- continue;
- }
-
- if (!_strcmp(tmp->name, "Prefix")) {
- xs = xmlNodeListGetString(doc,
- tmp->children, 1);
- keylist->common_pfx =
- g_list_append(
- keylist->common_pfx,
- strdup((char *)xs));
- xmlFree(xs);
- }
-
- tmp = tmp->next;
- }
- }
- else if (!_strcmp(node->name, "Contents"))
- httpstor_parse_key(doc, node->children, keylist);
-
- node = node->next;
- }
-
- xmlFreeDoc(doc);
- g_byte_array_free(all_data, TRUE);
- all_data = NULL;
-
- return keylist;
-
-err_out_doc:
- xmlFreeDoc(doc);
-err_out:
- g_byte_array_free(all_data, TRUE);
- all_data = NULL;
- return NULL;
-}
-
diff --git a/lib/httputil.c b/lib/httputil.c
deleted file mode 100644
index 1c56be9..0000000
--- a/lib/httputil.c
+++ /dev/null
@@ -1,366 +0,0 @@
-
-/*
- * Copyright 2008-2009 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#define _GNU_SOURCE
-#include "tabled-config.h"
-
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-#include <time.h>
-#include <glib.h>
-#include <openssl/hmac.h>
-#include <httputil.h>
-
-time_t str2time(const char *timestr)
-{
- struct tm tm;
-
- memset(&tm, 0, sizeof(tm));
-
- if (!strptime(timestr, "%a, %d %b %Y %H:%M:%S %z", &tm))
- return 0;
-
- return mktime(&tm);
-}
-
-char *time2str(char *strbuf, int buflen, time_t src_time)
-{
- struct tm tm;
- size_t rc;
-
- if (buflen <= 0)
- return NULL; /* too wrong, better crash right away. */
- gmtime_r(&src_time, &tm);
- rc = strftime(strbuf, buflen, "%a, %d %b %Y %H:%M:%S %z", &tm);
- if (rc >= buflen)
- strbuf[buflen-1] = 0;
- else if (rc == 0)
- strbuf[0] = 0;
- return strbuf;
-}
-
-/*
- * Temporary list of headers.
- */
-struct custom_hdr {
- char *key; /* by malloc */
- char *val; /* by ref */
-};
-
-struct custom_hdr_vec {
- int num;
- struct custom_hdr vec[REQ_MAX_HDR];
-};
-
-static const char amzpfx[] = "x-amz-";
-#define AMZPFX amzpfx
-#define AMZPFXLEN (sizeof("x-amz-")-1)
-
-static int cust_cmp(const void *p1, const void *p2)
-{
- struct custom_hdr *h1 = (struct custom_hdr *)p1;
- struct custom_hdr *h2 = (struct custom_hdr *)p2;
- return strcmp(h1->key, h2->key);
-}
-
-/*
- * Create a list of headers for us to iterate.
- * Preconvert keys to lowercase, sort, but leave duplicates as is.
- */
-static int cust_init(struct custom_hdr_vec *cv, struct http_req *req)
-{
- int cnt;
- int i, j;
- const char *key;
- char *ckey;
- int klen;
-
- cnt = 0;
- for (i = 0; i < req->n_hdr; i++) {
- key = req->hdr[i].key;
- if (!strncasecmp(AMZPFX, key, AMZPFXLEN)) {
- klen = strlen(key) - AMZPFXLEN;
- if ((ckey = malloc(klen+1)) == NULL) {
- while (cnt-- != 0)
- free(cv->vec[cnt].key);
- goto enocore;
- }
- for (j = 0; j < klen; j++)
- ckey[j] = tolower(key[AMZPFXLEN + j]);
- ckey[j] = 0;
-
- cv->vec[cnt].key = ckey;
- cv->vec[cnt].val = req->hdr[i].val;
- cnt++;
- }
- }
- cv->num = cnt;
-
- qsort(cv->vec, cv->num, sizeof(struct custom_hdr), cust_cmp);
- return 0;
-
- enocore:
- return -1;
-}
-
-static void cust_fin(struct custom_hdr_vec *cv)
-{
- int i;
-
- for (i = 0; i < cv->num; i++) {
- free(cv->vec[i].key);
- }
-}
-
-/*
- */
-int req_hdr_push(struct http_req *req, char *key, char *val)
-{
- struct http_hdr *hdr;
-
- if (req->n_hdr == REQ_MAX_HDR)
- return -ENOSPC;
-
- while (isspace(*val))
- val++;
-
- hdr = &req->hdr[req->n_hdr++];
- hdr->key = key;
- hdr->val = val;
-
- return 0;
-}
-
-char *req_hdr(struct http_req *req, const char *key)
-{
- int i;
-
- for (i = 0; i < req->n_hdr; i++)
- if (!strcasecmp(key, req->hdr[i].key))
- return req->hdr[i].val;
-
- return NULL;
-}
-
-static inline void _HMAC_Update(HMAC_CTX *ctx, const void *data, int len)
-{
- HMAC_Update(ctx, data, len);
-}
-
-static void req_sign_hdr(struct http_req *req, HMAC_CTX *ctx, const char *_hdr)
-{
- char *hdr = req_hdr(req, _hdr);
- if (hdr)
- _HMAC_Update(ctx, hdr, strlen(hdr));
- _HMAC_Update(ctx, "\n", 1);
-}
-
-static void req_sign_amz(HMAC_CTX *ctx, struct http_req *req)
-{
- struct custom_hdr_vec cust;
- struct custom_hdr *p;
- struct custom_hdr *prev;
- int i;
-
- if (cust_init(&cust, req))
- return;
-
- prev = NULL;
- p = &cust.vec[0];
- for (i = 0; i < cust.num; i++) {
- if (prev) {
- if (!strcmp(prev->key, p->key)) {
- _HMAC_Update(ctx, ",", 1);
- } else {
- _HMAC_Update(ctx, "\n", 1);
-
- _HMAC_Update(ctx, AMZPFX, AMZPFXLEN);
- _HMAC_Update(ctx, p->key, strlen(p->key));
- _HMAC_Update(ctx, ":", 1);
- prev = p;
- }
- } else {
- _HMAC_Update(ctx, AMZPFX, AMZPFXLEN);
- _HMAC_Update(ctx, p->key, strlen(p->key));
- _HMAC_Update(ctx, ":", 1);
- prev = p;
- }
- _HMAC_Update(ctx, p->val, strlen(p->val));
- p++;
- }
- if (prev)
- _HMAC_Update(ctx, "\n", 1);
-
- cust_fin(&cust);
-}
-
-static const char *req_query_sign[URIQNUM] = {
- "acl",
- "location",
- "logging",
- "torrent",
-};
-
-void req_sign(struct http_req *req, const char *bucket, const char *key,
- char *b64hmac_out)
-{
- HMAC_CTX ctx;
- unsigned int len = 0;
- unsigned char md[EVP_MAX_MD_SIZE];
- int save = 0, state = 0, b64_len;
-
- HMAC_CTX_init(&ctx);
- HMAC_Init(&ctx, key, strlen(key), EVP_sha1());
-
- _HMAC_Update(&ctx, req->method, strlen(req->method));
- _HMAC_Update(&ctx, "\n", 1);
-
- req_sign_hdr(req, &ctx, "content-md5");
- req_sign_hdr(req, &ctx, "content-type");
- if (req_hdr(req, "x-amz-date"))
- _HMAC_Update(&ctx, "\n", 1);
- else
- req_sign_hdr(req, &ctx, "date");
-
- req_sign_amz(&ctx, req);
-
- if (bucket) {
- _HMAC_Update(&ctx, "/", 1);
- _HMAC_Update(&ctx, bucket, strlen(bucket));
- }
-
- _HMAC_Update(&ctx, req->orig_path, strlen(req->orig_path));
-
- if (req_is_query(req) != -1) {
- _HMAC_Update(&ctx, "?", 1);
- _HMAC_Update(&ctx, req->uri.query, req->uri.query_len);
- }
-
- HMAC_Final(&ctx, md, &len);
- HMAC_CTX_cleanup(&ctx);
-
- b64_len = g_base64_encode_step(md, len, FALSE, b64hmac_out,
- &state, &save);
- b64_len += g_base64_encode_close(FALSE, b64hmac_out + b64_len,
- &state, &save);
- b64hmac_out[b64_len] = 0;
-}
-
-void req_free(struct http_req *req)
-{
- free(req->orig_path);
- req->orig_path = NULL;
-}
-
-GHashTable *req_query(struct http_req *req)
-{
- char *qtmp, *q, *tmp, *end;
- int qlen, qtmplen;
- GHashTable *ht;
-
- ht = g_hash_table_new_full(g_str_hash, g_str_equal, free, free);
- if (!ht)
- return NULL;
-
- qtmp = alloca(req->uri.query_len + 1);
-
- q = req->uri.query;
- qlen = req->uri.query_len;
-
- while (qlen > 0) {
- char *key, *val;
- int keylen, vallen, valskip;
-
- tmp = memchr(q, '=', qlen);
- if (!tmp || (tmp == q))
- break;
-
- keylen = tmp - q;
- end = memchr(tmp, '&', qlen - keylen);
-
- memcpy(qtmp, q, keylen);
- qtmp[keylen] = 0;
- qtmplen = field_unescape(qtmp, strlen(qtmp));
-
- key = g_ascii_strdown(qtmp, qtmplen);
-
- qlen -= (keylen + 1);
- q += (keylen + 1);
- tmp++;
-
- if (end)
- vallen = end - tmp;
- else
- vallen = qlen;
-
- memcpy(qtmp, tmp, vallen);
- qtmplen = field_unescape(qtmp, vallen);
-
- val = g_strndup(qtmp, qtmplen);
-
- valskip = vallen;
- if (end)
- valskip++;
-
- qlen -= valskip;
- q += valskip;
-
- g_hash_table_insert(ht, key, val);
- }
-
- return ht;
-}
-
-int req_is_query(struct http_req *req)
-{
- int i;
-
- if (req->uri.query_len)
- for (i = 0; i < URIQNUM; i++)
- if (!strcasecmp(req->uri.query, req_query_sign[i]))
- return i;
- return -1;
-}
-
-static const char *req_acl_cans[ACLCNUM] = {
- "private",
- "public-read",
- "public-read-write",
- "authenticated-read"
-};
-
-/*
- * Return -1 if no header is present, which is ok.
- * Return ACLCNUM if header is present, but the policy is invalid.
- */
-int req_acl_canned(struct http_req *req)
-{
- const char *aclhdr;
- int i;
-
- aclhdr = req_hdr(req, "x-amz-acl");
- if (!aclhdr)
- return -1;
-
- for (i = 0; i < ACLCNUM; i++)
- if (!strcasecmp(aclhdr, req_acl_cans[i]))
- return i;
- return ACLCNUM;
-}
diff --git a/lib/libhttpstor-uninstalled.pc.in b/lib/libhttpstor-uninstalled.pc.in
deleted file mode 100644
index ac2753a..0000000
--- a/lib/libhttpstor-uninstalled.pc.in
+++ /dev/null
@@ -1,12 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-libhttpstor_serverdir=@libexecdir@
-
-Name: libhttpstor
-Description: libhttpstor
-Requires: glib-2.0
-Version: @VERSION@
-Libs: ${pc_top_builddir}/${pcfiledir}/libhttpstor.la
-#Cflags: -I${pc_top_builddir}/${pcfiledir}/..
diff --git a/lib/libhttpstor.pc.in b/lib/libhttpstor.pc.in
deleted file mode 100644
index 44fd82d..0000000
--- a/lib/libhttpstor.pc.in
+++ /dev/null
@@ -1,13 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-libhttpstor_serverdir=@libexecdir@
-localstatedir=@localstatedir@
-
-Name: libhttpstor
-Description: libhttpstor
-Requires: glib-2.0
-Version: @VERSION@
-Libs: -L${libdir} -lhttpstor
-#Cflags: -I${includedir}/libhttpstor-2.0
diff --git a/lib/uri.c b/lib/uri.c
deleted file mode 100644
index a2cf2f5..0000000
--- a/lib/uri.c
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * Taken from GNet and modified for tabled
- */
-
-/* GNet - Networking library
- * Copyright (C) 2000-2003 David Helder, David Bolcsfoldi, Eric Williams
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdbool.h>
-#include <httputil.h>
-
-/* our own ISSPACE. ANSI isspace is locale dependent */
-#define ISSPACE(C) (((C) >= 9 && (C) <= 13) || (C) == ' ')
-
-#define ASSIGN(token, ptr, len) \
- do { \
- uri->token = (ptr); \
- uri->token##_len = (len); \
- } while (0)
-
-struct uri *uri_parse(struct uri *uri, char *uri_text)
-{
- char *p, *temp;
-
- memset(uri, 0, sizeof(*uri));
-
- /* Skip initial whitespace */
- p = uri_text;
- while (*p && ISSPACE((int)*p))
- ++p;
- if (!*p) /* Error if it's just a string of space */
- return NULL;
-
- /* Scheme */
- temp = p;
- while (*p && *p != ':' && *p != '/' && *p != '?' && *p != '#')
- ++p;
- if (*p == ':') {
- ASSIGN(scheme, temp, p - temp);
- ++p;
- } else /* This char is NUL, /, ?, or # */
- p = temp;
-
- /* Authority */
- if (*p == '/' && p[1] == '/') {
- p += 2;
-
- /* Userinfo */
- temp = p;
- while (*p && *p != '@' && *p != '/') /* Look for @ or / */
- ++p;
- if (*p == '@') { /* Found userinfo */
- ASSIGN(userinfo, temp, p - temp);
- ++p;
- } else
- p = temp;
-
- /* Hostname */
-
- /* Check for no hostname at all (e.g. file:// URIs) */
- if (*p == '/')
- goto path;
-
- /* Check for IPv6 canonical hostname in brackets */
- if (*p == '[') {
- p++; /* Skip [ */
- temp = p;
- while (*p && *p != ']')
- ++p;
- if ((p - temp) == 0)
- goto error;
- ASSIGN(hostname, temp, p - temp);
- if (*p)
- p++; /* Skip ] (if there) */
- } else {
- temp = p;
- while (*p && *p != '/' && *p != '?' && *p != '#'
- && *p != ':')
- ++p;
- if ((p - temp) == 0)
- goto error;
- ASSIGN(hostname, temp, p - temp);
- }
-
- /* Port */
- if (*p == ':') {
- for (++p; isdigit((int)*p); ++p)
- uri->port = uri->port * 10 + (*p - '0');
- }
-
- }
-
- /* Path (we are liberal and won't check if it starts with /) */
-
-path:
- temp = p;
- while (*p && *p != '?' && *p != '#')
- ++p;
- if (p != temp)
- ASSIGN(path, temp, p - temp);
-
- /* Query */
- if (*p == '?') {
- temp = p + 1;
- while (*p && *p != '#')
- ++p;
- ASSIGN(query, temp, p - temp);
- }
-
- /* Fragment */
- if (*p == '#') {
- ++p;
- uri->fragment = p;
- /* FIXME: assign uri->fragment_len! */
- }
-
- return uri;
-
-error:
- return NULL;
-}
-
-int field_unescape(char *s, int s_len)
-{
- int dst_len = 0;
- char *src;
- char *dst;
-
- for (src = dst = s; s_len; ++src, ++dst, ++dst_len, --s_len) {
- if (src[0] == '%' && (s_len > 2)) {
- int high, low;
-
- if ('a' <= src[1] && src[1] <= 'f')
- high = src[1] - 'a' + 10;
- else if ('A' <= src[1] && src[1] <= 'F')
- high = src[1] - 'A' + 10;
- else if ('0' <= src[1] && src[1] <= '9')
- high = src[1] - '0';
- else /* malformed */
- goto regular_copy;
-
- if ('a' <= src[2] && src[2] <= 'f')
- low = src[2] - 'a' + 10;
- else if ('A' <= src[2] && src[2] <= 'F')
- low = src[2] - 'A' + 10;
- else if ('0' <= src[2] && src[2] <= '9')
- low = src[2] - '0';
- else /* malformed */
- goto regular_copy;
-
- *dst = (char)((high << 4) + low);
- src += 2;
- s_len -= 2;
- } else {
-regular_copy:
- /* micro-opt: a lot of URIs do not include escape
- * sequences. by testing the pointer addresses
- * we can avoid a lot of reading+writing of the
- * same data
- */
- if (dst != src)
- *dst = *src;
- }
- }
-
- return dst_len;
-}
-
-static const guchar neednt_escape_table[] =
-{
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0e,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x00, 0x0c,
- 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x00, 0x00, 0x0f,
- 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-char* field_escape (char *signed_str, unsigned char mask)
-{
- int len;
- int i;
- bool must_escape = false;
- unsigned char *str;
- char *dst;
- gint j;
-
- str = (unsigned char *) signed_str;
-
- if (str == NULL)
- return NULL;
-
- /* Roughly calculate buffer size */
- len = 0;
- for (i = 0; str[i]; i++)
- {
- if (neednt_escape_table[str[i]] & mask)
- len++;
- else
- {
- len += 3;
- must_escape = TRUE;
- }
- }
-
- /* Don't escape if unnecessary */
- if (must_escape == FALSE)
- return signed_str;
-
- /* Allocate buffer */
- dst = (gchar*) g_malloc(len + 1);
-
- /* Copy */
- for (i = j = 0; str[i]; i++, j++)
- {
- /* Unescaped character */
- if (neednt_escape_table[str[i]] & mask)
- {
- dst[j] = str[i];
- }
-
- /* Escaped character */
- else
- {
- dst[j] = '%';
-
- if (((str[i] & 0xf0) >> 4) < 10)
- dst[j+1] = ((str[i] & 0xf0) >> 4) + '0';
- else
- dst[j+1] = ((str[i] & 0xf0) >> 4) + 'a' - 10;
-
- if ((str[i] & 0x0f) < 10)
- dst[j+2] = (str[i] & 0x0f) + '0';
- else
- dst[j+2] = (str[i] & 0x0f) + 'a' - 10;
-
- j += 2; /* and j is incremented in loop too */
- }
- }
- dst[j] = '\0';
-
- g_free (signed_str);
- return dst;
-}
-
diff --git a/server/.gitignore b/server/.gitignore
new file mode 100644
index 0000000..fafb1ca
--- /dev/null
+++ b/server/.gitignore
@@ -0,0 +1,4 @@
+
+tabled
+tdbadm
+
diff --git a/server/Makefile.am b/server/Makefile.am
index 6ebfd05..6397245 100644
--- a/server/Makefile.am
+++ b/server/Makefile.am
@@ -6,7 +6,7 @@ sbin_PROGRAMS = tabled tdbadm
tabled_SOURCES = tabled.h \
bucket.c cldu.c config.c object.c replica.c \
server.c status.c storage.c storparse.c util.c
-tabled_LDADD = ../lib/libhttputil.a ../lib/libtdb.a \
+tabled_LDADD = ../lib/libtdb.a \
@HAIL_LIBS@ @PCRE_LIBS@ @GLIB_LIBS@ \
@CRYPTO_LIBS@ @DB4_LIBS@ @EVENT_LIBS@ @SSL_LIBS@
diff --git a/server/bucket.c b/server/bucket.c
index 0acf987..a95d23e 100644
--- a/server/bucket.c
+++ b/server/bucket.c
@@ -265,7 +265,7 @@ bool service_list(struct client *cli, const char *user)
" </Bucket>\r\n",
ent->name,
- time2str(timestr, sizeof(timestr),
+ hutil_time2str(timestr, sizeof(timestr),
GUINT64_FROM_LE(ent->time_create)));
if (!s)
goto err_out_content;
@@ -467,7 +467,7 @@ bool bucket_add(struct client *cli, const char *user, const char *bucket)
/* prepare parameters */
setacl = false;
if (cli->req.uri.query_len) {
- switch (req_is_query(&cli->req)) {
+ switch (hreq_is_query(&cli->req)) {
case URIQ_ACL:
setacl = true;
break;
@@ -477,7 +477,7 @@ bool bucket_add(struct client *cli, const char *user, const char *bucket)
}
}
- if ((rc = req_acl_canned(&cli->req)) == ACLCNUM) {
+ if ((rc = hreq_acl_canned(&cli->req)) == ACLCNUM) {
err = InvalidArgument;
goto err_par;
}
@@ -562,7 +562,7 @@ bool bucket_add(struct client *cli, const char *user, const char *bucket)
"\r\n",
cli->req.major,
cli->req.minor,
- time2str(timestr, sizeof(timestr), time(NULL)),
+ hutil_time2str(timestr, sizeof(timestr), time(NULL)),
bucket) < 0)
return cli_err(cli, InternalError);
@@ -715,7 +715,7 @@ bool bucket_del(struct client *cli, const char *user, const char *bucket)
"\r\n",
cli->req.major,
cli->req.minor,
- time2str(timestr, sizeof(timestr), time(NULL))) < 0)
+ hutil_time2str(timestr, sizeof(timestr), time(NULL))) < 0)
return cli_err(cli, InternalError);
rc = cli_writeq(cli, hdr, strlen(hdr), cli_cb_free, hdr);
@@ -939,7 +939,7 @@ static bool bucket_list_keys(struct client *cli, const char *user,
}
/* parse URI query string */
- param = req_query(&cli->req);
+ param = hreq_query(&cli->req);
if (!param)
goto err_out;
@@ -1110,7 +1110,7 @@ static bool bucket_list_keys(struct client *cli, const char *user,
" </Contents>\r\n",
vp->key,
- time2str(timestr, sizeof(timestr), vp->mtime / 1000000),
+ hutil_time2str(timestr, sizeof(timestr), vp->mtime / 1000000),
vp->md5,
(unsigned long long) vp->size,
vp->owner,
@@ -1185,7 +1185,7 @@ bool access_list(struct client *cli, const char *bucket, const char *key,
}
/* parse URI query string */
- param = req_query(&cli->req);
+ param = hreq_query(&cli->req);
if (!param)
goto err_out;
@@ -1360,7 +1360,7 @@ bool bucket_list(struct client *cli, const char *user, const char *bucket)
getacl = false;
if (cli->req.uri.query_len) {
- switch (req_is_query(&cli->req)) {
+ switch (hreq_is_query(&cli->req)) {
case URIQ_ACL:
getacl = true;
break;
diff --git a/server/object.c b/server/object.c
index 6d7fe92..207bb3e 100644
--- a/server/object.c
+++ b/server/object.c
@@ -224,7 +224,7 @@ bool object_del(struct client *cli, const char *user,
"\r\n",
cli->req.major,
cli->req.minor,
- time2str(timestr, sizeof(timestr), time(NULL))) < 0)
+ hutil_time2str(timestr, sizeof(timestr), time(NULL))) < 0)
return cli_err(cli, InternalError);
rc = cli_writeq(cli, hdr, strlen(hdr), cli_cb_free, hdr);
@@ -337,7 +337,7 @@ static bool object_put_end(struct client *cli)
uint64_t tmp_time;
void *mem;
- if (http11(&cli->req))
+ if (hreq_http11(&cli->req))
cli->state = evt_recycle;
else
cli->state = evt_dispose;
@@ -376,7 +376,7 @@ static bool object_put_end(struct client *cli)
md5str(md, md5);
- type = req_hdr(&cli->req, "content-type");
+ type = hreq_hdr(&cli->req, "content-type");
if (!type)
type = "binary/octet-stream";
else
@@ -515,7 +515,7 @@ static bool object_put_end(struct client *cli)
cli->req.major,
cli->req.minor,
md5,
- time2str(timestr, sizeof(timestr), time(NULL))) < 0) {
+ hutil_time2str(timestr, sizeof(timestr), time(NULL))) < 0) {
/* FIXME: cleanup failure */
applog(LOG_ERR, "OOM in object_put_end");
return cli_err(cli, InternalError);
@@ -878,13 +878,13 @@ static bool object_put_acls(struct client *cli, const char *user,
if (!user || !has_access(user, bucket, key, "WRITE_ACP"))
return cli_err(cli, AccessDenied);
- if ((rc = req_acl_canned(&cli->req)) == ACLCNUM) {
+ if ((rc = hreq_acl_canned(&cli->req)) == ACLCNUM) {
err = InvalidArgument;
goto err_out_parm;
}
canacl = (rc == -1)? ACLC_PRIV: rc;
- if (http11(&cli->req))
+ if (hreq_http11(&cli->req))
cli->state = evt_recycle;
else
cli->state = evt_dispose;
@@ -929,7 +929,7 @@ static bool object_put_acls(struct client *cli, const char *user,
"\r\n",
cli->req.major,
cli->req.minor,
- time2str(timestr, sizeof(timestr), time(NULL))) < 0) {
+ hutil_time2str(timestr, sizeof(timestr), time(NULL))) < 0) {
/* FIXME: cleanup failure */
applog(LOG_ERR, "OOM in object_put_end");
return cli_err(cli, InternalError);
@@ -959,7 +959,7 @@ bool object_put(struct client *cli, const char *user, const char *bucket,
setacl = false;
if (cli->req.uri.query_len) {
- switch (req_is_query(&cli->req)) {
+ switch (hreq_is_query(&cli->req)) {
case URIQ_ACL:
setacl = true;
break;
@@ -1162,7 +1162,7 @@ static bool object_get_body(struct client *cli, const char *user,
md5 = obj->md5;
- hdr = req_hdr(&cli->req, "if-match");
+ hdr = hreq_hdr(&cli->req, "if-match");
if (hdr && strcmp(md5, hdr)) {
err = PreconditionFailed;
goto err_out_reset;
@@ -1250,11 +1250,11 @@ static bool object_get_body(struct client *cli, const char *user,
stor_node_put(stnode);
- hdr = req_hdr(&cli->req, "if-unmodified-since");
+ hdr = hreq_hdr(&cli->req, "if-unmodified-since");
if (hdr) {
time_t t;
- t = str2time(hdr);
+ t = hutil_str2time(hdr);
if (!t) {
err = InvalidArgument;
goto err_out_in_end;
@@ -1266,11 +1266,11 @@ static bool object_get_body(struct client *cli, const char *user,
}
}
- hdr = req_hdr(&cli->req, "if-modified-since");
+ hdr = hreq_hdr(&cli->req, "if-modified-since");
if (hdr) {
time_t t;
- t = str2time(hdr);
+ t = hutil_str2time(hdr);
if (!t) {
err = InvalidArgument;
goto err_out_in_end;
@@ -1282,7 +1282,7 @@ static bool object_get_body(struct client *cli, const char *user,
}
}
- hdr = req_hdr(&cli->req, "if-none-match");
+ hdr = hreq_hdr(&cli->req, "if-none-match");
if (hdr && (!strcmp(md5, hdr))) {
modified = false;
want_body = false;
@@ -1302,8 +1302,8 @@ static bool object_get_body(struct client *cli, const char *user,
modified ? 200 : 304,
(unsigned long long) GUINT64_FROM_LE(obj->size),
md5,
- time2str(timestr, sizeof(timestr), time(NULL)),
- time2str(modstr, sizeof(modstr),
+ hutil_time2str(timestr, sizeof(timestr), time(NULL)),
+ hutil_time2str(modstr, sizeof(modstr),
GUINT64_FROM_LE(obj->mtime) / 1000000),
extra_hdr->str) < 0)
goto err_out_in_end;
@@ -1396,7 +1396,7 @@ bool object_get(struct client *cli, const char *user, const char *bucket,
getacl = false;
if (cli->req.uri.query_len) {
- switch (req_is_query(&cli->req)) {
+ switch (hreq_is_query(&cli->req)) {
case URIQ_ACL:
getacl = true;
break;
diff --git a/server/server.c b/server/server.c
index 4e8dba3..7950693 100644
--- a/server/server.c
+++ b/server/server.c
@@ -356,7 +356,7 @@ static int authcheck(struct http_req *req, char *extra_bucket,
pass = val.data;
}
- req_sign(req, extra_bucket, pass, b64sig);
+ hreq_sign(req, extra_bucket, pass, b64sig);
free(pass);
if (strncmp(b64sig, auth + captured[4], usiglen) != 0) {
@@ -493,7 +493,7 @@ static void cli_free(struct client *cli)
close(cli->fd);
}
- req_free(&cli->req);
+ hreq_free(&cli->req);
if (cli->write_cnt_max > tabled_srv.stats.max_write_buf)
tabled_srv.stats.max_write_buf = cli->write_cnt_max;
@@ -519,7 +519,7 @@ static bool cli_evt_recycle(struct client *cli, unsigned int events)
{
unsigned int slop;
- req_free(&cli->req);
+ hreq_free(&cli->req);
cli->hdr_start = NULL;
cli->hdr_end = NULL;
@@ -769,7 +769,7 @@ bool cli_err(struct client *cli, enum errcode code)
cli->req.minor,
err_info[code].status,
strlen(content),
- time2str(timestr, sizeof(timestr), time(NULL)),
+ hutil_time2str(timestr, sizeof(timestr), time(NULL)),
"*");
if (rc < 0) {
free(content);
@@ -788,7 +788,7 @@ bool cli_err(struct client *cli, enum errcode code)
cli->req.minor,
err_info[code].status,
strlen(content),
- time2str(timestr, sizeof(timestr), time(NULL)));
+ hutil_time2str(timestr, sizeof(timestr), time(NULL)));
if (rc < 0) {
free(content);
return false;
@@ -819,7 +819,7 @@ static bool cli_resp(struct client *cli, int http_status,
{
int rc;
char *hdr, timestr[50];
- bool rcb, cxn_close = !http11(&cli->req);
+ bool rcb, cxn_close = !hreq_http11(&cli->req);
if (asprintf(&hdr,
"HTTP/%d.%d %d x\r\n"
@@ -834,7 +834,7 @@ static bool cli_resp(struct client *cli, int http_status,
http_status,
content_type,
strlist_len(content),
- time2str(timestr, sizeof(timestr), time(NULL)),
+ hutil_time2str(timestr, sizeof(timestr), time(NULL)),
cxn_close ? "Connection: close\r\n" : "") < 0) {
__strlist_free(content);
return false;
@@ -901,11 +901,11 @@ static bool cli_evt_http_req(struct client *cli, unsigned int events)
}
/* grab useful headers */
- host = req_hdr(req, "host");
- content_len_str = req_hdr(req, "content-length");
- auth = req_hdr(req, "authorization");
+ host = hreq_hdr(req, "host");
+ content_len_str = hreq_hdr(req, "content-length");
+ auth = hreq_hdr(req, "authorization");
if (req->major > 1 || req->minor > 0) {
- char *expect = req_hdr(req, "expect");
+ char *expect = hreq_hdr(req, "expect");
if (expect && strcasestr(expect, "100-continue"))
expect_cont = true;
}
@@ -947,7 +947,7 @@ static bool cli_evt_http_req(struct client *cli, unsigned int events)
* the operations below may override this next-state setting,
* however.
*/
- if (http11(req))
+ if (hreq_http11(req))
cli->state = evt_recycle;
else
cli->state = evt_dispose;
@@ -1113,7 +1113,7 @@ static bool cli_hdr_flush(struct client *cli, bool *loop_state)
*tmp = 0;
/* add to list of headers */
- if (req_hdr_push(&cli->req, cli->hdr_start, tmp + 1)) {
+ if (hreq_hdr_push(&cli->req, cli->hdr_start, tmp + 1)) {
err_resp = InvalidArgument;
goto err_out;
}
@@ -1246,14 +1246,14 @@ static bool cli_evt_parse_req(struct client *cli, unsigned int events)
strup(cli->req.method);
/* URI is the second token, immediately following the first space */
- if (!uri_parse(&cli->req.uri, sp1 + 1)) {
+ if (!huri_parse(&cli->req.uri, sp1 + 1)) {
err_resp = InvalidURI;
goto err_out;
}
cli->req.orig_path = g_strndup(cli->req.uri.path, cli->req.uri.path_len);
- cli->req.uri.path_len = field_unescape(cli->req.uri.path,
+ cli->req.uri.path_len = huri_field_unescape(cli->req.uri.path,
cli->req.uri.path_len);
/* HTTP version is the final token, following second space */
diff --git a/server/status.c b/server/status.c
index 8fb142b..e9fbb38 100644
--- a/server/status.c
+++ b/server/status.c
@@ -102,7 +102,7 @@ static bool stat_err(struct client *cli, enum errcode code)
"\r\n",
cli->req.major, cli->req.minor, err_status,
strlen(content),
- time2str(timestr, sizeof(timestr), time(NULL)));
+ hutil_time2str(timestr, sizeof(timestr), time(NULL)));
if (rc < 0)
goto out_hdr;
@@ -160,7 +160,7 @@ bool stat_evt_http_req(struct client *cli, unsigned int events)
bool rcb;
/* grab useful headers */
- // content_len_str = req_hdr(req, "content-length");
+ // content_len_str = hreq_hdr(req, "content-length");
path = strdup(req->uri.path);
if (!path)
@@ -178,7 +178,7 @@ bool stat_evt_http_req(struct client *cli, unsigned int events)
* the operations below may override this next-state setting,
* however.
*/
- if (http11(req))
+ if (hreq_http11(req))
cli->state = evt_recycle;
else
cli->state = evt_dispose;
diff --git a/server/tabled.h b/server/tabled.h
index b6e4cbb..ae67838 100644
--- a/server/tabled.h
+++ b/server/tabled.h
@@ -27,7 +27,7 @@
#include <glib.h>
#include <pcre.h>
#include <event.h>
-#include <httputil.h>
+#include <hstor.h>
#include <elist.h>
#include <tdb.h>
#include <hail_log.h>
diff --git a/test/Makefile.am b/test/Makefile.am
index 3d751bc..9264cba 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -34,10 +34,9 @@ check_PROGRAMS = basic-bucket basic-object it-works large-object \
noinst_LIBRARIES = libtest.a
-TESTLDADD = ../lib/libhttpstor.la \
- ../lib/libhttputil.a \
- libtest.a \
- @LIBCURL@ @GLIB_LIBS@ @CRYPTO_LIBS@ @XML_LIBS@
+TESTLDADD = libtest.a \
+ @HAIL_LIBS@ @GLIB_LIBS@ \
+ @LIBCURL@ @CRYPTO_LIBS@ @XML_LIBS@
basic_bucket_LDADD = $(TESTLDADD)
basic_object_LDADD = $(TESTLDADD)
large_object_LDADD = $(TESTLDADD)
@@ -45,6 +44,6 @@ hdr_content_type_LDADD = $(TESTLDADD)
hdr_meta_LDADD = $(TESTLDADD)
it_works_LDADD = $(TESTLDADD)
-wait_for_listen_LDADD = ../lib/libhttputil.a
+wait_for_listen_LDADD = libtest.a
TESTS_ENVIRONMENT=top_srcdir=$(top_srcdir)
diff --git a/test/basic-bucket.c b/test/basic-bucket.c
index da54547..a1c705d 100644
--- a/test/basic-bucket.c
+++ b/test/basic-bucket.c
@@ -22,15 +22,14 @@
#include <string.h>
#include <locale.h>
-#include <httpstor.h>
-#include <httputil.h>
+#include <hstor.h>
#include "test.h"
int main(int argc, char *argv[])
{
- struct httpstor_client *httpstor;
- struct httpstor_blist *blist;
- struct httpstor_bucket *buck;
+ struct hstor_client *hstor;
+ struct hstor_blist *blist;
+ struct hstor_bucket *buck;
bool rcb;
char accbuf[80];
int rc;
@@ -40,22 +39,22 @@ int main(int argc, char *argv[])
rc = tb_readport(TEST_FILE_TB, accbuf, sizeof(accbuf));
OK(rc > 0);
- httpstor = httpstor_new(accbuf, TEST_HOST, TEST_USER, TEST_USER_KEY);
- OK(httpstor);
+ hstor = hstor_new(accbuf, TEST_HOST, TEST_USER, TEST_USER_KEY);
+ OK(hstor);
/* make sure bucket list is empty */
- blist = httpstor_list_buckets(httpstor);
+ blist = hstor_list_buckets(hstor);
OK(blist);
OK(!blist->list);
- httpstor_free_blist(blist);
+ hstor_free_blist(blist);
/* add bucket */
- rcb = httpstor_add_bucket(httpstor, "test1");
+ rcb = hstor_add_bucket(hstor, "test1");
OK(rcb);
/* make sure bucket list contains one item */
- blist = httpstor_list_buckets(httpstor);
+ blist = hstor_list_buckets(hstor);
OK(blist);
OK(blist->list);
OK(blist->list->next == NULL);
@@ -63,18 +62,18 @@ int main(int argc, char *argv[])
buck = blist->list->data;
OK(!strcmp(buck->name, "test1"));
- httpstor_free_blist(blist);
+ hstor_free_blist(blist);
/* delete bucket */
- rcb = httpstor_del_bucket(httpstor, "test1");
+ rcb = hstor_del_bucket(hstor, "test1");
OK(rcb);
/* make sure bucket list is empty */
- blist = httpstor_list_buckets(httpstor);
+ blist = hstor_list_buckets(hstor);
OK(blist);
OK(!blist->list);
- httpstor_free_blist(blist);
+ hstor_free_blist(blist);
return 0;
}
diff --git a/test/basic-object.c b/test/basic-object.c
index 0761e31..85adc79 100644
--- a/test/basic-object.c
+++ b/test/basic-object.c
@@ -22,15 +22,14 @@
#include <string.h>
#include <locale.h>
-#include <httpstor.h>
-#include <httputil.h>
+#include <hstor.h>
#include "test.h"
int main(int argc, char *argv[])
{
static char bucket[] = "test1";
static char key[] = "my first key";
- struct httpstor_client *httpstor;
+ struct hstor_client *hstor;
char accbuf[80];
int rc;
bool rcb;
@@ -43,29 +42,29 @@ int main(int argc, char *argv[])
rc = tb_readport(TEST_FILE_TB, accbuf, sizeof(accbuf));
OK(rc > 0);
- httpstor = httpstor_new(accbuf, TEST_HOST, TEST_USER, TEST_USER_KEY);
- OK(httpstor);
+ hstor = hstor_new(accbuf, TEST_HOST, TEST_USER, TEST_USER_KEY);
+ OK(hstor);
/* add bucket */
- rcb = httpstor_add_bucket(httpstor, bucket);
+ rcb = hstor_add_bucket(hstor, bucket);
OK(rcb);
/* store object */
- rcb = httpstor_put_inline(httpstor, bucket, key, val, strlen(val), NULL);
+ rcb = hstor_put_inline(hstor, bucket, key, val, strlen(val), NULL);
OK(rcb);
/* get object */
- mem = httpstor_get_inline(httpstor, bucket, key, false, &len);
+ mem = hstor_get_inline(hstor, bucket, key, false, &len);
OK(mem);
OK(len == strlen(val));
OK(!memcmp(val, mem, strlen(val)));
/* delete object */
- rcb = httpstor_del(httpstor, bucket, key);
+ rcb = hstor_del(hstor, bucket, key);
OK(rcb);
/* delete bucket */
- rcb = httpstor_del_bucket(httpstor, bucket);
+ rcb = hstor_del_bucket(hstor, bucket);
OK(rcb);
return 0;
diff --git a/test/hdr-content-type.c b/test/hdr-content-type.c
index f798638..6987372 100644
--- a/test/hdr-content-type.c
+++ b/test/hdr-content-type.c
@@ -25,8 +25,7 @@
#include <stdlib.h>
#include <ctype.h>
#include <locale.h>
-#include <httpstor.h>
-#include <httputil.h>
+#include <hstor.h>
#include "test.h"
static char bucket[] = "test-hdr-ctt";
@@ -38,17 +37,17 @@ static char *user_hdrs[] = {
NULL
};
-static void runtest(struct httpstor_client *httpstor)
+static void runtest(struct hstor_client *hstor)
{
bool rcb;
void *data = NULL;
size_t data_len = 0;
- rcb = httpstor_put_inline(httpstor, bucket, key,
+ rcb = hstor_put_inline(hstor, bucket, key,
value, strlen(value) + 1, user_hdrs);
OK(rcb);
- data = httpstor_get_inline(httpstor, bucket, key, true, &data_len);
+ data = hstor_get_inline(hstor, bucket, key, true, &data_len);
OK(data);
OK(data_len > 0);
@@ -60,7 +59,7 @@ static void runtest(struct httpstor_client *httpstor)
int main(int argc, char *argv[])
{
- struct httpstor_client *httpstor;
+ struct hstor_client *hstor;
char accbuf[80];
int rc;
bool rcb;
@@ -70,19 +69,19 @@ int main(int argc, char *argv[])
rc = tb_readport(TEST_FILE_TB, accbuf, sizeof(accbuf));
OK(rc > 0);
- httpstor = httpstor_new(accbuf, TEST_HOST, TEST_USER, TEST_USER_KEY);
- OK(httpstor);
+ hstor = hstor_new(accbuf, TEST_HOST, TEST_USER, TEST_USER_KEY);
+ OK(hstor);
/* add bucket - since tests are independent, we do not rely on others */
- rcb = httpstor_add_bucket(httpstor, bucket);
+ rcb = hstor_add_bucket(hstor, bucket);
OK(rcb);
- runtest(httpstor);
+ runtest(hstor);
- rcb = httpstor_del(httpstor, bucket, key);
+ rcb = hstor_del(hstor, bucket, key);
OK(rcb);
- rcb = httpstor_del_bucket(httpstor, bucket);
+ rcb = hstor_del_bucket(hstor, bucket);
OK(rcb);
return 0;
diff --git a/test/hdr-meta.c b/test/hdr-meta.c
index 424006c..d7f7414 100644
--- a/test/hdr-meta.c
+++ b/test/hdr-meta.c
@@ -25,8 +25,7 @@
#include <stdlib.h>
#include <ctype.h>
#include <locale.h>
-#include <httpstor.h>
-#include <httputil.h>
+#include <hstor.h>
#include "test.h"
static char bucket[] = "test-hdr-meta";
@@ -39,18 +38,18 @@ static char *user_hdrs[] = {
NULL
};
-static void runtest(struct httpstor_client *httpstor)
+static void runtest(struct hstor_client *hstor)
{
bool rcb;
void *data = NULL;
size_t data_len = 0;
int idx;
- rcb = httpstor_put_inline(httpstor, bucket, key,
+ rcb = hstor_put_inline(hstor, bucket, key,
value, strlen(value) + 1, user_hdrs);
OK(rcb);
- data = httpstor_get_inline(httpstor, bucket, key, true, &data_len);
+ data = hstor_get_inline(hstor, bucket, key, true, &data_len);
OK(data);
OK(data_len > 0);
@@ -67,7 +66,7 @@ static void runtest(struct httpstor_client *httpstor)
int main(int argc, char *argv[])
{
- struct httpstor_client *httpstor;
+ struct hstor_client *hstor;
char accbuf[80];
int rc;
bool rcb;
@@ -77,19 +76,19 @@ int main(int argc, char *argv[])
rc = tb_readport(TEST_FILE_TB, accbuf, sizeof(accbuf));
OK(rc > 0);
- httpstor = httpstor_new(accbuf, TEST_HOST, TEST_USER, TEST_USER_KEY);
- OK(httpstor);
+ hstor = hstor_new(accbuf, TEST_HOST, TEST_USER, TEST_USER_KEY);
+ OK(hstor);
/* add bucket - since tests are independent, we do not rely on others */
- rcb = httpstor_add_bucket(httpstor, bucket);
+ rcb = hstor_add_bucket(hstor, bucket);
OK(rcb);
- runtest(httpstor);
+ runtest(hstor);
- rcb = httpstor_del(httpstor, bucket, key);
+ rcb = hstor_del(hstor, bucket, key);
OK(rcb);
- rcb = httpstor_del_bucket(httpstor, bucket);
+ rcb = hstor_del_bucket(hstor, bucket);
OK(rcb);
return 0;
diff --git a/test/it-works.c b/test/it-works.c
index c1fddd3..534f6cd 100644
--- a/test/it-works.c
+++ b/test/it-works.c
@@ -22,14 +22,13 @@
#include <string.h>
#include <locale.h>
-#include <httpstor.h>
-#include <httputil.h>
+#include <hstor.h>
#include "test.h"
int main(int argc, char *argv[])
{
- struct httpstor_client *httpstor;
- struct httpstor_blist *blist;
+ struct hstor_client *hstor;
+ struct hstor_blist *blist;
char accbuf[80];
int rc;
@@ -38,14 +37,14 @@ int main(int argc, char *argv[])
rc = tb_readport(TEST_FILE_TB, accbuf, sizeof(accbuf));
OK(rc > 0);
- httpstor = httpstor_new(accbuf, TEST_HOST, TEST_USER, TEST_USER_KEY);
- OK(httpstor);
+ hstor = hstor_new(accbuf, TEST_HOST, TEST_USER, TEST_USER_KEY);
+ OK(hstor);
- blist = httpstor_list_buckets(httpstor);
+ blist = hstor_list_buckets(hstor);
OK(blist);
- OK(!strcmp(blist->own_id, httpstor->user));
- OK(!strcmp(blist->own_name, httpstor->user));
+ OK(!strcmp(blist->own_id, hstor->user));
+ OK(!strcmp(blist->own_name, hstor->user));
OK(!blist->list);
return 0;
diff --git a/test/large-object.c b/test/large-object.c
index 919bbc4..dbe2027 100644
--- a/test/large-object.c
+++ b/test/large-object.c
@@ -30,8 +30,7 @@
#include <string.h>
#include <stdlib.h>
#include <locale.h>
-#include <httpstor.h>
-#include <httputil.h>
+#include <hstor.h>
#include "test.h"
#define BLKSZ0 1024
@@ -162,7 +161,7 @@ static size_t get_cb(void *ptr, size_t membsize, size_t nmemb, void *user_data)
return nmemb;
}
-static void runtest(struct httpstor_client *httpstor,
+static void runtest(struct hstor_client *hstor,
size_t blklen, int nblks)
{
off_t total = blklen * nblks;
@@ -176,7 +175,7 @@ static void runtest(struct httpstor_client *httpstor,
putctx.blksize = blklen;
putctx.total = total;
- rcb = httpstor_put(httpstor, bucket, key, put_cb, total, &putctx, NULL);
+ rcb = hstor_put(hstor, bucket, key, put_cb, total, &putctx, NULL);
OK(rcb);
OK(putctx.off == total);
@@ -186,7 +185,7 @@ static void runtest(struct httpstor_client *httpstor,
getctx.csum = CSUM_INIT;
getctx.blksize = blklen;
- rcb = httpstor_get(httpstor, bucket, key, get_cb, &getctx, false);
+ rcb = hstor_get(hstor, bucket, key, get_cb, &getctx, false);
OK(rcb);
OK(getctx.off == total);
@@ -195,7 +194,7 @@ static void runtest(struct httpstor_client *httpstor,
int main(int argc, char *argv[])
{
- struct httpstor_client *httpstor;
+ struct hstor_client *hstor;
char accbuf[80];
int rc;
bool rcb;
@@ -205,21 +204,21 @@ int main(int argc, char *argv[])
rc = tb_readport(TEST_FILE_TB, accbuf, sizeof(accbuf));
OK(rc > 0);
- httpstor = httpstor_new(accbuf, TEST_HOST, TEST_USER, TEST_USER_KEY);
- OK(httpstor);
+ hstor = hstor_new(accbuf, TEST_HOST, TEST_USER, TEST_USER_KEY);
+ OK(hstor);
/* add bucket - since tests are independent, we do not rely on others */
- rcb = httpstor_add_bucket(httpstor, bucket);
+ rcb = hstor_add_bucket(hstor, bucket);
OK(rcb);
- runtest(httpstor, BLKSZ0, NBLKS0);
- runtest(httpstor, BLKSZ1, NBLKS1);
- runtest(httpstor, BLKSZ2, NBLKS2);
+ runtest(hstor, BLKSZ0, NBLKS0);
+ runtest(hstor, BLKSZ1, NBLKS1);
+ runtest(hstor, BLKSZ2, NBLKS2);
- rcb = httpstor_del(httpstor, bucket, key);
+ rcb = hstor_del(hstor, bucket, key);
OK(rcb);
- rcb = httpstor_del_bucket(httpstor, bucket);
+ rcb = hstor_del_bucket(hstor, bucket);
OK(rcb);
return 0;
diff --git a/test/libtest.c b/test/libtest.c
index bdfe912..1e15172 100644
--- a/test/libtest.c
+++ b/test/libtest.c
@@ -17,9 +17,14 @@
*
*/
+#include <sys/types.h>
+#include <sys/stat.h>
#include <string.h>
#include <stdbool.h>
+#include <unistd.h>
#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
#include "test.h"
bool find_our_hdr(const char *hdr, const void *data, size_t data_len)
@@ -61,3 +66,34 @@ bool find_our_hdr(const char *hdr, const void *data, size_t data_len)
return false;
}
+/*
+ * Read a port number from a port file, fill buffer.
+ * Unlike cld_readport, host is included as well, and we use strings.
+ */
+int tb_readport(const char *fname, char *buf, size_t len)
+{
+ int fd;
+ char *s;
+ int rc;
+
+ if (len < 3)
+ return -EDOM;
+ if ((fd = open(fname, O_RDONLY)) == -1)
+ return -errno;
+ rc = read(fd, buf, len-1);
+ close(fd);
+ if (rc < 0)
+ return -errno;
+ if (rc == 0)
+ return -EPIPE;
+ buf[rc] = 0;
+
+ s = strchr(buf, '\n');
+ if (s) {
+ *s = 0;
+ rc = s - buf;
+ }
+
+ return rc;
+}
+
diff --git a/test/test.h b/test/test.h
index 50b7e36..ae7b68b 100644
--- a/test/test.h
+++ b/test/test.h
@@ -19,7 +19,7 @@
*
*/
-
+#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
@@ -39,5 +39,6 @@
} while (0)
extern bool find_our_hdr(const char *hdr, const void *data, size_t data_len);
+extern int tb_readport(const char *fname, char *buf, size_t len);
#endif /* __TABLED_TEST_H__ */
diff --git a/test/wait-for-listen.c b/test/wait-for-listen.c
index d52690e..fef5028 100644
--- a/test/wait-for-listen.c
+++ b/test/wait-for-listen.c
@@ -34,7 +34,6 @@
#include <time.h>
#include <unistd.h>
#include <netdb.h>
-#include <httputil.h>
#include "test.h"
#define ADDRSIZE 24 /* Enough for IPv6, including port. */
next reply other threads:[~2010-07-07 22:38 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-07-07 22:38 Jeff Garzik [this message]
2010-07-08 0:38 ` [PATCH] tabled: use httpstor API from libhail Jeff Garzik
2010-07-08 1:05 ` Jeff Garzik
2010-07-08 3:23 ` Pete Zaitcev
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100707223822.GA25328@havoc.gtf.org \
--to=jeff@garzik.org \
--cc=hail-devel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).