| 369 | } |
| 370 | |
| 371 | static void inspect_link(link_ctx *ctx, const char *s, size_t slen) |
| 372 | { |
| 373 | /* RFC 5988 <https://tools.ietf.org/html/rfc5988#section-6.2.1> |
| 374 | Link = "Link" ":" #link-value |
| 375 | link-value = "<" URI-Reference ">" *( ";" link-param ) |
| 376 | link-param = ( ( "rel" "=" relation-types ) |
| 377 | | ( "anchor" "=" <"> URI-Reference <"> ) |
| 378 | | ( "rev" "=" relation-types ) |
| 379 | | ( "hreflang" "=" Language-Tag ) |
| 380 | | ( "media" "=" ( MediaDesc | ( <"> MediaDesc <"> ) ) ) |
| 381 | | ( "title" "=" quoted-string ) |
| 382 | | ( "title*" "=" ext-value ) |
| 383 | | ( "type" "=" ( media-type | quoted-mt ) ) |
| 384 | | ( link-extension ) ) |
| 385 | link-extension = ( parmname [ "=" ( ptoken | quoted-string ) ] ) |
| 386 | | ( ext-name-star "=" ext-value ) |
| 387 | ext-name-star = parmname "*" ; reserved for RFC2231-profiled |
| 388 | ; extensions. Whitespace NOT |
| 389 | ; allowed in between. |
| 390 | ptoken = 1*ptokenchar |
| 391 | ptokenchar = "!" | "#" | "$" | "%" | "&" | "'" | "(" |
| 392 | | ")" | "*" | "+" | "-" | "." | "/" | DIGIT |
| 393 | | ":" | "<" | "=" | ">" | "?" | "@" | ALPHA |
| 394 | | "[" | "]" | "^" | "_" | "`" | "{" | "|" |
| 395 | | "}" | "~" |
| 396 | media-type = type-name "/" subtype-name |
| 397 | quoted-mt = <"> media-type <"> |
| 398 | relation-types = relation-type |
| 399 | | <"> relation-type *( 1*SP relation-type ) <"> |
| 400 | relation-type = reg-rel-type | ext-rel-type |
| 401 | reg-rel-type = LOALPHA *( LOALPHA | DIGIT | "." | "-" ) |
| 402 | ext-rel-type = URI |
| 403 | |
| 404 | and from <https://tools.ietf.org/html/rfc5987> |
| 405 | parmname = 1*attr-char |
| 406 | attr-char = ALPHA / DIGIT |
| 407 | / "!" / "#" / "$" / "&" / "+" / "-" / "." |
| 408 | / "^" / "_" / "`" / "|" / "~" |
| 409 | */ |
| 410 | |
| 411 | ctx->s = s; |
| 412 | ctx->slen = slen; |
| 413 | ctx->i = 0; |
| 414 | |
| 415 | while (read_link(ctx)) { |
| 416 | init_params(ctx); |
| 417 | while (read_param(ctx)) { |
| 418 | /* nop */ |
| 419 | } |
| 420 | add_push(ctx); |
| 421 | if (!read_sep(ctx)) { |
| 422 | break; |
| 423 | } |
| 424 | } |
| 425 | } |
| 426 | |
| 427 | static int head_iter(void *ctx, const char *key, const char *value) |
| 428 | { |
no test coverage detected