LCOV - code coverage report
Current view: top level - src - HTTP.h (source / functions) Hit Total Coverage
Test: app.info Lines: 17 21 81.0 %
Date: 2010-12-13 Functions: 10 14 71.4 %
Branches: 6 26 23.1 %

           Branch data     Line data    Source code
       1                 :            : // $Id: HTTP.h 6942 2009-11-16 03:54:08Z vern $
       2                 :            : //
       3                 :            : // See the file "COPYING" in the main distribution directory for copyright.
       4                 :            : 
       5                 :            : #ifndef http_h
       6                 :            : #define http_h
       7                 :            : 
       8                 :            : #include "TCP.h"
       9                 :            : #include "ContentLine.h"
      10                 :            : #include "MIME.h"
      11                 :            : #include "binpac_bro.h"
      12                 :            : #include "ZIP.h"
      13                 :            : 
      14                 :            : enum CHUNKED_TRANSFER_STATE {
      15                 :            :         NON_CHUNKED_TRANSFER,
      16                 :            :         BEFORE_CHUNK,
      17                 :            :         EXPECT_CHUNK_SIZE,
      18                 :            :         EXPECT_CHUNK_DATA,
      19                 :            :         EXPECT_CHUNK_DATA_CRLF,
      20                 :            :         EXPECT_CHUNK_TRAILER,
      21                 :            :         EXPECT_NOTHING,
      22                 :            : };
      23                 :            : 
      24                 :            : class HTTP_Entity;
      25                 :            : class HTTP_Message;
      26                 :            : class HTTP_Analyzer;
      27                 :            : 
      28                 :            : class HTTP_Entity : public MIME_Entity {
      29                 :            : public:
      30                 :            :         HTTP_Entity(HTTP_Message* msg, MIME_Entity* parent_entity,
      31                 :            :                         int expect_body);
      32                 :        881 :         ~HTTP_Entity()
      33                 :        881 :                 {
      34                 :            : #ifdef HAVE_LIBZ
      35 [ -  + ][ #  # ]:        881 :                 if ( zip )
      36 [ #  # ][ #  # ]:          0 :                         { zip->Done(); delete zip; }
      37                 :            : #endif
      38 [ +  - ][ #  # ]:        881 :                 }
      39                 :            : 
      40                 :            :         void EndOfData();
      41                 :            :         void Deliver(int len, const char* data, int trailing_CRLF);
      42                 :            :         int Undelivered(int len);
      43                 :        881 :         int BodyLength() const          { return body_length; }
      44                 :        881 :         int HeaderLength() const        { return header_length; }
      45                 :          0 :         void SkipBody()                 { deliver_body = 0; }
      46                 :            : 
      47                 :            : protected:
      48                 :            :         class UncompressedOutput;
      49                 :            :         friend class UncompressedOutput;
      50                 :            : 
      51                 :            :         HTTP_Message* http_message;
      52                 :            :         int chunked_transfer_state;
      53                 :            :         int content_length;
      54                 :            :         int expect_data_length;
      55                 :            :         int expect_body;
      56                 :            :         int body_length;
      57                 :            :         int header_length;
      58                 :            :         int deliver_body;
      59                 :            :         enum { IDENTITY, GZIP, COMPRESS, DEFLATE } encoding;
      60                 :            : #ifdef HAVE_LIBZ
      61                 :            :         ZIP_Analyzer* zip;
      62                 :            : #endif
      63                 :            : 
      64                 :          0 :         MIME_Entity* NewChildEntity() { return new HTTP_Entity(http_message, this, 1); }
      65                 :            : 
      66                 :            :         void DeliverBody(int len, const char* data, int trailing_CRLF);
      67                 :            :         void DeliverBodyClear(int len, const char* data, int trailing_CRLF);
      68                 :            : 
      69                 :            :         void SubmitData(int len, const char* buf);
      70                 :            : 
      71                 :            :         void SetPlainDelivery(int length);
      72                 :            : 
      73                 :            :         void SubmitHeader(MIME_Header* h);
      74                 :            :         void SubmitAllHeaders();
      75                 :            : };
      76                 :            : 
      77                 :            : enum {
      78                 :            :         HTTP_BODY_NOT_EXPECTED,
      79                 :            :         HTTP_BODY_EXPECTED,
      80                 :            :         HTTP_BODY_MAYBE,
      81                 :            : };
      82                 :            : 
      83                 :            : // Finishing HTTP Messages:
      84                 :            : //
      85                 :            : // HTTP_Entity::SubmitAllHeaders        -> EndOfData (no body)
      86                 :            : // HTTP_Entity::Deliver -> EndOfData (end of body)
      87                 :            : // HTTP_Analyzer::Done  -> {Request,Reply}Made (connection terminated)
      88                 :            : // {Request,Reply}Made  -> HTTP_Message::Done
      89                 :            : // HTTP_Message::Done   -> MIME_Message::Done, EndOfData, HTTP_MessageDone
      90                 :            : // MIME_Entity::EndOfData       -> Message::EndEntity
      91                 :            : // HTTP_Message::EndEntity      -> Message::Done
      92                 :            : // HTTP_MessageDone     -> {Request,Reply}Made
      93                 :            : 
      94                 :            : class HTTP_Message : public MIME_Message {
      95                 :            : public:
      96                 :            :         HTTP_Message(HTTP_Analyzer* analyzer, ContentLine_Analyzer* cl,
      97                 :            :                          bool is_orig, int expect_body, int init_header_length);
      98                 :            :         ~HTTP_Message();
      99                 :            :         void Done(const int interrupted, const char* msg);
     100                 :        881 :         void Done() { Done(0, "message ends normally"); }
     101                 :            : 
     102                 :            :         int Undelivered(int len);
     103                 :            : 
     104                 :            :         void BeginEntity(MIME_Entity* /* entity */);
     105                 :            :         void EndEntity(MIME_Entity* entity);
     106                 :            :         void SubmitHeader(MIME_Header* h);
     107                 :            :         void SubmitAllHeaders(MIME_HeaderList& /* hlist */);
     108                 :            :         void SubmitData(int len, const char* buf);
     109                 :            :         int RequestBuffer(int* plen, char** pbuf);
     110                 :            :         void SubmitAllData();
     111                 :            :         void SubmitEvent(int event_type, const char* detail);
     112                 :            : 
     113                 :            :         void SubmitTrailingHeaders(MIME_HeaderList& /* hlist */);
     114                 :            :         void SetPlainDelivery(int length);
     115                 :            :         void SkipEntityData();
     116                 :            : 
     117                 :      15034 :         HTTP_Analyzer* MyHTTP_Analyzer() const
     118                 :      15034 :                 { return (HTTP_Analyzer*) analyzer; }
     119                 :            : 
     120                 :            :         void Weird(const char* msg);
     121                 :       7890 :         bool IsOrig()   { return is_orig; }
     122                 :            : 
     123                 :            : protected:
     124                 :            :         HTTP_Analyzer* analyzer;
     125                 :            :         ContentLine_Analyzer* content_line;
     126                 :            :         bool is_orig;
     127                 :            : 
     128                 :            :         vector<const BroString*> buffers;
     129                 :            : 
     130                 :            :         // Controls the total buffer size within http_entity_data_delivery_size.
     131                 :            :         int total_buffer_size;
     132                 :            : 
     133                 :            :         int buffer_offset, buffer_size;
     134                 :            :         BroString* data_buffer;
     135                 :            : 
     136                 :            :         double start_time;
     137                 :            : 
     138                 :            :         int body_length;        // total length of entity bodies
     139                 :            :         int header_length;      // total length of headers, including the request/reply line
     140                 :            : 
     141                 :            :         // Total length of content gaps that are "successfully" skipped.
     142                 :            :         // Note: this might NOT include all content gaps!
     143                 :            :         int content_gap_length;
     144                 :            : 
     145                 :            :         HTTP_Entity* current_entity;
     146                 :            : 
     147                 :            :         int InitBuffer(int length);
     148                 :            :         void DeliverEntityData();
     149                 :            : 
     150                 :            :         Val* BuildMessageStat(const int interrupted, const char* msg);
     151                 :            : };
     152                 :            : 
     153                 :            : class HTTP_Analyzer : public TCP_ApplicationAnalyzer {
     154                 :            : public:
     155                 :            :         HTTP_Analyzer(Connection* conn);
     156                 :            :         ~HTTP_Analyzer();
     157                 :            : 
     158                 :            :         void Undelivered(TCP_Endpoint* sender, int seq, int len);
     159                 :            : 
     160                 :            :         void HTTP_Header(int is_orig, MIME_Header* h);
     161                 :            :         void HTTP_EntityData(int is_orig, const BroString* entity_data);
     162                 :            :         void HTTP_MessageDone(int is_orig, HTTP_Message* message);
     163                 :            :         void HTTP_Event(const char* category, const char* detail);
     164                 :            :         void HTTP_Event(const char* category, StringVal *detail);
     165                 :            : 
     166                 :            :         void SkipEntityData(int is_orig);
     167                 :            : 
     168                 :            :         // Overriden from Analyzer.
     169                 :            :         virtual void Done();
     170                 :            :         virtual void DeliverStream(int len, const u_char* data, bool orig);
     171                 :            :         virtual void Undelivered(int seq, int len, bool orig);
     172                 :      12416 :         virtual int RewritingTrace()
     173 [ +  - ][ -  + ]:      12416 :                 { return rewriting_http_trace || TCP_ApplicationAnalyzer::RewritingTrace(); }
     174                 :            : 
     175                 :            :         // Overriden from TCP_ApplicationAnalyzer
     176                 :            :         virtual void EndpointEOF(bool is_orig);
     177                 :            :         virtual void ConnectionFinished(int half_finished);
     178                 :            :         virtual void ConnectionReset();
     179                 :            :         virtual void PacketWithRST();
     180                 :            : 
     181                 :        684 :         static Analyzer* InstantiateAnalyzer(Connection* conn)
     182                 :        684 :                 { return new HTTP_Analyzer(conn); }
     183                 :            : 
     184                 :          1 :         static bool Available()
     185 [ -  + ][ #  # ]:          1 :                 { return (http_request || http_reply) && !FLAGS_use_binpac; }
                 [ +  - ]
     186                 :            : 
     187                 :        428 :         int IsConnectionClose()         { return connection_close; }
     188                 :            : 
     189                 :            : protected:
     190                 :            :         void GenStats();
     191                 :            : 
     192                 :            :         int HTTP_RequestLine(const char* line, const char* end_of_line);
     193                 :            :         int HTTP_ReplyLine(const char* line, const char* end_of_line);
     194                 :            : 
     195                 :            :         void InitHTTPMessage(ContentLine_Analyzer* cl, HTTP_Message*& message, bool is_orig,
     196                 :            :                                 int expect_body, int init_header_length);
     197                 :            : 
     198                 :            :         const char* PrefixMatch(const char* line, const char* end_of_line,
     199                 :            :                                 const char* prefix);
     200                 :            :         const char* PrefixWordMatch(const char* line, const char* end_of_line,
     201                 :            :                                 const char* prefix);
     202                 :            : 
     203                 :            :         int ParseRequest(const char* line, const char* end_of_line);
     204                 :            :         double HTTP_Version(int len, const char* data);
     205                 :            : 
     206                 :            :         void SetVersion(double& version, double new_version);
     207                 :            : 
     208 [ #  # ][ #  # ]:          0 :         int RequestExpected() const { return num_requests == 0 || keep_alive; }
     209                 :            : 
     210                 :            :         void HTTP_Request();
     211                 :            :         void HTTP_Reply();
     212                 :            : 
     213                 :            :         void RequestMade(const int interrupted, const char* msg);
     214                 :            :         void ReplyMade(const int interrupted, const char* msg);
     215                 :            :         void RequestClash(Val* clash_val);
     216                 :            : 
     217                 :            :         const BroString* UnansweredRequestMethod();
     218                 :            : 
     219                 :            :         void ParseVersion(data_chunk_t ver, const uint32* host, bool user_agent);
     220                 :            :         int HTTP_ReplyCode(const char* code_str);
     221                 :            :         int ExpectReplyMessageBody();
     222                 :            : 
     223                 :            :         StringVal* TruncateURI(StringVal* uri);
     224                 :            : 
     225                 :            :         int request_state, reply_state;
     226                 :            :         int num_requests, num_replies;
     227                 :            :         int num_request_lines, num_reply_lines;
     228                 :            :         double request_version, reply_version;
     229                 :            :         int keep_alive;
     230                 :            :         int connection_close;
     231                 :            :         int request_ongoing, reply_ongoing;
     232                 :            : 
     233                 :            :         Val* request_method;
     234                 :            : 
     235                 :            :         // request_URI is in the original form (may contain '%<hex><hex>'
     236                 :            :         // sequences).
     237                 :            :         Val* request_URI;
     238                 :            : 
     239                 :            :         // unescaped_URI does not contain escaped sequences.
     240                 :            :         Val* unescaped_URI;
     241                 :            : 
     242                 :            :         std::queue<Val*> unanswered_requests;
     243                 :            : 
     244                 :            :         int reply_code;
     245                 :            :         Val* reply_reason_phrase;
     246                 :            : 
     247                 :            :         ContentLine_Analyzer* content_line_orig;
     248                 :            :         ContentLine_Analyzer* content_line_resp;
     249                 :            : 
     250                 :            :         HTTP_Message* request_message;
     251                 :            :         HTTP_Message* reply_message;
     252                 :            : };
     253                 :            : 
     254                 :            : extern int is_reserved_URI_char(unsigned char ch);
     255                 :            : extern int is_unreserved_URI_char(unsigned char ch);
     256                 :            : extern void escape_URI_char(unsigned char ch, unsigned char*& p);
     257                 :            : extern BroString* unescape_URI(const u_char* line, const u_char* line_end,
     258                 :            :                                 Analyzer* analyzer);
     259                 :            : 
     260                 :            : #endif

Generated by: LCOV version 1.8