On Wed, Aug 04, 2021 at 10:53:39AM +0200, Claudio Jeker wrote:
> This adds a few more HTTP Status codes to the mix of the accepted ones.
> Mainly 100, 103 and 203 are now also accepted. All other codes in the 1xx
> and 2xx are still considered an error since they are not expected from the
> GET request made by the http client. This is a minimal HTTP client and it
> should remain minimal. If a server is sending back something unexpected
> just fail and fall back to rsync.


Update with additional comments for the various status codes.

-- 
:wq Claudio

Index: http.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/http.c,v
retrieving revision 1.34
diff -u -p -r1.34 http.c
--- http.c      23 Jul 2021 16:03:47 -0000      1.34
+++ http.c      4 Aug 2021 15:22:22 -0000
@@ -865,7 +865,9 @@ http_request(struct http_connection *con
 
 /*
  * Parse the HTTP status line.
- * Return 0 for status codes 200, 301-304, 307-308.
+ * Return 0 for status codes 100, 103, 200, 203, 301-304, 307-308.
+ * The other 1xx and 2xx status codes are explicitly not handled and are
+ * considered an error.
  * Failure codes and other errors return -1.
  * The redirect loop limit is enforced here.
  */
@@ -885,7 +887,7 @@ http_parse_status(struct http_connection
                cp++;
 
        strlcpy(ststr, cp, sizeof(ststr));
-       status = strtonum(ststr, 200, 599, &errstr);
+       status = strtonum(ststr, 100, 599, &errstr);
        if (errstr != NULL) {
                strnvis(gerror, cp, sizeof gerror, VIS_SAFE);
                warnx("Error retrieving %s: %s", http_info(conn->host),
@@ -894,19 +896,23 @@ http_parse_status(struct http_connection
        }
 
        switch (status) {
-       case 301:
-       case 302:
-       case 303:
-       case 307:
-       case 308:
+       case 301:       /* Redirect: moved permanently */
+       case 302:       /* Redirect: found / moved temporarily */
+       case 303:       /* Redirect: see other */
+       case 307:       /* Redirect: temporary redirect */
+       case 308:       /* Redirect: permanent redirect */
                if (conn->req->redirect_loop++ > 10) {
                        warnx("%s: Too many redirections requested",
                            http_info(conn->host));
                        return -1;
                }
                /* FALLTHROUGH */
-       case 200:
-       case 304:
+       case 100:       /* Informational: continue (ignored) */
+       case 103:       /* Informational: early hints (ignored) */
+               /* FALLTHROUGH */
+       case 200:       /* Success: OK */
+       case 203:       /* Success: non-authoritative information (proxy) */
+       case 304:       /* Redirect: not modified */
                conn->status = status;
                break;
        default:
@@ -931,6 +937,14 @@ http_isredirect(struct http_connection *
        return 0;
 }
 
+static inline int
+http_isok(struct http_connection *conn)
+{
+       if (conn->status >= 200 && conn->status < 300)
+               return 1;
+       return 0;
+}
+
 static void
 http_redirect(struct http_connection *conn)
 {
@@ -1165,7 +1179,7 @@ again:
                }
 
                /* Check status header and decide what to do next */
-               if (conn->status == 200 || http_isredirect(conn)) {
+               if (http_isok(conn) || http_isredirect(conn)) {
                        if (http_isredirect(conn))
                                http_redirect(conn);
 
@@ -1174,6 +1188,8 @@ again:
                        else
                                conn->state = STATE_RESPONSE_DATA;
                        goto again;
+               } else if (conn->status == 100 || conn->status == 103) {
+                       conn->state = STATE_RESPONSE_STATUS;
                } else if (conn->status == 304) {
                        return http_done(conn, HTTP_NOT_MOD);
                }

Reply via email to