FileAnalysis: add unit tests covering current protocol integration.

And had to make various fixes/refinements after scrutinizing results.
This commit is contained in:
Jon Siwek 2013-03-19 15:50:05 -05:00
parent b30211c178
commit 59ed5c75f1
72 changed files with 2605 additions and 53 deletions

View file

@ -47,7 +47,8 @@ HTTP_Entity::HTTP_Entity(HTTP_Message *arg_message, MIME_Entity* parent_entity,
zip = 0;
is_partial_content = false;
offset = 0;
content_size = -1; // unspecified
instance_length = -1; // unspecified
send_size = true;
}
void HTTP_Entity::EndOfData()
@ -282,27 +283,33 @@ void HTTP_Entity::SubmitData(int len, const char* buf)
if ( deliver_body )
MIME_Entity::SubmitData(len, buf);
if ( send_size && ( encoding == GZIP || encoding == DEFLATE ) )
// Auto-decompress in DeliverBody invalidates sizes derived from headers
send_size = false;
if ( is_partial_content )
{
if ( send_size && instance_length > 0 )
file_mgr->SetSize(instance_length,
http_message->MyHTTP_Analyzer()->Conn(),
http_message->IsOrig());
file_mgr->DataIn(reinterpret_cast<const u_char*>(buf), len, offset,
http_message->MyHTTP_Analyzer()->Conn(),
http_message->IsOrig());
http_message->MyHTTP_Analyzer()->Conn(),
http_message->IsOrig());
offset += len;
if ( content_size >= 0 )
file_mgr->SetSize(content_size,
http_message->MyHTTP_Analyzer()->Conn(),
http_message->IsOrig());
}
else
{
file_mgr->DataIn(reinterpret_cast<const u_char*>(buf), len,
http_message->MyHTTP_Analyzer()->Conn(),
http_message->IsOrig());
if ( content_length >= 0 )
if ( send_size && content_length > 0 )
file_mgr->SetSize(content_length,
http_message->MyHTTP_Analyzer()->Conn(),
http_message->IsOrig());
http_message->MyHTTP_Analyzer()->Conn(),
http_message->IsOrig());
file_mgr->DataIn(reinterpret_cast<const u_char*>(buf), len,
http_message->MyHTTP_Analyzer()->Conn(),
http_message->IsOrig());
}
send_size = false;
}
void HTTP_Entity::SetPlainDelivery(int64_t length)
@ -333,9 +340,7 @@ void HTTP_Entity::SubmitHeader(MIME_Header* h)
}
// Figure out content-length for HTTP 206 Partial Content response
// that uses multipart/byteranges content-type.
else if ( strcasecmp_n(h->get_name(), "content-range") == 0 && Parent() &&
Parent()->MIMEContentType() == CONTENT_TYPE_MULTIPART &&
else if ( strcasecmp_n(h->get_name(), "content-range") == 0 &&
http_message->MyHTTP_Analyzer()->HTTP_ReplyCode() == 206 )
{
data_chunk_t vt = h->get_value_token();
@ -359,7 +364,7 @@ void HTTP_Entity::SubmitHeader(MIME_Header* h)
}
string byte_range_resp_spec = byte_range.substr(0, p);
string instance_length = byte_range.substr(p + 1);
string instance_length_str = byte_range.substr(p + 1);
p = byte_range_resp_spec.find("-");
if ( p == string::npos )
@ -374,7 +379,7 @@ void HTTP_Entity::SubmitHeader(MIME_Header* h)
if ( DEBUG_http )
DEBUG_MSG("Parsed Content-Range: %s %s-%s/%s\n", byte_unit.c_str(),
first_byte_pos.c_str(), last_byte_pos.c_str(),
instance_length.c_str());
instance_length_str.c_str());
int64_t f, l;
atoi_n(first_byte_pos.size(), first_byte_pos.c_str(), 0, 10, f);
@ -386,9 +391,13 @@ void HTTP_Entity::SubmitHeader(MIME_Header* h)
if ( len > 0 )
{
if ( instance_length != "*" )
atoi_n(instance_length.size(), instance_length.c_str(), 0, 10,
content_size);
if ( instance_length_str != "*" )
{
if ( ! atoi_n(instance_length_str.size(),
instance_length_str.c_str(), 0, 10,
instance_length) )
instance_length = 0;
}
is_partial_content = true;
offset = f;
content_length = len;
@ -554,8 +563,11 @@ void HTTP_Message::Done(const int interrupted, const char* detail)
GetAnalyzer()->ConnectionEvent(http_message_done, vl);
}
if ( is_orig || MyHTTP_Analyzer()->HTTP_ReplyCode() != 206 )
// multipart/byteranges may span multiple connections
file_mgr->EndOfFile(MyHTTP_Analyzer()->Conn(), is_orig);
MyHTTP_Analyzer()->HTTP_MessageDone(is_orig, this);
file_mgr->EndOfFile(MyHTTP_Analyzer()->Conn(), is_orig);
delete_strings(buffers);
@ -620,8 +632,7 @@ void HTTP_Message::EndEntity(MIME_Entity* entity)
// SubmitAllHeaders (through EndOfData).
if ( entity == top_level )
Done();
else if ( ! ( current_entity->MIMEContentType() == CONTENT_TYPE_MULTIPART &&
MyHTTP_Analyzer()->HTTP_ReplyCode() == 206 ) )
else if ( is_orig || MyHTTP_Analyzer()->HTTP_ReplyCode() != 206 )
file_mgr->EndOfFile(MyHTTP_Analyzer()->Conn(), is_orig);
}
@ -884,7 +895,12 @@ void HTTP_Analyzer::Done()
unanswered_requests.pop();
}
file_mgr->EndOfFile(Conn());
file_mgr->EndOfFile(Conn(), true);
/* TODO: this might be nice to have, but reply code is cleared by now.
if ( HTTP_ReplyCode() != 206 )
// multipart/byteranges may span multiple connections
file_mgr->EndOfFile(Conn(), false);
*/
}
void HTTP_Analyzer::DeliverStream(int len, const u_char* data, bool is_orig)