summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjbj <devnull@localhost>2004-11-11 00:13:38 +0000
committerjbj <devnull@localhost>2004-11-11 00:13:38 +0000
commit103a5c0e4860837984060eeb2c3d6f366993d03d (patch)
treecf25c9063dd42035999f30ac671e5311214b8546
parent910c42099e33c725937ec9c78460aa8bafb0ccd0 (diff)
downloadlibrpm-tizen-103a5c0e4860837984060eeb2c3d6f366993d03d.tar.gz
librpm-tizen-103a5c0e4860837984060eeb2c3d6f366993d03d.tar.bz2
librpm-tizen-103a5c0e4860837984060eeb2c3d6f366993d03d.zip
Wire HTTP PUT through libneon.
CVS patchset: 7570 CVS date: 2004/11/11 00:13:38
-rw-r--r--rpmio/rpmdav.c197
-rw-r--r--rpmio/rpmio.c78
2 files changed, 170 insertions, 105 deletions
diff --git a/rpmio/rpmdav.c b/rpmio/rpmdav.c
index f91b54458..f53229b2c 100644
--- a/rpmio/rpmdav.c
+++ b/rpmio/rpmdav.c
@@ -14,6 +14,13 @@
#include <neon/ne_basic.h>
#include <neon/ne_dates.h>
#include <neon/ne_locks.h>
+
+#define NEONBLOWSCHUNKS
+#ifndef NEONBLOWSCHUNKS
+/* HACK: include ne_private.h to access sess->socket for now. */
+#include "../neon/src/ne_private.h"
+#endif
+
#include <neon/ne_props.h>
#include <neon/ne_request.h>
#include <neon/ne_socket.h>
@@ -33,7 +40,11 @@
/*@access FD_t @*/
/*@access urlinfo @*/
+#if 0 /* HACK: reasonable value needed. */
#define TIMEOUT_SECS 60
+#else
+#define TIMEOUT_SECS 5
+#endif
/*@unchecked@*/
static int httpTimeoutSecs = TIMEOUT_SECS;
@@ -247,12 +258,50 @@ fprintf(stderr, "*** davVerifyCert(%p,%d,%p) %s\n", userdata, failures, cert, ho
return 0; /* HACK: trust all server certificates. */
}
+static int davConnect(urlinfo u)
+ /*@globals internalState @*/
+ /*@modifies u, internalState @*/
+{
+ const char * path = NULL;
+ int rc;
+
+ /* 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:
+ break;
+ case NE_ERROR:
+ /* HACK: "301 Moved Permanently" on empty subdir. */
+ if (!strncmp("301 ", ne_get_error(u->sess), sizeof("301 ")-1))
+ break;
+ /*@fallthrough@*/
+ case NE_CONNECT:
+ case NE_LOOKUP:
+ default:
+if (_dav_debug)
+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;
+}
+
static int davInit(const char * url, urlinfo * uret)
/*@globals internalState @*/
/*@modifies *uret, internalState @*/
{
urlinfo u = NULL;
- int xx;
+ int rc = 0;
/*@-globs@*/ /* FIX: h_errno annoyance. */
if (urlSplit(url, &u))
@@ -266,10 +315,10 @@ static int davInit(const char * url, urlinfo * uret)
/* HACK: oneshots should be done Somewhere Else Instead. */
/*@-noeffect@*/
- xx = ((_dav_debug < 0) ? NE_DBG_HTTP : 0);
- ne_debug_init(stderr, xx); /* XXX oneshot? */
+ rc = ((_dav_debug < 0) ? NE_DBG_HTTP : 0);
+ ne_debug_init(stderr, rc); /* XXX oneshot? */
/*@=noeffect@*/
- xx = ne_sock_init(); /* XXX oneshot? */
+ rc = ne_sock_init(); /* XXX oneshot? */
u->capabilities = capabilities = xcalloc(1, sizeof(*capabilities));
u->sess = ne_session_create(u->scheme, u->host, u->port);
@@ -306,52 +355,21 @@ static int davInit(const char * url, urlinfo * uret)
ne_hook_pre_send(u->sess, davPreSend, u);
ne_hook_post_send(u->sess, davPostSend, u);
ne_hook_destroy_request(u->sess, davDestroyRequest, u);
+
+ /* HACK: where should server capabilities be read? */
+ rc = davConnect(u);
+ if (rc)
+ goto exit;
+
}
+exit:
/*@-boundswrite@*/
- if (uret != NULL)
+ if (rc == 0 && uret != NULL)
*uret = urlLink(u, __FUNCTION__);
/*@=boundswrite@*/
u = urlFree(u, "urlSplit (davInit)");
- return 0;
-}
-
-static int davConnect(urlinfo u)
- /*@globals internalState @*/
- /*@modifies u, internalState @*/
-{
- const char * path = NULL;
- int rc;
-
- /* 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:
- break;
- case NE_ERROR:
- /* HACK: "301 Moved Permanently" on empty subdir. */
- if (!strncmp("301 ", ne_get_error(u->sess), sizeof("301 ")-1))
- break;
- /*@fallthrough@*/
- case NE_CONNECT:
- case NE_LOOKUP:
- default:
-if (_dav_debug)
-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;
}
@@ -749,11 +767,6 @@ static int davNLST(struct fetch_context_s * ctx)
if (rc || u == NULL)
goto exit;
- /* HACK: where should server capabilities be read? */
- rc = davConnect(u);
- if (rc)
- goto exit;
-
rc = davFetch(u, ctx);
switch (rc) {
case NE_OK:
@@ -816,8 +829,8 @@ static int my_result(const char * msg, int ret, /*@null@*/ FILE * fp)
return ret;
}
-#ifdef DYING
-static void hexdump(unsigned char * buf, ssize_t len)
+#ifndef DYING
+static void hexdump(const unsigned char * buf, ssize_t len)
/*@*/
{
int i;
@@ -882,10 +895,12 @@ int davResp(urlinfo u, FD_t ctrl, /*@unused@*/ char *const * str)
rc = ne_begin_request(ctrl->req);
rc = my_result("ne_begin_req(ctrl->req)", rc, NULL);
+
if (_dav_debug < 0)
fprintf(stderr, "*** davResp(%p,%p,%p) sess %p req %p rc %d\n", u, ctrl, str, u->sess, ctrl->req, rc);
/* HACK: stupid error impedence matching. */
+ /* HACK: NE_TIMEOUT et al here does not unravel refcnt correctly. */
switch (rc) {
case NE_OK: rc = 0; break;
case NE_ERROR: rc = FTPERR_SERVER_IO_ERROR; break;
@@ -912,7 +927,7 @@ fprintf(stderr, "*** davResp(%p,%p,%p) sess %p req %p rc %d\n", u, ctrl, str, u-
int davReq(FD_t ctrl, const char * httpCmd, const char * httpArg)
{
urlinfo u;
- int rc;
+ int rc = 0;
assert(ctrl != NULL);
u = ctrl->url;
@@ -921,23 +936,6 @@ assert(ctrl != NULL);
if (_dav_debug < 0)
fprintf(stderr, "*** davReq(%p,%s,\"%s\") entry sess %p req %p\n", ctrl, httpCmd, (httpArg ? httpArg : ""), u->sess, ctrl->req);
- /* HACK: handle proxy host and port here. */
-#ifdef REFERENCE
- if (((host = (u->proxyh ? u->proxyh : u->host)) == NULL))
- return FTPERR_BAD_HOSTNAME;
-
- if ((port = (u->proxyp > 0 ? u->proxyp : u->port)) < 0) port = 80;
- path = (u->proxyh || u->proxyp > 0) ? u->url : httpArg;
-
-/*@-branchstate@*/
- if (path == NULL) path = "";
-/*@=branchstate@*/
-#endif
-
- /* 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)");
@@ -952,22 +950,30 @@ assert(ctrl->req != NULL);
ne_add_response_header_catcher(ctrl->req, davAllHeaders, ctrl);
- ne_add_response_header_handler(ctrl->req, "Accept-Ranges",
- davAcceptRanges, u);
ne_add_response_header_handler(ctrl->req, "Content-Length",
davContentLength, ctrl);
ne_add_response_header_handler(ctrl->req, "Connection",
davConnection, ctrl);
-#ifdef NOTYET
-if (_ftp_debug)
-fprintf(stderr, "-> %s", req);
-#endif
-
- /* HACK: other errors may need retry too. */
- do {
+ if (!strcmp(httpCmd, "PUT")) {
+ ctrl->wr_chunked = 1;
+ ne_add_request_header(ctrl->req, "Transfer-Encoding", "chunked");
+ ne_set_request_chunked(ctrl->req, 1);
+ /* HACK: no retries if/when chunking. */
rc = davResp(u, ctrl, NULL);
- } while (rc == NE_RETRY);
+ } else {
+ /* HACK: possible Last-Modified: Tue, 02 Nov 2004 14:29:36 GMT */
+ /* HACK: possible ETag: "inode-size-mtime" */
+ ne_add_response_header_handler(ctrl->req, "Accept-Ranges",
+ davAcceptRanges, u);
+ /* HACK: possible Transfer-Encoding: on GET. */
+
+ /* HACK: other errors may need retry too. */
+ /* HACK: neon retries once, gud enuf. */
+ do {
+ rc = davResp(u, ctrl, NULL);
+ } while (rc == NE_RETRY);
+ }
if (rc)
goto errxit;
@@ -1059,14 +1065,33 @@ hexdump(buf, rc);
ssize_t davWrite(void * cookie, const char * buf, size_t count)
{
-#ifdef NOTYET
FD_t fd = cookie;
- return ne_read_response_block(fd->req, buf, count);
+ ssize_t rc;
+ int xx;
+
+#ifndef NEONBLOWSCHUNKS
+ ne_session * sess;
+
+assert(fd->req != NULL);
+ sess = ne_get_session(fd->req);
+assert(sess != NULL);
+
+ /* HACK: include ne_private.h to access sess->socket for now. */
+ xx = ne_sock_fullwrite(sess->socket, buf, count);
#else
-if (_dav_debug < 0)
-fprintf(stderr, "*** davWrite(%p,%p,0x%x)\n", cookie, buf, count);
- return -1;
+assert(fd->req != NULL);
+ xx = ne_send_request_chunk(fd->req, buf, count);
#endif
+
+ /* HACK: stupid error impedence matching. */
+ rc = (xx == 0 ? count : -1);
+
+if (_dav_debug < 0)
+fprintf(stderr, "*** davWrite(%p,%p,0x%x) rc 0x%x\n", cookie, buf, count, rc);
+if (count > 0)
+hexdump(buf, count);
+
+ return rc;
}
int davSeek(void * cookie, /*@unused@*/ _libio_pos_t pos, int whence)
@@ -1105,7 +1130,6 @@ int davMkdir(const char * path, mode_t mode)
int rc;
rc = davInit(path, &u);
-assert(u != NULL);
if (rc)
goto exit;
@@ -1130,7 +1154,6 @@ int davRmdir(const char * path)
int rc;
rc = davInit(path, &u);
-assert(u != NULL);
if (rc)
goto exit;
@@ -1157,7 +1180,6 @@ int davRename(const char * oldpath, const char * newpath)
int rc;
rc = davInit(oldpath, &u);
-assert(u != NULL);
if (rc)
goto exit;
@@ -1183,7 +1205,6 @@ int davUnlink(const char * path)
int rc;
rc = davInit(path, &u);
-assert(u != NULL);
if (rc)
goto exit;
@@ -1193,9 +1214,9 @@ assert(u != NULL);
rc = ne_delete(u->sess, src);
+exit:
if (rc) rc = -1; /* XXX HACK: errno impedance match */
-exit:
if (_dav_debug)
fprintf(stderr, "*** davUnlink(%s) rc %d\n", path, rc);
return rc;
diff --git a/rpmio/rpmio.c b/rpmio/rpmio.c
index 4d05f2f32..39c469896 100644
--- a/rpmio/rpmio.c
+++ b/rpmio/rpmio.c
@@ -398,24 +398,47 @@ static ssize_t fdWrite(void * cookie, const char * buf, size_t count)
if (fd->ndigests && count > 0) fdUpdateDigests(fd, buf, count);
+#define NEONBLOWSCHUNKS
+#ifdef NEONBLOWSCHUNKS
+ if (fd->req == NULL)
+#endif
if (fd->wr_chunked) {
- char chunksize[20];
+ char chunksize[20]; /* HACK: big enough. */
sprintf(chunksize, "%x\r\n", (unsigned)count);
- rc = write(fdno, chunksize, strlen(chunksize));
+#ifndef NEONBLOWSCHUNKS
+ /* HACK: flimsy wiring for davWrite */
+ if (fd->req != NULL)
+ rc = davWrite(fd, chunksize, strlen(chunksize));
+ else
+#endif
+ rc = write(fdno, chunksize, strlen(chunksize));
if (rc == -1) fd->syserrno = errno;
}
if (count == 0) return 0;
fdstat_enter(fd, FDSTAT_WRITE);
/*@-boundsread@*/
- rc = write(fdno, buf, (count > fd->bytesRemain ? fd->bytesRemain : count));
+ /* HACK: flimsy wiring for davWrite */
+ if (fd->req != NULL)
+ rc = davWrite(fd, buf, (count > fd->bytesRemain ? fd->bytesRemain : count));
+ else
+ rc = write(fdno, buf, (count > fd->bytesRemain ? fd->bytesRemain : count));
/*@=boundsread@*/
fdstat_exit(fd, FDSTAT_WRITE, rc);
+#ifdef NEONBLOWSCHUNKS
+ if (fd->req == NULL)
+#endif
if (fd->wr_chunked) {
int ec;
/*@-boundsread@*/
- ec = write(fdno, "\r\n", sizeof("\r\n")-1);
+#ifndef NEONBLOWSCHUNKS
+ /* HACK: flimsy wiring for davWrite */
+ if (fd->req != NULL)
+ ec = davWrite(fd, "\r\n", sizeof("\r\n")-1);
+ else
+#endif
+ ec = write(fdno, "\r\n", sizeof("\r\n")-1);
/*@=boundsread@*/
if (ec == -1) fd->syserrno = errno;
}
@@ -542,6 +565,7 @@ int fdWritable(FD_t fd, int secs)
/*@=compdef =nullpass@*/
#endif
+ /* HACK: EBADF on PUT chunked termination from ufdClose. */
if (_rpmio_debug && !(rc == 1 && errno == 0))
fprintf(stderr, "*** fdWritable fdno %d rc %d %s\n", fdno, rc, strerror(errno));
if (rc < 0) {
@@ -1568,17 +1592,22 @@ static int httpResp(urlinfo u, FD_t ctrl, /*@out@*/ char ** str)
URLSANE(u);
rc = checkResponse(u, ctrl, &ec, str);
-if (_ftp_debug && !(rc == 0 && ec == 200))
+if (_ftp_debug && !(rc == 0 && (ec == 200 || ec == 201)))
fprintf(stderr, "*** httpResp: rc %d ec %d\n", rc, ec);
switch (ec) {
case 200:
+ case 201: /* 201 Created. */
+ break;
+ case 204: /* HACK: if overwriting, 204 No Content. */
+ case 403: /* 403 Forbidden. */
+ ctrl->syserrno = EACCES; /* HACK */
+ rc = FTPERR_UNKNOWN;
break;
default:
rc = FTPERR_FILE_NOT_FOUND;
break;
}
-
return rc;
}
@@ -1935,21 +1964,36 @@ 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. */
- (void) fdWrite(fd, NULL, 0);
- fd->wr_chunked = 0;
- /* XXX HTTP PUT requires terminating entity-header. */
+
+#ifdef NEONBLOWSCHUNKS
+ if (!noNeon) {
+ fd->wr_chunked = 0;
+ /* HACK: flimsy wiring for davWrite */
+ rc = ne_send_request_chunk(fd->req, (void *)NULL, (size_t)0);
+ rc = ne_finish_request(fd->req);
+ rc = davResp(u, fd, NULL);
+ } else
+#endif
+ {
+ /* XXX HTTP PUT requires terminating 0 length chunk. */
+ (void) fdWrite(fd, NULL, 0);
+ fd->wr_chunked = 0;
+ /* XXX HTTP PUT requires terminating entity-header. */
if (_ftp_debug)
fprintf(stderr, "-> \r\n");
- (void) fdWrite(fd, "\r\n", sizeof("\r\n")-1);
- /* HACK: flimsy wiring for davWrite */
- if (!strcmp(u->scheme, "https"))
- rc = davResp(u, fd, NULL);
- else
- rc = httpResp(u, fd, NULL);
+ (void) fdWrite(fd, "\r\n", sizeof("\r\n")-1);
+#ifndef NEONBLOWSCHUNKS
+ if (!noNeon) {
+ rc = ne_finish_request(fd->req);
+ rc = davResp(u, fd, NULL);
+ } else
+#endif
+ rc = httpResp(u, fd, NULL);
+ }
+if ((_ftp_debug || _rpmio_debug) && rc) /* HACK: PUT rc not returned to Fclose. */
+fprintf(stderr, "*** ufdClose: httpResp rc %d errno(%d) %s\n", rc, fd->syserrno, strerror(fd->syserrno));
}
/*