On Wed, Sep 07, 2022 at 03:56:31PM +0200, Claudio Jeker wrote:
> The HTTP RFC defines a header as:
> message-header = field-name ":" [ field-value ]
> field-name = token
> field-value = *( field-content | LWS )
>
> The field-content does not include any leading or trailing LWS:
> linear white space occurring before the first non-whitespace
> character of the field-value or after the last non-whitespace
> character of the field-value. Such leading or trailing LWS MAY be
> removed without changing the semantics of the field value.
>
> Plus there is this as well:
> The field value MAY be preceded by any amount of LWS, though a single
> SP is preferred.
>
> Now rpki-client's http client does currently require exactly one space
> between the ':' and the field-value. This works in most cases but is
> incorrect and too strict.
>
> The following diff fixes this for rpki-client. Now rpki-client does not
> require any space at all (I assume that no space is also covered by any
> amount of LWS).
>
> Btw. ftp(1) has the same issue and it should be fixed there as well.
ok tb
> --
> :wq Claudio
>
> Index: http.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/http.c,v
> retrieving revision 1.65
> diff -u -p -r1.65 http.c
> --- http.c 30 Aug 2022 14:33:26 -0000 1.65
> +++ http.c 7 Sep 2022 13:21:08 -0000
> @@ -1164,11 +1164,11 @@ http_redirect(struct http_connection *co
> static int
> http_parse_header(struct http_connection *conn, char *buf)
> {
> -#define CONTENTLEN "Content-Length: "
> -#define LOCATION "Location: "
> -#define CONNECTION "Connection: "
> -#define TRANSFER_ENCODING "Transfer-Encoding: "
> -#define LAST_MODIFIED "Last-Modified: "
> +#define CONTENTLEN "Content-Length:"
> +#define LOCATION "Location:"
> +#define CONNECTION "Connection:"
> +#define TRANSFER_ENCODING "Transfer-Encoding:"
> +#define LAST_MODIFIED "Last-Modified:"
> const char *errstr;
> char *cp, *redirurl;
> char *locbase, *loctail;
> @@ -1178,10 +1178,9 @@ http_parse_header(struct http_connection
> if (*cp == '\0')
> return 0;
> else if (strncasecmp(cp, CONTENTLEN, sizeof(CONTENTLEN) - 1) == 0) {
> - size_t s;
> cp += sizeof(CONTENTLEN) - 1;
> - if ((s = strcspn(cp, " \t")) != 0)
> - *(cp + s) = 0;
> + cp += strspn(cp, " \t");
> + cp[strcspn(cp, " \t")] = '\0';
> conn->iosz = strtonum(cp, 0, MAX_CONTENTLEN, &errstr);
> if (errstr != NULL) {
> warnx("Content-Length of %s is %s",
> @@ -1191,6 +1190,7 @@ http_parse_header(struct http_connection
> } else if (http_isredirect(conn) &&
> strncasecmp(cp, LOCATION, sizeof(LOCATION) - 1) == 0) {
> cp += sizeof(LOCATION) - 1;
> + cp += strspn(cp, " \t");
> /*
> * If there is a colon before the first slash, this URI
> * is not relative. RFC 3986 4.2
> @@ -1232,11 +1232,13 @@ http_parse_header(struct http_connection
> } else if (strncasecmp(cp, TRANSFER_ENCODING,
> sizeof(TRANSFER_ENCODING) - 1) == 0) {
> cp += sizeof(TRANSFER_ENCODING) - 1;
> + cp += strspn(cp, " \t");
> cp[strcspn(cp, " \t")] = '\0';
> if (strcasecmp(cp, "chunked") == 0)
> conn->chunked = 1;
> } else if (strncasecmp(cp, CONNECTION, sizeof(CONNECTION) - 1) == 0) {
> cp += sizeof(CONNECTION) - 1;
> + cp += strspn(cp, " \t");
> cp[strcspn(cp, " \t")] = '\0';
> if (strcasecmp(cp, "close") == 0)
> conn->keep_alive = 0;
> @@ -1245,6 +1247,7 @@ http_parse_header(struct http_connection
> } else if (strncasecmp(cp, LAST_MODIFIED,
> sizeof(LAST_MODIFIED) - 1) == 0) {
> cp += sizeof(LAST_MODIFIED) - 1;
> + cp += strspn(cp, " \t");
> free(conn->last_modified);
> if ((conn->last_modified = strdup(cp)) == NULL)
> err(1, NULL);
>