| 364 | } |
| 365 | |
| 366 | int |
| 367 | QPACK::_encode_header(const MIMEField &field, uint16_t base_index, IOBufferBlock *compressed_header, uint16_t &referred_index) |
| 368 | { |
| 369 | auto name{field.name_get()}; |
| 370 | char *lowered_name = this->_arena.str_store(name.data(), name.length()); |
| 371 | for (size_t i = 0; i < name.length(); i++) { |
| 372 | lowered_name[i] = ParseRules::ink_tolower(lowered_name[i]); |
| 373 | } |
| 374 | auto value{field.value_get()}; |
| 375 | |
| 376 | // TODO Set never_index flag on/off according to encoding headers |
| 377 | bool never_index = false; |
| 378 | |
| 379 | // Find from tables, and insert / duplicate a entry prior to encode it |
| 380 | XpackLookupResult lookup_result_static; |
| 381 | XpackLookupResult lookup_result_dynamic; |
| 382 | lookup_result_static = StaticTable::lookup(lowered_name, name.length(), value.data(), value.length()); |
| 383 | if (lookup_result_static.match_type != XpackLookupResult::MatchType::EXACT) { |
| 384 | lookup_result_dynamic = this->_dynamic_table.lookup(lowered_name, name.length(), value.data(), value.length()); |
| 385 | if (lookup_result_dynamic.match_type == XpackLookupResult::MatchType::EXACT) { |
| 386 | if (this->_dynamic_table.should_duplicate(lookup_result_dynamic.index)) { |
| 387 | // Duplicate an entry and use the new entry |
| 388 | uint16_t current_index = lookup_result_dynamic.index; |
| 389 | lookup_result_dynamic = this->_dynamic_table.duplicate_entry(current_index); |
| 390 | if (lookup_result_dynamic.match_type != XpackLookupResult::MatchType::NONE) { |
| 391 | this->_write_duplicate(current_index); |
| 392 | QPACKDebug("Wrote Duplicate: current_index=%d", current_index); |
| 393 | this->_dynamic_table.ref_entry(current_index); |
| 394 | } |
| 395 | } |
| 396 | } else if (lookup_result_static.match_type == XpackLookupResult::MatchType::NAME) { |
| 397 | if (never_index) { |
| 398 | // Name in static table is always available. Do nothing. |
| 399 | } else { |
| 400 | // Insert both the name and the value |
| 401 | lookup_result_dynamic = this->_dynamic_table.insert_entry(lowered_name, name.length(), value.data(), value.length()); |
| 402 | if (lookup_result_dynamic.match_type != XpackLookupResult::MatchType::NONE) { |
| 403 | this->_write_insert_with_name_ref(lookup_result_static.index, false, value.data(), value.length()); |
| 404 | QPACKDebug("Wrote Insert With Name Ref: index=%u, dynamic_table=%d value=%.*s", lookup_result_static.index, false, |
| 405 | static_cast<int>(value.length()), value.data()); |
| 406 | } |
| 407 | } |
| 408 | } else if (lookup_result_dynamic.match_type == XpackLookupResult::MatchType::NAME) { |
| 409 | if (never_index) { |
| 410 | if (this->_dynamic_table.should_duplicate(lookup_result_dynamic.index)) { |
| 411 | // Duplicate an entry and use the new entry |
| 412 | uint16_t current_index = lookup_result_dynamic.index; |
| 413 | lookup_result_dynamic = this->_dynamic_table.duplicate_entry(current_index); |
| 414 | if (lookup_result_dynamic.match_type != XpackLookupResult::MatchType::NONE) { |
| 415 | this->_write_duplicate(current_index); |
| 416 | QPACKDebug("Wrote Duplicate: current_index=%d", current_index); |
| 417 | this->_dynamic_table.ref_entry(current_index); |
| 418 | } |
| 419 | } |
| 420 | } else { |
| 421 | if (this->_dynamic_table.should_duplicate(lookup_result_dynamic.index)) { |
| 422 | // Duplicate an entry and use the new entry |
| 423 | uint16_t current_index = lookup_result_dynamic.index; |
no test coverage detected