This source file includes following definitions.
- TokenizeHeaderLine
- RemoveLastTokenFromHeaderValue
- CheckHeaderForLastToken
- TokenizeHeaderValue
- ParseTokenList
#include "net/tools/balsa/balsa_headers_token_utils.h"
#include "net/tools/balsa/string_piece_utils.h"
namespace net {
inline void BalsaHeadersTokenUtils::TokenizeHeaderLine(
const BalsaHeaders& headers,
const BalsaHeaders::HeaderLineDescription& header_line,
BalsaHeaders::HeaderTokenList* tokens) {
CHECK(tokens);
const char* stream_begin = headers.GetPtr(header_line.buffer_base_idx);
const char* value_begin = stream_begin + header_line.value_begin_idx;
const char* line_end = stream_begin + header_line.last_char_idx;
ParseTokenList(value_begin, line_end, tokens);
}
void BalsaHeadersTokenUtils::RemoveLastTokenFromHeaderValue(
const base::StringPiece& key, BalsaHeaders* headers) {
BalsaHeaders::HeaderLines::iterator it =
headers->GetHeaderLinesIterator(key, headers->header_lines_.begin());
if (it == headers->header_lines_.end()) {
DLOG(WARNING) << "Attempting to remove last token from a non-existent "
<< "header \"" << key << "\"";
return;
}
BalsaHeaders::HeaderLines::iterator header_line;
do {
header_line = it;
it = headers->GetHeaderLinesIterator(key, it + 1);
}
while (it != headers->header_lines_.end());
BalsaHeaders::HeaderTokenList tokens;
TokenizeHeaderLine(*headers, *header_line, &tokens);
if (tokens.empty()) {
DLOG(WARNING) << "Attempting to remove a token from an empty header value "
<< "for header \"" << key << "\"";
header_line->skip = true;
} else if (tokens.size() == 1) {
header_line->skip = true;
} else {
const base::StringPiece& new_last_token = tokens[tokens.size() - 2];
const char* last_char_address =
new_last_token.data() + new_last_token.size() - 1;
const char* stream_begin = headers->GetPtr(header_line->buffer_base_idx);
header_line->last_char_idx = last_char_address - stream_begin + 1;
}
}
bool BalsaHeadersTokenUtils::CheckHeaderForLastToken(
const BalsaHeaders& headers,
const base::StringPiece& key,
const base::StringPiece& token) {
BalsaHeaders::const_header_lines_key_iterator it =
headers.GetIteratorForKey(key);
if (it == headers.header_lines_key_end())
return false;
BalsaHeaders::const_header_lines_key_iterator header_line = it;
do {
header_line = it;
++it;
}
while (it != headers.header_lines_key_end());
BalsaHeaders::HeaderTokenList tokens;
ParseTokenList(header_line->second.begin(), header_line->second.end(),
&tokens);
return !tokens.empty() &&
StringPieceUtils::StartsWithIgnoreCase(tokens.back(), token);
}
void BalsaHeadersTokenUtils::TokenizeHeaderValue(
const BalsaHeaders& headers,
const base::StringPiece& key,
BalsaHeaders::HeaderTokenList* tokens) {
CHECK(tokens);
tokens->clear();
for (BalsaHeaders::const_header_lines_key_iterator header_line =
headers.GetIteratorForKey(key);
header_line != headers.header_lines_key_end(); ++header_line) {
ParseTokenList(header_line->second.begin(), header_line->second.end(),
tokens);
}
}
void BalsaHeadersTokenUtils::ParseTokenList(
const char* start,
const char* end,
BalsaHeaders::HeaderTokenList* tokens) {
if (start == end) {
return;
}
while (true) {
while (*start == ',' || *start <= ' ') {
++start;
if (start == end) {
return;
}
}
const char* nws = start;
while (*start != ',' && *start > ' ') {
++start;
if (start == end) {
if (nws != start) {
tokens->push_back(base::StringPiece(nws, start - nws));
}
return;
}
}
tokens->push_back(base::StringPiece(nws, start - nws));
}
}
}