GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/node_http_common-inl.h Lines: 66 85 77.6 %
Date: 2020-08-17 22:13:26 Branches: 15 26 57.7 %

Line Branch Exec Source
1
#ifndef SRC_NODE_HTTP_COMMON_INL_H_
2
#define SRC_NODE_HTTP_COMMON_INL_H_
3
4
#include "node_http_common.h"
5
#include "node.h"
6
#include "node_mem-inl.h"
7
#include "env-inl.h"
8
#include "v8.h"
9
10
#include <algorithm>
11
12
namespace node {
13
14
template <typename T>
15
23552
NgHeaders<T>::NgHeaders(Environment* env, v8::Local<v8::Array> headers) {
16
  v8::Local<v8::Value> header_string =
17
70656
      headers->Get(env->context(), 0).ToLocalChecked();
18
  v8::Local<v8::Value> header_count =
19
70656
      headers->Get(env->context(), 1).ToLocalChecked();
20
23552
  CHECK(header_count->IsUint32());
21
47104
  CHECK(header_string->IsString());
22
47104
  count_ = header_count.As<v8::Uint32>()->Value();
23
47104
  int header_string_len = header_string.As<v8::String>()->Length();
24
25
23552
  if (count_ == 0) {
26
25
    CHECK_EQ(header_string_len, 0);
27
51
    return;
28
  }
29
30
23527
  buf_.AllocateSufficientStorage((alignof(nv_t) - 1) +
31
23527
                                 count_ * sizeof(nv_t) +
32
                                 header_string_len);
33
34
23527
  char* start = AlignUp(buf_.out(), alignof(nv_t));
35
23527
  char* header_contents = start + (count_ * sizeof(nv_t));
36
23527
  nv_t* const nva = reinterpret_cast<nv_t*>(start);
37
38
23527
  CHECK_LE(header_contents + header_string_len, *buf_ + buf_.length());
39
70581
  CHECK_EQ(header_string.As<v8::String>()->WriteOneByte(
40
               env->isolate(),
41
               reinterpret_cast<uint8_t*>(header_contents),
42
               0,
43
               header_string_len,
44
               v8::String::NO_NULL_TERMINATION),
45
           header_string_len);
46
47
23527
  size_t n = 0;
48
  char* p;
49
95543
  for (p = header_contents; p < header_contents + header_string_len; n++) {
50
72017
    if (n >= count_) {
51
      static uint8_t zero = '\0';
52
1
      nva[0].name = nva[0].value = &zero;
53
1
      nva[0].namelen = nva[0].valuelen = 1;
54
1
      count_ = 1;
55
1
      return;
56
    }
57
58
72016
    nva[n].name = reinterpret_cast<uint8_t*>(p);
59
72016
    nva[n].namelen = strlen(p);
60
72016
    p += nva[n].namelen + 1;
61
72016
    nva[n].value = reinterpret_cast<uint8_t*>(p);
62
72016
    nva[n].valuelen = strlen(p);
63
72016
    p += nva[n].valuelen + 1;
64
72016
    nva[n].flags = *p;
65
72016
    p++;
66
  }
67
}
68
69
306
size_t GetClientMaxHeaderPairs(size_t max_header_pairs) {
70
  static constexpr size_t min_header_pairs = 1;
71
306
  return std::max(max_header_pairs, min_header_pairs);
72
}
73
74
322
size_t GetServerMaxHeaderPairs(size_t max_header_pairs) {
75
  static constexpr size_t min_header_pairs = 4;
76
322
  return std::max(max_header_pairs, min_header_pairs);
77
}
78
79
template <typename allocator_t>
80
std::string NgHeaderBase<allocator_t>::ToString() const {
81
  std::string ret = name();
82
  ret += " = ";
83
  ret += value();
84
  return ret;
85
}
86
87
template <typename T>
88
bool NgHeader<T>::IsZeroLength(
89
    NgHeader<T>::rcbuf_t* name,
90
    NgHeader<T>::rcbuf_t* value) {
91
  return IsZeroLength(-1, name, value);
92
}
93
94
template <typename T>
95
bool NgHeader<T>::IsZeroLength(
96
    int32_t token,
97
    NgHeader<T>::rcbuf_t* name,
98
    NgHeader<T>::rcbuf_t* value) {
99
100
  if (NgHeader<T>::rcbufferpointer_t::IsZeroLength(value))
101
    return true;
102
103
  const char* header_name = T::ToHttpHeaderName(token);
104
  return header_name != nullptr ||
105
      NgHeader<T>::rcbufferpointer_t::IsZeroLength(name);
106
}
107
108
template <typename T>
109
71949
NgHeader<T>::NgHeader(
110
    Environment* env,
111
    NgHeader<T>::rcbuf_t* name,
112
    NgHeader<T>::rcbuf_t* value,
113
    uint8_t flags)
114
71949
    : NgHeader<T>(env, -1, name, value, flags) {}
115
116
template <typename T>
117
71949
NgHeader<T>::NgHeader(
118
    Environment* env,
119
    int32_t token,
120
    NgHeader<T>::rcbuf_t* name,
121
    NgHeader<T>::rcbuf_t* value,
122
71949
    uint8_t flags) : env_(env), token_(token), flags_(flags) {
123
71949
  if (token == -1) {
124
71949
    CHECK_NOT_NULL(name);
125
71949
    name_.reset(name, true);  // Internalizable
126
  }
127
71949
  CHECK_NOT_NULL(value);
128
71949
  name_.reset(name, true);  // Internalizable
129
71949
  value_.reset(value);
130
71949
}
131
132
template <typename T>
133
71970
NgHeader<T>::NgHeader(NgHeader<T>&& other) noexcept
134
71970
    : name_(std::move(other.name_)),
135
71970
      value_(std::move(other.value_)),
136
71970
      token_(other.token_),
137
287880
      flags_(other.flags_) {
138
71970
  other.token_ = -1;
139
71970
  other.flags_ = 0;
140
71970
  other.env_ = nullptr;
141
71970
}
142
143
template <typename T>
144
void NgHeader<T>::MemoryInfo(MemoryTracker* tracker) const {
145
  tracker->TrackField("name", name_);
146
  tracker->TrackField("value", value_);
147
}
148
149
template <typename T>
150
71835
v8::MaybeLocal<v8::String> NgHeader<T>::GetName(
151
    NgHeader<T>::allocator_t* allocator) const {
152
153
  // Not all instances will support using token id's for header names.
154
  // HTTP/2 specifically does not support it.
155
71835
  const char* header_name = T::ToHttpHeaderName(token_);
156
157
  // If header_name is not nullptr, then it is a known header with
158
  // a statically defined name. We can safely internalize it here.
159
71835
  if (header_name != nullptr) {
160
    auto& static_str_map = env_->isolate_data()->static_str_map;
161
    v8::Eternal<v8::String> eternal = static_str_map[header_name];
162
    if (eternal.IsEmpty()) {
163
      v8::Local<v8::String> str = OneByteString(env_->isolate(), header_name);
164
      eternal.Set(env_->isolate(), str);
165
      return str;
166
    }
167
    return eternal.Get(env_->isolate());
168
  }
169
71835
  return rcbufferpointer_t::External::New(allocator, name_);
170
}
171
172
template <typename T>
173
71835
v8::MaybeLocal<v8::String> NgHeader<T>::GetValue(
174
    NgHeader<T>::allocator_t* allocator) const {
175
71835
  return rcbufferpointer_t::External::New(allocator, value_);
176
}
177
178
template <typename T>
179
std::string NgHeader<T>::name() const {
180
  return name_.str();
181
}
182
183
template <typename T>
184
std::string NgHeader<T>::value() const {
185
  return value_.str();
186
}
187
188
template <typename T>
189
71949
size_t NgHeader<T>::length() const {
190
71949
  return name_.len() + value_.len();
191
}
192
193
template <typename T>
194
71835
uint8_t NgHeader<T>::flags() const {
195
71835
  return flags_;
196
}
197
198
}  // namespace node
199
200
#endif  // SRC_NODE_HTTP_COMMON_INL_H_