Drill many neon hooks.

CVS patchset: 7552
CVS date: 2004/11/07 18:49:08
This commit is contained in:
jbj 2004-11-07 18:49:08 +00:00
parent 351af63e8c
commit e5370f96a4
9 changed files with 331 additions and 65 deletions

View File

@ -12,6 +12,7 @@ tdigest
tdir
tficl
tfts
tget
tglob
tinv
tkey

View File

@ -4,9 +4,9 @@ AUTOMAKE_OPTIONS = 1.4 foreign
LINT = splint
EXTRA_DIST = tax.c tdigest.c tdir.c tficl.c tfts.c tget.c tglob.c tinv.c tkey.c trpmio.c
EXTRA_DIST = tax.c tdigest.c tdir.c tficl.c tfts.c tget.c tput.c tglob.c tinv.c tkey.c trpmio.c
EXTRA_PROGRAMS = tax tdigest tdir tfts tget tglob tinv tkey tring trpmio tsw dumpasn1
EXTRA_PROGRAMS = tax tdigest tdir tfts tget tput tglob tinv tkey tring trpmio tsw dumpasn1
INCLUDES = -I. \
-I$(top_srcdir) \
@ -84,6 +84,11 @@ tget_SOURCES = tget.c
tget_LDFLAGS = -all-static
tget_LDADD = librpmio.la $(top_builddir)/popt/libpopt.la
tput_SOURCES = tput.c
tput_LDFLAGS = -all-static
tput_LDADD = librpmio.la $(top_builddir)/popt/libpopt.la
tglob_SOURCES = tglob.c
tglob_LDFLAGS = -all-static
tglob_LDADD = librpmio.la $(top_builddir)/popt/libpopt.la

View File

@ -37,6 +37,10 @@
/*@access FD_t @*/
/*@access urlinfo @*/
#define TIMEOUT_SECS 60
/*@unchecked@*/
static int httpTimeoutSecs = TIMEOUT_SECS;
/**
* Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
* @param p memory to free
@ -66,14 +70,173 @@ static int davFree(urlinfo u)
return 0;
}
static void davProgress(void * userdata, off_t current, off_t total)
{
urlinfo u = userdata;
ne_session * sess;
assert(u != NULL);
sess = u->sess;
assert(sess != NULL);
assert(u == ne_get_session_private(sess, "urlinfo"));
u->current = current;
u->total = total;
if (_dav_debug)
fprintf(stderr, "*** davProgress(%p,0x%x:0x%x) sess %p u %p\n", userdata, (unsigned int)current, (unsigned int)total, sess, u);
}
static void davNotify(void * userdata,
ne_conn_status connstatus, const char * info)
{
urlinfo u = userdata;
ne_session * sess;
static const char * connstates[] = {
"namelookup",
"connecting",
"connected",
"secure",
"unknown"
};
assert(u != NULL);
sess = u->sess;
assert(sess != NULL);
assert(u == ne_get_session_private(sess, "urlinfo"));
#ifdef REFERENCE
typedef enum {
ne_conn_namelookup, /* lookup up hostname (info = hostname) */
ne_conn_connecting, /* connecting to host (info = hostname) */
ne_conn_connected, /* connected to host (info = hostname) */
ne_conn_secure /* connection now secure (info = crypto level) */
} ne_conn_status;
#endif
u->connstatus = connstatus;
if (_dav_debug)
fprintf(stderr, "*** davNotify(%p,%d,%p) sess %p u %p %s\n", userdata, connstatus, info, sess, u, connstates[ (connstatus < 4 ? connstatus : 4)]);
}
static void davCreateRequest(ne_request * req, void * userdata,
const char * method, const char * uri)
{
urlinfo u = userdata;
ne_session * sess;
void * private = NULL;;
const char * id = "urlinfo";
assert(u != NULL);
assert(u->sess);
assert(req != NULL);
sess = ne_get_session(req);
assert(sess == u->sess);
assert(u == ne_get_session_private(sess, "urlinfo"));
assert(sess != NULL);
private = ne_get_session_private(sess, id);
assert(u == private);
if (_dav_debug)
fprintf(stderr, "*** davCreateRequest(%p,%p,%s,%s) %s:%p\n", req, userdata, method, uri, id, private);
}
static void davPreSend(ne_request * req, void * userdata, ne_buffer * buf)
{
urlinfo u = userdata;
ne_session * sess;
const char * id = "fd";
FD_t fd = NULL;
assert(u != NULL);
assert(u->sess);
assert(req != NULL);
sess = ne_get_session(req);
assert(sess == u->sess);
assert(u == ne_get_session_private(sess, "urlinfo"));
fd = ne_get_request_private(req, id);
if (_dav_debug) {
fprintf(stderr, "*** davPreSend(%p,%p,%p) sess %p %s %p\n", req, userdata, buf, sess, id, fd);
fprintf(stderr, "-> %s\n", buf->data);
}
}
static int davPostSend(ne_request * req, void * userdata, const ne_status * status)
{
urlinfo u = userdata;
ne_session * sess;
const char * id = "fd";
FD_t fd = NULL;
assert(u != NULL);
assert(u->sess);
assert(req != NULL);
sess = ne_get_session(req);
assert(sess == u->sess);
assert(u == ne_get_session_private(sess, "urlinfo"));
fd = ne_get_request_private(req, id);
if (_dav_debug)
fprintf(stderr, "*** davPostSend(%p,%p,%p) sess %p %s %p %s\n", req, userdata, status, sess, id, fd, ne_get_error(sess));
return NE_OK;
}
static void davDestroyRequest(ne_request * req, void * userdata)
{
urlinfo u = userdata;
ne_session * sess;
const char * id = "fd";
FD_t fd = NULL;
assert(u != NULL);
assert(u->sess);
assert(req != NULL);
sess = ne_get_session(req);
assert(sess == u->sess);
assert(u == ne_get_session_private(sess, "urlinfo"));
fd = ne_get_request_private(req, id);
if (_dav_debug)
fprintf(stderr, "*** davDestroyRequest(%p,%p) sess %p %s %p\n", req, userdata, sess, id, fd);
}
static void davDestroySession(void * userdata)
{
urlinfo u = userdata;
ne_session * sess;
void * private = NULL;;
const char * id = "urlinfo";
assert(u != NULL);
assert(u->sess);
sess = u->sess;
assert(u == ne_get_session_private(sess, "urlinfo"));
assert(sess != NULL);
private = ne_get_session_private(sess, id);
assert(u == private);
if (_dav_debug)
fprintf(stderr, "*** davDestroySession(%p) sess %p %s %p\n", userdata, sess, id, private);
}
static int
trust_all_server_certs(/*@unused@*/ void *userdata, /*@unused@*/ int failures,
/*@unused@*/ const ne_ssl_certificate *cert)
davVerifyCert(void *userdata, int failures, const ne_ssl_certificate *cert)
/*@*/
{
#if 0
const char *hostname = userdata;
#endif
if (_dav_debug)
fprintf(stderr, "*** davVerifyCert(%p,%d,%p) %s\n", userdata, failures, cert, hostname);
return 0; /* HACK: trust all server certificates. */
}
@ -102,14 +265,38 @@ static int davInit(const char * url, urlinfo * uret)
u->capabilities = capabilities = xcalloc(1, sizeof(*capabilities));
u->sess = ne_session_create(u->scheme, u->host, u->port);
/* XXX check that neon is ssl enabled. */
if (!strcasecmp(u->scheme, "https"))
ne_ssl_set_verify(u->sess, trust_all_server_certs, (char *)u->host);
u->lockstore = ne_lockstore_create(); /* XXX oneshot? */
ne_lockstore_register(u->lockstore, u->sess);
if (u->proxyh != NULL)
ne_session_proxy(u->sess, u->proxyh, u->proxyp);
#if 0
{ const ne_inet_addr ** addrs;
unsigned int n;
ne_set_addrlist(u->sess, addrs, n);
}
#endif
ne_set_progress(u->sess, davProgress, u);
ne_set_status(u->sess, davNotify, u);
ne_set_persist(u->sess, 1);
ne_set_read_timeout(u->sess, httpTimeoutSecs);
ne_set_useragent(u->sess, PACKAGE "/" PACKAGE_VERSION);
/* XXX check that neon is ssl enabled. */
if (!strcasecmp(u->scheme, "https"))
ne_ssl_set_verify(u->sess, davVerifyCert, (char *)u->host);
ne_set_session_private(u->sess, "urlinfo", u);
ne_hook_destroy_session(u->sess, davDestroySession, u);
ne_hook_create_request(u->sess, davCreateRequest, u);
ne_hook_pre_send(u->sess, davPreSend, u);
ne_hook_post_send(u->sess, davPostSend, u);
ne_hook_destroy_request(u->sess, davDestroyRequest, u);
}
if (uret != NULL)
@ -128,6 +315,7 @@ static int davConnect(urlinfo u)
/* HACK: where should server capabilities be read? */
(void) urlPath(u->url, &path);
/* HACK: perhaps capture Allow: tag, look for PUT permitted. */
rc = ne_options(u->sess, path, u->capabilities);
switch (rc) {
case NE_OK:
@ -141,10 +329,18 @@ static int davConnect(urlinfo u)
case NE_LOOKUP:
default:
if (_dav_debug)
fprintf(stderr, "Connect to %s:%d failed(%d):\n%s\n",
fprintf(stderr, "*** Connect to %s:%d failed(%d):\n\t%s\n",
u->host, u->port, rc, ne_get_error(u->sess));
break;
}
/* HACK: sensitive to error returns? */
u->httpVersion = (ne_version_pre_http11(u->sess) ? 0 : 1);
/* HACK: stupid error impedence matching. */
if (rc)
rc = FTPERR_FAILED_CONNECT;
return rc;
}
@ -549,7 +745,8 @@ static int davNLST(struct fetch_context_s * ctx)
break;
/*@fallthrough@*/
default:
fprintf(stderr, "Fetch from %s:%d failed:\n%s\n",
if (_dav_debug)
fprintf(stderr, "*** Fetch from %s:%d failed:\n\t%s\n",
u->host, u->port, ne_get_error(u->sess));
break;
}
@ -613,35 +810,48 @@ static void hexdump(unsigned char * buf, ssize_t len)
fprintf(stderr, "\n");
}
static void davAcceptRanges(void * userdata, const char * val)
static void davAcceptRanges(void * userdata, const char * value)
{
urlinfo u = userdata;
if (_dav_debug)
fprintf(stderr, "*** u %p Accept-Ranges: %s\n", u, val);
if (!strcmp(val, "bytes"))
fprintf(stderr, "*** u %p Accept-Ranges: %s\n", u, value);
if (!strcmp(value, "bytes"))
u->httpHasRange = 1;
if (!strcmp(val, "none"))
if (!strcmp(value, "none"))
u->httpHasRange = 0;
}
static void davContentLength(void * userdata, const char * val)
static void davAllHeaders(void * userdata, const char * value)
{
FD_t ctrl = userdata;
if (_dav_debug)
fprintf(stderr, "*** fd %p Content-Length: %s\n", ctrl, val);
ctrl->contentLength = strtoll(val, NULL, 10);
fprintf(stderr, "<- %s\n", value);
}
static void davConnection(void * userdata, const char * val)
static void davContentLength(void * userdata, const char * value)
{
FD_t ctrl = userdata;
if (_dav_debug)
fprintf(stderr, "*** fd %p Connection: %s\n", ctrl, val);
if (!strcmp(val, "close"))
fprintf(stderr, "*** fd %p Content-Length: %s\n", ctrl, value);
ctrl->contentLength = strtoll(value, NULL, 10);
}
static void davConnection(void * userdata, const char * value)
{
FD_t ctrl = userdata;
if (_dav_debug)
fprintf(stderr, "*** fd %p Connection: %s\n", ctrl, value);
if (!strcasecmp(value, "close"))
ctrl->persist = 0;
else if (!strcasecmp(value, "Keep-Alive"))
ctrl->persist = 1;
}
static int davResp(urlinfo u, FD_t ctrl, /*@unused@*/ /*@out@*/ char ** str)
int davResp(urlinfo u, FD_t ctrl, /*@unused@*/ char *const * str)
/*@globals fileSystem @*/
/*@modifies ctrl, *str, fileSystem @*/
{
@ -649,6 +859,8 @@ static int davResp(urlinfo u, FD_t ctrl, /*@unused@*/ /*@out@*/ char ** str)
rc = ne_begin_request(ctrl->req);
rc = my_result("ne_begin_req(ctrl->req)", rc, NULL);
if (_dav_debug)
fprintf(stderr, "*** davResp(%p,%p,%p) sess %p req %p rc %d\n", u, ctrl, str, u->sess, ctrl->req, rc);
#ifdef NOTYET
if (_ftp_debug)
@ -687,6 +899,9 @@ assert(ctrl != NULL);
u = ctrl->url;
URLSANE(u);
if (_dav_debug)
fprintf(stderr, "*** davReq(%p,%s,\"%s\") entry sess %p req %p\n", ctrl, httpCmd, httpArg, u->sess, ctrl->req);
/* HACK: handle proxy host and port here. */
#ifdef REFERENCE
if (((host = (u->proxyh ? u->proxyh : u->host)) == NULL))
@ -702,10 +917,19 @@ assert(ctrl != NULL);
/* HACK: where should server capabilities be read? */
rc = davConnect(u);
if (rc)
goto errxit;
ctrl->persist = (u->httpVersion > 0 ? 1 : 0);
ctrl = fdLink(ctrl, "open ctrl (davReq)");
assert(u->sess);
assert(ctrl->req == NULL);
ctrl->req = ne_request_create(u->sess, httpCmd, httpArg);
assert(ctrl->req != NULL);
ne_set_request_private(ctrl->req, "fd", ctrl);
ne_add_response_header_catcher(ctrl->req, davAllHeaders, ctrl);
ne_add_response_header_handler(ctrl->req, "Accept-Ranges",
davAcceptRanges, u);
@ -723,23 +947,21 @@ fprintf(stderr, "-> %s", req);
do {
rc = davResp(u, ctrl, NULL);
} while (rc == NE_RETRY);
if (rc)
goto errxit;
if (_dav_debug)
fprintf(stderr, "*** davReq(%p,%s,\"%s\") sess %p req %p rc %d\n", ctrl, httpCmd, httpArg, u->sess, ctrl->req, rc);
fprintf(stderr, "*** davReq(%p,%s,\"%s\") exit sess %p req %p rc %d\n", ctrl, httpCmd, httpArg, u->sess, ctrl->req, rc);
/* HACK: error path refcnts probably goofy here. */
if (rc == 0) {
ctrl = fdLink(ctrl, "open ctrl (davReq)");
ctrl = fdLink(ctrl, "open data (davReq)");
}
ctrl = fdLink(ctrl, "open data (davReq)");
return 0;
errxit:
fdSetSyserrno(ctrl, errno, ftpStrerror(rc));
return rc;
}
#define TIMEOUT_SECS 60
/*@unchecked@*/
static int httpTimeoutSecs = TIMEOUT_SECS;
FD_t davOpen(const char * url, /*@unused@*/ int flags,
/*@unused@*/ mode_t mode, /*@out@*/ urlinfo * uret)
{
@ -829,21 +1051,18 @@ fprintf(stderr, "*** davSeek(%p,pos,%d)\n", cookie, whence);
int davClose(/*@only@*/ void * cookie)
{
FD_t fd = cookie;
ne_request * req = fd->req;
int ret;
int rc;
if (_dav_debug)
fprintf(stderr, "*** davClose(%p)\n", cookie);
ret = ne_end_request(req);
ret = my_result("ne_end_request(req)", ret, NULL);
assert(fd->req != NULL);
rc = ne_end_request(fd->req);
rc = my_result("ne_end_request(req)", rc, NULL);
/* HACK: gotta figger NE_RETRY somehow. */
/* HACK: also needs doing in rpmio.c */
ne_request_destroy(req);
ne_request_destroy(fd->req);
fd->req = NULL;
return ret;
if (_dav_debug)
fprintf(stderr, "*** davClose(%p) rc %d\n", fd, rc);
return rc;
}
/* =============================================================== */

View File

@ -83,14 +83,25 @@ DIR * avOpendir(const char * path)
/*@-globuse@*/
/**
* Send a http request.
* @param data
* @param ctrl
* @param davCmd http command
* @param davArg http command argumeny
* @param davArg http command argument
* @returns 0 on success
*/
int davReq(FD_t data, const char * davCmd, const char * davArg)
int davReq(FD_t ctrl, const char * davCmd, const char * davArg)
/*@globals fileSystem, internalState @*/
/*@modifies data, fileSystem, internalState @*/;
/*@modifies ctrl, fileSystem, internalState @*/;
/**
* Read a http response.
* @param u
* @param cntl
* @retval *str error msg
* @returns 0 on success
*/
int davResp(urlinfo u, FD_t ctrl, /*@out@*/ char *const * str)
/*@globals fileSystem @*/
/*@modifies ctrl, *str, fileSystem @*/;
/**
*/

View File

@ -459,7 +459,12 @@ static int fdClose( /*@only@*/ void * cookie)
fdSetFdno(fd, -1);
fdstat_enter(fd, FDSTAT_CLOSE);
rc = ((fdno >= 0) ? close(fdno) : -2);
/* HACK: flimsy wiring for davClose */
if (fd->req != NULL) {
rc = davClose(fd);
assert(fd->req == NULL);
} else
rc = ((fdno >= 0) ? close(fdno) : -2);
fdstat_exit(fd, FDSTAT_CLOSE, rc);
DBGIO(fd, (stderr, "==>\tfdClose(%p) rc %lx %s\n", (fd ? fd : NULL), (unsigned long)rc, fdbg(fd)));
@ -559,6 +564,10 @@ int fdReadable(FD_t fd, int secs)
FD_ZERO(&rdfds);
#endif
/* HACK: flimsy wiring for davRead */
if (fd->req != NULL)
return 1;
if ((fdno = fdFileno(fd)) < 0)
return -1; /* XXX W2DO? */
@ -1724,8 +1733,6 @@ static ssize_t ufdRead(void * cookie, /*@out@*/ char * buf, size_t count)
bytesRead = 0;
/* HACK: flimsy wiring for davRead */
if (fd->req == NULL) {
/* Is there data to read? */
if (fd->bytesRemain == 0) return total; /* XXX simulate EOF */
rc = fdReadable(fd, fd->rd_timeoutsecs);
@ -1738,7 +1745,6 @@ static ssize_t ufdRead(void * cookie, /*@out@*/ char * buf, size_t count)
default: /* data to read */
/*@switchbreak@*/ break;
}
}
/*@-boundswrite@*/
rc = fdRead(fd, buf + total, count - total);
@ -1925,6 +1931,7 @@ int ufdClose( /*@only@*/ void * cookie)
/* XXX Why not (u->urltype == URL_IS_HTTPS) ??? */
if (u->scheme != NULL && !strncmp(u->scheme, "http", sizeof("http")-1))
{
/* HACK: not even close for neon. */
if (fd->wr_chunked) {
int rc;
/* XXX HTTP PUT requires terminating 0 length chunk. */
@ -1934,7 +1941,11 @@ int ufdClose( /*@only@*/ void * cookie)
if (_ftp_debug)
fprintf(stderr, "-> \r\n");
(void) fdWrite(fd, "\r\n", sizeof("\r\n")-1);
rc = httpResp(u, fd, NULL);
/* HACK: flimsy wiring for davClose */
if (!strcmp(u->scheme, "https"))
rc = davResp(u, fd, NULL);
else
rc = httpResp(u, fd, NULL);
}
if (fd == u->ctrl)
@ -1965,6 +1976,9 @@ fprintf(stderr, "-> \r\n");
if (fd->persist && u->httpVersion &&
(fd == u->ctrl || fd == u->data) && fd->bytesRemain == 0) {
fd->contentLength = fd->bytesRemain = -1;
/* HACK: flimsy wiring for davClose */
if (!strcmp(u->scheme, "https"))
return davClose(fd);
return 0;
} else {
fd->contentLength = fd->bytesRemain = -1;

View File

@ -57,7 +57,18 @@ struct urlinfo_s {
void * lockstore; /*!< neon ne_lock_store ptr */
/*@relnull@*/
void * sess; /*!< neon ne_session ptr */
off_t current; /*!< neon current body offset. */
off_t total; /*!< neon total body length. */
int connstatus; /*!< neon connection status. */
#ifdef REFERENCE
typedef enum {
ne_conn_namelookup, /* lookup up hostname (info = hostname) */
ne_conn_connecting, /* connecting to host (info = hostname) */
ne_conn_connected, /* connected to host (info = hostname) */
ne_conn_secure /* connection now secure (info = crypto level) */
} ne_conn_status;
#endif
int bufAlloced; /*!< sizeof I/O buffer */
/*@owned@*/
char * buf; /*!< I/O buffer */

View File

@ -12,13 +12,13 @@
static int _fts_debug = 0;
#if 1
#define HTTPPATH "https://wellfleet.jbj.org/rawhide/test/"
#define HTTPSPATH "https://wellfleet.jbj.org/rawhide/test/"
#else
#define HTTPPATH "https://wellfleet.jbj.org/rawhide/"
#define HTTPSPATH "https://wellfleet.jbj.org/rawhide/"
#endif
#define FTPPATH "ftp://wellfleet.jbj.org/pub/rawhide/packages/test"
#define DIRPATH "/var/ftp/pub/rawhide/packages/test"
static char * httppath = HTTPPATH;
static char * httpspath = HTTPSPATH;
static char * ftppath = FTPPATH;
static char * dirpath = DIRPATH;
@ -166,7 +166,7 @@ _dav_debug = -1;
#if 0
ftsWalk(ftppath);
#endif
ftsWalk(httppath);
ftsWalk(httpspath);
/*@i@*/ urlFreeCache();

View File

@ -18,7 +18,7 @@ static char * httppath = HTTPPATH;
static char * ftppath = FTPPATH;
static char * dirpath = DIRPATH;
static void printFile(const char * path)
static void readFile(const char * path)
{
FD_t fd;
@ -27,11 +27,10 @@ fprintf(stderr, "===== %s\n", path);
if (fd != NULL) {
char buf[BUFSIZ];
size_t len = Fread(buf, 1, sizeof(buf), fd);
int xx;
int xx = Fclose(fd);
if (len > 0)
fwrite(buf, 1, len, stderr);
xx = Fclose(fd);
}
}
@ -73,11 +72,12 @@ _av_debug = -1;
_ftp_debug = -1;
_dav_debug = -1;
#if 0
printFile(dirpath);
printFile(ftppath);
readFile(dirpath);
readFile(ftppath);
readFile(httppath);
#endif
printFile(httppath);
printFile(httpspath);
readFile(httpspath);
readFile(httpspath);
/*@i@*/ urlFreeCache();

View File

@ -143,6 +143,11 @@ URLDBGREFS(0, (stderr, "--> url %p -- %d %s at %s:%u\n", u, u->nrefs, msg, file,
(u->scheme ? u->scheme : ""));
/*@=usereleased@*/
}
if (u->sess != NULL) {
/* HACK: neon include has prototype. */
ne_session_destroy(u->sess);
u->sess = NULL;
}
u->buf = _free(u->buf);
u->url = _free(u->url);
u->scheme = _free((void *)u->scheme);