mirror of
https://github.com/zeek/zeek.git
synced 2025-10-04 07:38:19 +00:00
Merge remote-tracking branch 'origin/topic/jsiwek/http-multipart-byteranges'
* origin/topic/jsiwek/http-multipart-byteranges: Teach HTTP parser to derive content length of multipart/byteranges bodies. Closes #448.
This commit is contained in:
commit
5f7aed6687
3 changed files with 67 additions and 2 deletions
63
src/HTTP.cc
63
src/HTTP.cc
|
@ -5,6 +5,8 @@
|
|||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
#include "NetVar.h"
|
||||
#include "HTTP.h"
|
||||
|
@ -310,6 +312,67 @@ 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 &&
|
||||
http_message->MyHTTP_Analyzer()->HTTP_ReplyCode() == 206 )
|
||||
{
|
||||
data_chunk_t vt = h->get_value_token();
|
||||
string byte_unit(vt.data, vt.length);
|
||||
vt = h->get_value_after_token();
|
||||
string byte_range(vt.data, vt.length);
|
||||
byte_range.erase(remove(byte_range.begin(), byte_range.end(), ' '),
|
||||
byte_range.end());
|
||||
|
||||
if ( byte_unit != "bytes" )
|
||||
{
|
||||
http_message->Weird("HTTP_content_range_unknown_byte_unit");
|
||||
return;
|
||||
}
|
||||
|
||||
size_t p = byte_range.find("/");
|
||||
if ( p == string::npos )
|
||||
{
|
||||
http_message->Weird("HTTP_content_range_cannot_parse");
|
||||
return;
|
||||
}
|
||||
|
||||
string byte_range_resp_spec = byte_range.substr(0, p);
|
||||
string instance_length = byte_range.substr(p + 1);
|
||||
|
||||
p = byte_range_resp_spec.find("-");
|
||||
if ( p == string::npos )
|
||||
{
|
||||
http_message->Weird("HTTP_content_range_cannot_parse");
|
||||
return;
|
||||
}
|
||||
|
||||
string first_byte_pos = byte_range_resp_spec.substr(0, p);
|
||||
string last_byte_pos = byte_range_resp_spec.substr(p + 1);
|
||||
|
||||
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());
|
||||
|
||||
int64_t f, l;
|
||||
atoi_n(first_byte_pos.size(), first_byte_pos.c_str(), 0, 10, f);
|
||||
atoi_n(last_byte_pos.size(), last_byte_pos.c_str(), 0, 10, l);
|
||||
int64_t len = l - f + 1;
|
||||
|
||||
if ( DEBUG_http )
|
||||
DEBUG_MSG("Content-Range length = %"PRId64"\n", len);
|
||||
|
||||
if ( len > 0 )
|
||||
content_length = len;
|
||||
else
|
||||
{
|
||||
http_message->Weird("HTTP_non_positive_content_range");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
else if ( strcasecmp_n(h->get_name(), "transfer-encoding") == 0 )
|
||||
{
|
||||
data_chunk_t vt = h->get_value_token();
|
||||
|
|
|
@ -163,6 +163,9 @@ public:
|
|||
|
||||
void SkipEntityData(int is_orig);
|
||||
|
||||
int IsConnectionClose() { return connection_close; }
|
||||
int HTTP_ReplyCode() const { return reply_code; };
|
||||
|
||||
// Overriden from Analyzer.
|
||||
virtual void Done();
|
||||
virtual void DeliverStream(int len, const u_char* data, bool orig);
|
||||
|
@ -183,8 +186,6 @@ public:
|
|||
http_content_type || http_entity_data || http_message_done ||
|
||||
http_event || http_stats) && !FLAGS_use_binpac; }
|
||||
|
||||
int IsConnectionClose() { return connection_close; }
|
||||
|
||||
protected:
|
||||
void GenStats();
|
||||
|
||||
|
|
|
@ -95,6 +95,7 @@ public:
|
|||
virtual void EndOfData();
|
||||
|
||||
MIME_Entity* Parent() const { return parent; }
|
||||
int MIMEContentType() const { return content_type; }
|
||||
StringVal* ContentType() const { return content_type_str; }
|
||||
StringVal* ContentSubType() const { return content_subtype_str; }
|
||||
int ContentTransferEncoding() const { return content_encoding; }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue