| 486 | } |
| 487 | |
| 488 | AP_DECLARE(ap_condition_e) ap_condition_if_range(request_rec *r, |
| 489 | apr_table_t *headers) |
| 490 | { |
| 491 | const char *if_range, *etag; |
| 492 | |
| 493 | if ((if_range = apr_table_get(r->headers_in, "If-Range")) |
| 494 | && apr_table_get(r->headers_in, "Range")) { |
| 495 | if (if_range[0] == '"') { |
| 496 | |
| 497 | if ((etag = apr_table_get(headers, "ETag")) |
| 498 | && !strcmp(if_range, etag)) { |
| 499 | return AP_CONDITION_STRONG; |
| 500 | } |
| 501 | else { |
| 502 | return AP_CONDITION_NOMATCH; |
| 503 | } |
| 504 | |
| 505 | } |
| 506 | else { |
| 507 | apr_int64_t mtime; |
| 508 | apr_int64_t rtime, reqtime; |
| 509 | |
| 510 | /* All of our comparisons must be in seconds, because that's the |
| 511 | * highest time resolution the HTTP specification allows. |
| 512 | */ |
| 513 | |
| 514 | mtime = apr_time_sec(apr_date_parse_http( |
| 515 | apr_table_get(headers, "Last-Modified"))); |
| 516 | if (mtime == APR_DATE_BAD) { |
| 517 | mtime = apr_time_sec(r->mtime ? r->mtime : apr_time_now()); |
| 518 | } |
| 519 | |
| 520 | reqtime = apr_time_sec(apr_date_parse_http( |
| 521 | apr_table_get(headers, "Date"))); |
| 522 | if (!reqtime) { |
| 523 | reqtime = apr_time_sec(r->request_time); |
| 524 | } |
| 525 | |
| 526 | rtime = apr_time_sec(apr_date_parse_http(if_range)); |
| 527 | |
| 528 | if (rtime == mtime) { |
| 529 | if (reqtime < mtime + 60) { |
| 530 | /* weak matches not allowed with Range requests */ |
| 531 | return AP_CONDITION_NOMATCH; |
| 532 | } |
| 533 | else { |
| 534 | return AP_CONDITION_STRONG; |
| 535 | } |
| 536 | } |
| 537 | else { |
| 538 | return AP_CONDITION_NOMATCH; |
| 539 | } |
| 540 | } |
| 541 | } |
| 542 | |
| 543 | return AP_CONDITION_NONE; |
| 544 | } |
| 545 |
no outgoing calls
no test coverage detected