This source file includes following definitions.
- IsCompleteMessage
- StringToMethod
- StringToVersion
- MethodToString
- VersionToString
- InitializeFields
- AddHeader
- RemoveHeader
- ReplaceHeader
- AddBody
- ValidateMessage
#include "net/tools/quic/test_tools/http_message.h"
#include <vector>
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
using base::StringPiece;
using std::string;
using std::vector;
namespace net {
namespace tools {
namespace test {
namespace {
const char* kContentLength = "content-length";
const char* kTransferCoding = "transfer-encoding";
const char* kHTTPVersionString[] = {
"",
"HTTP/0.9",
"HTTP/1.0",
"HTTP/1.1"
};
const char* kMethodString[] = {
"",
"OPTIONS",
"GET",
"HEAD",
"POST",
"PUT",
"DELETE",
"TRACE",
"CONNECT",
"MKCOL",
"UNLOCK",
};
bool IsCompleteMessage(const HTTPMessage& message) {
const BalsaHeaders* headers = message.headers();
StringPiece content_length = headers->GetHeader(kContentLength);
if (!content_length.empty()) {
int parsed_content_length;
if (!base::StringToInt(content_length, &parsed_content_length)) {
return false;
}
return (message.body().size() == (uint)parsed_content_length);
} else {
return message.has_complete_message();
}
}
}
HTTPMessage::Method HTTPMessage::StringToMethod(StringPiece str) {
for (unsigned long i = 1; i < arraysize(kMethodString); ++i) {
if (strncmp(str.data(), kMethodString[i], str.length()) == 0) {
return static_cast<HTTPMessage::Method>(i);
}
}
return HttpConstants::UNKNOWN_METHOD;
}
HTTPMessage::Version HTTPMessage::StringToVersion(StringPiece str) {
for (unsigned long i = 1; i < arraysize(kHTTPVersionString); ++i) {
if (strncmp(str.data(), kHTTPVersionString[i], str.length()) == 0) {
return static_cast<HTTPMessage::Version>(i);
}
}
return HttpConstants::HTTP_UNKNOWN;
}
const char* HTTPMessage::MethodToString(Method method) {
CHECK_LT(static_cast<size_t>(method), arraysize(kMethodString));
return kMethodString[method];
}
const char* HTTPMessage::VersionToString(Version version) {
CHECK_LT(static_cast<size_t>(version), arraysize(kHTTPVersionString));
return kHTTPVersionString[version];
}
HTTPMessage::HTTPMessage()
: is_request_(true) {
InitializeFields();
}
HTTPMessage::HTTPMessage(Version ver, Method request, const string& path)
: is_request_(true) {
InitializeFields();
if (ver != HttpConstants::HTTP_0_9) {
headers()->SetRequestVersion(VersionToString(ver));
}
headers()->SetRequestMethod(MethodToString(request));
headers()->SetRequestUri(path);
}
HTTPMessage::~HTTPMessage() {
}
void HTTPMessage::InitializeFields() {
has_complete_message_ = true;
skip_message_validation_ = false;
}
void HTTPMessage::AddHeader(const string& header, const string& value) {
headers()->AppendHeader(header, value);
}
void HTTPMessage::RemoveHeader(const string& header) {
headers()->RemoveAllOfHeader(header);
}
void HTTPMessage::ReplaceHeader(const string& header, const string& value) {
headers()->ReplaceOrAppendHeader(header, value);
}
void HTTPMessage::AddBody(const string& body, bool add_content_length) {
body_ = body;
RemoveHeader(kTransferCoding);
if (add_content_length) {
ReplaceHeader(kContentLength, base::IntToString(body.size()));
} else {
RemoveHeader(kContentLength);
}
}
void HTTPMessage::ValidateMessage() const {
if (skip_message_validation_) {
return;
}
vector<StringPiece> transfer_encodings;
headers()->GetAllOfHeader(kTransferCoding, &transfer_encodings);
CHECK_GE(1ul, transfer_encodings.size());
for (vector<StringPiece>::iterator it = transfer_encodings.begin();
it != transfer_encodings.end();
++it) {
CHECK(StringPieceUtils::EqualIgnoreCase("identity", *it) ||
StringPieceUtils::EqualIgnoreCase("chunked", *it)) << *it;
}
vector<StringPiece> content_lengths;
headers()->GetAllOfHeader(kContentLength, &content_lengths);
CHECK_GE(1ul, content_lengths.size());
CHECK_EQ(has_complete_message_, IsCompleteMessage(*this));
}
}
}
}