* range entry valid [a,b] (a >= 0 and b >= 0 and a <= b) * HttpTransact::RANGE_NONE if the content length of cached copy is zero or * no range entry * HttpTransact::RANGE_NOT_SATISFIABLE iff all range entries are valid but * none overlap the current extent of the cached copy * HttpTransact::RANGE_NOT_HANDLED if out-of-order Range entries or * the cached copy`s content_length is INT64_MAX (e.
| 4664 | * in order (remove the entries that not overlap the extent of cache copy) |
| 4665 | */ |
| 4666 | void |
| 4667 | HttpSM::parse_range_and_compare(MIMEField *field, int64_t content_length) |
| 4668 | { |
| 4669 | int prev_good_range = -1; |
| 4670 | const char *value; |
| 4671 | int value_len; |
| 4672 | int n_values; |
| 4673 | int nr = 0; // number of valid ranges, also index to range array. |
| 4674 | int not_satisfy = 0; |
| 4675 | HdrCsvIter csv; |
| 4676 | const char *s, *e, *tmp; |
| 4677 | RangeRecord *ranges = nullptr; |
| 4678 | int64_t start, end; |
| 4679 | |
| 4680 | ink_assert(field != nullptr && t_state.range_setup == HttpTransact::RANGE_NONE && t_state.ranges == nullptr); |
| 4681 | |
| 4682 | if (content_length <= 0) { |
| 4683 | return; |
| 4684 | } |
| 4685 | |
| 4686 | // ToDo: Can this really happen? |
| 4687 | if (content_length == INT64_MAX) { |
| 4688 | t_state.range_setup = HttpTransact::RANGE_NOT_HANDLED; |
| 4689 | return; |
| 4690 | } |
| 4691 | |
| 4692 | if (parse_range_done) { |
| 4693 | SMDbg(dbg_ctl_http_range, "parse_range already done, t_state.range_setup %d", t_state.range_setup); |
| 4694 | return; |
| 4695 | } |
| 4696 | parse_range_done = true; |
| 4697 | |
| 4698 | n_values = 0; |
| 4699 | value = csv.get_first(field, &value_len); |
| 4700 | while (value) { |
| 4701 | ++n_values; |
| 4702 | value = csv.get_next(&value_len); |
| 4703 | } |
| 4704 | |
| 4705 | value = csv.get_first(field, &value_len); |
| 4706 | if (n_values <= 0 || ptr_len_ncmp(value, value_len, "bytes=", 6)) { |
| 4707 | return; |
| 4708 | } |
| 4709 | |
| 4710 | ranges = new RangeRecord[n_values]; |
| 4711 | value += 6; // skip leading 'bytes=' |
| 4712 | value_len -= 6; |
| 4713 | |
| 4714 | // assume range_in_cache |
| 4715 | t_state.range_in_cache = true; |
| 4716 | |
| 4717 | for (; value; value = csv.get_next(&value_len)) { |
| 4718 | if (!(tmp = static_cast<const char *>(memchr(value, '-', value_len)))) { |
| 4719 | t_state.range_setup = HttpTransact::RANGE_NONE; |
| 4720 | goto Lfaild; |
| 4721 | } |
| 4722 | |
| 4723 | // process start value |
nothing calls this directly
no test coverage detected