| 316 | } |
| 317 | |
| 318 | static int add_push(link_ctx *ctx) |
| 319 | { |
| 320 | /* so, we have read a Link header and need to decide |
| 321 | * if we transform it into a push. |
| 322 | */ |
| 323 | if (has_relation(ctx, "preload") && !has_param(ctx, "nopush")) { |
| 324 | apr_uri_t uri; |
| 325 | if (apr_uri_parse(ctx->pool, ctx->link, &uri) == APR_SUCCESS) { |
| 326 | if (uri.path && same_authority(ctx->req, &uri)) { |
| 327 | char *path; |
| 328 | const char *method; |
| 329 | apr_table_t *headers; |
| 330 | h2_request *req; |
| 331 | h2_push *push; |
| 332 | |
| 333 | /* We only want to generate pushes for resources in the |
| 334 | * same authority than the original request. |
| 335 | * icing: i think that is wise, otherwise we really need to |
| 336 | * check that the vhost/server is available and uses the same |
| 337 | * TLS (if any) parameters. |
| 338 | */ |
| 339 | path = apr_uri_unparse(ctx->pool, &uri, APR_URI_UNP_OMITSITEPART); |
| 340 | push = apr_pcalloc(ctx->pool, sizeof(*push)); |
| 341 | switch (ctx->push_policy) { |
| 342 | case H2_PUSH_HEAD: |
| 343 | method = "HEAD"; |
| 344 | break; |
| 345 | default: |
| 346 | method = "GET"; |
| 347 | break; |
| 348 | } |
| 349 | headers = apr_table_make(ctx->pool, 5); |
| 350 | apr_table_do(set_push_header, headers, ctx->req->headers, NULL); |
| 351 | req = h2_request_create(0, ctx->pool, method, ctx->req->scheme, |
| 352 | ctx->req->authority, path, headers); |
| 353 | /* atm, we do not push on pushes */ |
| 354 | h2_request_end_headers(req, ctx->pool, 0); |
| 355 | push->req = req; |
| 356 | if (has_param(ctx, "critical")) { |
| 357 | h2_priority *prio = apr_pcalloc(ctx->pool, sizeof(*prio)); |
| 358 | prio->dependency = H2_DEPENDANT_BEFORE; |
| 359 | push->priority = prio; |
| 360 | } |
| 361 | if (!ctx->pushes) { |
| 362 | ctx->pushes = apr_array_make(ctx->pool, 5, sizeof(h2_push*)); |
| 363 | } |
| 364 | APR_ARRAY_PUSH(ctx->pushes, h2_push*) = push; |
| 365 | } |
| 366 | } |
| 367 | } |
| 368 | return 0; |
| 369 | } |
| 370 | |
| 371 | static void inspect_link(link_ctx *ctx, const char *s, size_t slen) |
| 372 | { |
no test coverage detected