This diff is mostly cleanup and adding the missing bits needed for RRDP.
Instead of a simple bool ok use an enum to report the state back.
Can be fail, ok or not-modified (the last is used for 304 Not Modified
answers (if a  If-Modified-Since header was passed in the request).

Additionally add 308 redirect support and remove 206 as a valid status
response. The http client does not do range requests so a 206 return is
never expected.

-- 
:wq Claudio

Index: extern.h
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
retrieving revision 1.55
diff -u -p -r1.55 extern.h
--- extern.h    19 Mar 2021 13:56:10 -0000      1.55
+++ extern.h    25 Mar 2021 09:10:04 -0000
@@ -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: http.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/http.c,v
retrieving revision 1.8
diff -u -p -r1.8 http.c
--- http.c      18 Mar 2021 16:15:19 -0000      1.8
+++ http.c      25 Mar 2021 09:12:18 -0000
@@ -264,7 +264,7 @@ http_resolv(struct http_connection *conn
 }
 
 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, 
        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 *co
 {
        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
        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
                }
                /* 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_connectio
        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 *co
                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: main.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/main.c,v
retrieving revision 1.122
diff -u -p -r1.122 main.c
--- main.c      19 Mar 2021 13:56:10 -0000      1.122
+++ main.c      25 Mar 2021 09:15:22 -0000
@@ -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);
                }
 
                /*

Reply via email to