Adjust HTTP client code a bit. Add support for 304 Not Modified responses,
authorclaudio <claudio@openbsd.org>
Thu, 25 Mar 2021 12:18:45 +0000 (12:18 +0000)
committerclaudio <claudio@openbsd.org>
Thu, 25 Mar 2021 12:18:45 +0000 (12:18 +0000)
remove handling of 206 Partial Content (the client does not use range
headers). Report the Last-Modified timestamp back to the requestor and
switch OK to a enum value for (FAIL, OK and NOT MODIFIED).
OK tb@

usr.sbin/rpki-client/extern.h
usr.sbin/rpki-client/http.c
usr.sbin/rpki-client/main.c

index 0fa14e1..03f6d89 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: extern.h,v 1.55 2021/03/19 13:56:10 claudio Exp $ */
+/*     $OpenBSD: extern.h,v 1.56 2021/03/25 12:18:45 claudio Exp $ */
 /*
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -264,6 +264,12 @@ enum rtype {
        RTYPE_GBR,
 };
 
+enum http_result {
+       HTTP_FAILED,    /* anything else */
+       HTTP_OK,        /* 200 OK */
+       HTTP_NOT_MOD,   /* 304 Not Modified */
+};
+
 /*
  * An entity (MFT, ROA, certificate, etc.) that needs to be downloaded
  * and parsed.
index 84c11fa..8f49b74 100644 (file)
@@ -1,4 +1,4 @@
-/*      $OpenBSD: http.c,v 1.8 2021/03/18 16:15:19 tb Exp $  */
+/*      $OpenBSD: http.c,v 1.9 2021/03/25 12:18:45 claudio Exp $  */
 /*
  * Copyright (c) 2020 Nils Fisher <nils_fisher@hotmail.com>
  * Copyright (c) 2020 Claudio Jeker <claudio@openbsd.com>
@@ -264,7 +264,7 @@ http_resolv(struct http_connection *conn, const char *host, const char *port)
 }
 
 static void
-http_done(struct http_connection *conn, int ok)
+http_done(struct http_connection *conn, enum http_result res)
 {
        struct ibuf *b;
 
@@ -273,10 +273,8 @@ http_done(struct http_connection *conn, int ok)
        if ((b = ibuf_dynamic(64, UINT_MAX)) == NULL)
                err(1, NULL);
        io_simple_buffer(b, &conn->id, sizeof(conn->id));
-       io_simple_buffer(b, &ok, sizeof(ok));
-#if 0  /* TODO: cache last_modified */
+       io_simple_buffer(b, &res, sizeof(res));
        io_str_buffer(b, conn->last_modified);
-#endif
        ibuf_close(&msgq, b);
 }
 
@@ -284,12 +282,13 @@ static void
 http_fail(size_t id)
 {
        struct ibuf *b;
-       int ok = 0;
+       enum http_result res = HTTP_FAILED;
 
        if ((b = ibuf_dynamic(8, UINT_MAX)) == NULL)
                err(1, NULL);
        io_simple_buffer(b, &id, sizeof(id));
-       io_simple_buffer(b, &ok, sizeof(ok));
+       io_simple_buffer(b, &res, sizeof(res));
+       io_str_buffer(b, NULL);
        ibuf_close(&msgq, b);
 }
 
@@ -434,7 +433,7 @@ http_redirect(struct http_connection *conn, char *uri)
 {
        char *host, *port, *path;
 
-       warnx("redirect to %s", http_info(uri));
+       logx("redirect to %s", http_info(uri));
 
        if (http_parse_uri(uri, &host, &port, &path) == -1) {
                free(uri);
@@ -705,6 +704,7 @@ http_parse_status(struct http_connection *conn, char *buf)
        case 302:
        case 303:
        case 307:
+       case 308:
                if (conn->redirect_loop++ > 10) {
                        warnx("%s: Too many redirections requested",
                            http_info(conn->url));
@@ -712,7 +712,6 @@ http_parse_status(struct http_connection *conn, char *buf)
                }
                /* FALLTHROUGH */
        case 200:
-       case 206:
        case 304:
                conn->status = status;
                break;
@@ -729,7 +728,7 @@ static inline int
 http_isredirect(struct http_connection *conn)
 {
        if ((conn->status >= 301 && conn->status <= 303) ||
-           conn->status == 307)
+           conn->status == 307 || conn->status == 308)
                return 1;
        return 0;
 }
@@ -865,7 +864,7 @@ http_parse_chunked(struct http_connection *conn, char *buf)
        conn->chunksz = chunksize;
 
        if (conn->chunksz == 0) {
-               http_done(conn, 1);
+               http_done(conn, HTTP_OK);
                return 0;
        }
 
@@ -970,7 +969,7 @@ data_write(struct http_connection *conn)
        memmove(conn->buf, conn->buf + s, conn->bufpos);
 
        if (conn->bytes == conn->filesize) {
-               http_done(conn, 1);
+               http_done(conn, HTTP_OK);
                return 0;
        }
 
@@ -1065,10 +1064,13 @@ http_nextstep(struct http_connection *conn)
                conn->state = STATE_RESPONSE_HEADER;
                return WANT_POLLIN;
        case STATE_RESPONSE_HEADER:
-               if (conn->status == 200)
+               if (conn->status == 200) {
                        conn->state = STATE_RESPONSE_DATA;
-               else {
-                       http_done(conn, 0);
+               } else {
+                       if (conn->status == 304)
+                               http_done(conn, HTTP_NOT_MOD);
+                       else
+                               http_done(conn, HTTP_FAILED);
                        return http_close(conn);
                }
                return WANT_POLLIN;
index e922b7f..70b7c65 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: main.c,v 1.122 2021/03/19 13:56:10 claudio Exp $ */
+/*     $OpenBSD: main.c,v 1.123 2021/03/25 12:18:45 claudio Exp $ */
 /*
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -321,11 +321,11 @@ http_ta_fetch(struct repo *rp)
 }
 
 static int
-http_done(struct repo *rp, int ok)
+http_done(struct repo *rp, enum http_result res)
 {
        if (rp->repouri == NULL) {
                /* Move downloaded TA file into place, or unlink on failure. */
-               if (ok) {
+               if (res == HTTP_OK) {
                        char *file;
 
                        file = ta_filename(rp, 0);
@@ -339,18 +339,16 @@ http_done(struct repo *rp, int ok)
                rp->temp = NULL;
        }
 
-       if (!ok && rp->uriidx < REPO_MAX_URI - 1 &&
+       if (res == HTTP_OK)
+               logx("%s: loaded from network", rp->local);
+       else if (rp->uriidx < REPO_MAX_URI - 1 &&
            rp->uris[rp->uriidx + 1] != NULL) {
                logx("%s: load from network failed, retry", rp->local);
 
                rp->uriidx++;
                repo_fetch(rp);
                return 0;
-       }
-
-       if (ok)
-               logx("%s: loaded from network", rp->local);
-       else
+       } else
                logx("%s: load from network failed, "
                    "fallback to cache", rp->local);
 
@@ -842,7 +840,7 @@ suicide(int sig __attribute__((unused)))
 int
 main(int argc, char *argv[])
 {
-       int              rc = 1, c, st, proc, rsync, http,
+       int              rc = 1, c, st, proc, rsync, http, ok,
                         fl = SOCK_STREAM | SOCK_CLOEXEC;
        size_t           i, id, outsz = 0, talsz = 0;
        pid_t            procpid, rsyncpid, httppid;
@@ -1157,7 +1155,6 @@ main(int argc, char *argv[])
                 */
 
                if ((pfd[0].revents & POLLIN)) {
-                       int ok;
                        io_simple_read(rsync, &id, sizeof(id));
                        io_simple_read(rsync, &ok, sizeof(ok));
                        rp = repo_find(id);
@@ -1176,19 +1173,23 @@ main(int argc, char *argv[])
                }
 
                if ((pfd[2].revents & POLLIN)) {
-                       int ok;
+                       enum http_result res;
+                       char *last_mod;
+
                        io_simple_read(http, &id, sizeof(id));
-                       io_simple_read(http, &ok, sizeof(ok));
+                       io_simple_read(http, &res, sizeof(res));
+                       io_str_read(http, &last_mod);
                        rp = repo_find(id);
                        if (rp == NULL)
                                errx(1, "unknown repository id: %zu", id);
 
                        assert(!rp->loaded);
-                       if (http_done(rp, ok)) {
+                       if (http_done(rp, res)) {
                                rp->loaded = 1;
                                stats.repos++;
                                entityq_flush(rp);
                        }
+                       free(last_mod);
                }
 
                /*