1 //--------------------------------------------------------------------------
2 // Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
3 //
4 // This program is free software; you can redistribute it and/or modify it
5 // under the terms of the GNU General Public License Version 2 as published
6 // by the Free Software Foundation.  You may not use, modify or distribute
7 // this program under any other version of the GNU General Public License.
8 //
9 // This program is distributed in the hope that it will be useful, but
10 // WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License along
15 // with this program; if not, write to the Free Software Foundation, Inc.,
16 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 //--------------------------------------------------------------------------
18 // http_field.cc author Tom Peters <thopeter@cisco.com>
19 
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23 
24 #include "http_field.h"
25 
26 #include "http_common.h"
27 #include "http_enum.h"
28 #include "http_test_manager.h"
29 
30 using namespace HttpCommon;
31 using namespace HttpEnums;
32 
33 const Field Field::FIELD_NULL { STAT_NO_SOURCE };
34 
Field(int32_t length,const uint8_t * start,bool own_the_buffer_)35 Field::Field(int32_t length, const uint8_t* start, bool own_the_buffer_) :
36     strt(start), len(length), own_the_buffer(own_the_buffer_)
37 {
38     assert(!((start == nullptr) && (length > 0)));
39     assert(!((start != nullptr) && (length < 0)));
40 }
41 
operator =(const Field & rhs)42 Field& Field::operator=(const Field& rhs)
43 {
44     assert(len == STAT_NOT_COMPUTE);
45     assert(strt == nullptr);
46     strt = rhs.strt;
47     len = rhs.len;
48     own_the_buffer = false;    // buffer must not have two owners
49     return *this;
50 }
51 
set(int32_t length,const uint8_t * start,bool own_the_buffer_)52 void Field::set(int32_t length, const uint8_t* start, bool own_the_buffer_)
53 {
54     assert(len == STAT_NOT_COMPUTE);
55     assert(strt == nullptr);
56     assert(start != nullptr);
57     assert(length >= 0);
58     strt = start;
59     len = length;
60     own_the_buffer = own_the_buffer_;
61 }
62 
set(StatusCode stat_code)63 void Field::set(StatusCode stat_code)
64 {
65     assert(len == STAT_NOT_COMPUTE);
66     assert(strt == nullptr);
67     assert(stat_code <= 0);
68     len = stat_code;
69 }
70 
set(const Field & f)71 void Field::set(const Field& f)
72 {
73     assert(len == STAT_NOT_COMPUTE);
74     assert(strt == nullptr);
75     strt = f.strt;
76     len = f.len;
77     // Both Fields cannot be responsible for deleting the buffer so do not copy own_the_buffer
78 }
79 
80 #ifdef REG_TEST
print(FILE * output,const char * name) const81 void Field::print(FILE* output, const char* name) const
82 {
83     if ((len == STAT_NOT_PRESENT) || (len == STAT_NOT_COMPUTE) || (len == STAT_NO_SOURCE))
84     {
85         return;
86     }
87     const int out_count = fprintf(output, "%s, length = %d, ", name, len);
88     if (len <= 0)
89     {
90         fprintf(output, "\n");
91         return;
92     }
93     // Limit the amount of data printed
94     const int32_t print_length = (len <= HttpTestManager::get_print_amount()) ? len :
95         HttpTestManager::get_print_amount();
96     for (int32_t k=0; k < print_length; k++)
97     {
98         if ((strt[k] >= 0x20) && (strt[k] <= 0x7E))
99             fprintf(output, "%c", (char)strt[k]);
100         else if (strt[k] == 0xD)
101             fprintf(output, "~");
102         else if (strt[k] == 0xA)
103             fprintf(output, "^");
104         else if (HttpTestManager::get_print_hex())
105             fprintf(output, "[%.2x]", (uint8_t)strt[k]);
106         else
107             fprintf(output, "*");
108         if ((k%120 == (119 - out_count)) && (k+1 < print_length))
109         {
110             fprintf(output, "\n");
111         }
112     }
113     fprintf(output, "\n");
114 }
115 #endif
116 
117