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-09-03 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
23633
NgHeaders<T>::NgHeaders(Environment* env, v8::Local<v8::Array> headers) {
16
  v8::Local<v8::Value> header_string =
17
70899
      headers->Get(env->context(), 0).ToLocalChecked();
18
  v8::Local<v8::Value> header_count =
19
70899
      headers->Get(env->context(), 1).ToLocalChecked();
20
23633
  CHECK(header_count->IsUint32());
21
47266
  CHECK(header_string->IsString());
22
47266
  count_ = header_count.As<v8::Uint32>()->Value();
23
47266
  int header_string_len = header_string.As<v8::String>()->Length();
24
25
23633
  if (count_ == 0) {
26
26
    CHECK_EQ(header_string_len, 0);
27
53
    return;
28
  }
29
30
23607
  buf_.AllocateSufficientStorage((alignof(nv_t) - 1) +
31
23607
                                 count_ * sizeof(nv_t) +
32
                                 header_string_len);
33
34
23607
  char* start = AlignUp(buf_.out(), alignof(nv_t));
35
23607
  char* header_contents = start + (count_ * sizeof(nv_t));
36
23607
  nv_t* const nva = reinterpret_cast<nv_t*>(start);
37
38
23607
  CHECK_LE(header_contents + header_string_len, *buf_ + buf_.length());
39
70821
  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
23607
  size_t n = 0;
48
  char* p;
49
95861
  for (p = header_contents; p < header_contents + header_string_len; n++) {
50
72255
    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
72254
    nva[n].name = reinterpret_cast<uint8_t*>(p);
59
72254
    nva[n].namelen = strlen(p);
60
72254
    p += nva[n].namelen + 1;
61
72254
    nva[n].value = reinterpret_cast<uint8_t*>(p);
62
72254
    nva[n].valuelen = strlen(p);
63
72254
    p += nva[n].valuelen + 1;
64
72254
    nva[n].flags = *p;
65
72254
    p++;
66
  }
67
}
68
69
307
size_t GetClientMaxHeaderPairs(size_t max_header_pairs) {
70
  static constexpr size_t min_header_pairs = 1;
71
307
  return std::max(max_header_pairs, min_header_pairs);
72
}
73
74
323
size_t GetServerMaxHeaderPairs(size_t max_header_pairs) {
75
  static constexpr size_t min_header_pairs = 4;
76
323
  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
72187
NgHeader<T>::NgHeader(
110
    Environment* env,
111
    NgHeader<T>::rcbuf_t* name,
112
    NgHeader<T>::rcbuf_t* value,
113
    uint8_t flags)
114
72187
    : NgHeader<T>(env, -1, name, value, flags) {}
115
116
template <typename T>
117
72187
NgHeader<T>::NgHeader(
118
    Environment* env,
119
    int32_t token,
120
    NgHeader<T>::rcbuf_t* name,
121
    NgHeader<T>::rcbuf_t* value,
122
72187
    uint8_t flags) : env_(env), token_(token), flags_(flags) {
123
72187
  if (token == -1) {
124
72187
    CHECK_NOT_NULL(name);
125
72187
    name_.reset(name, true);  // Internalizable
126
  }
127
72187
  CHECK_NOT_NULL(value);
128
72187
  name_.reset(name, true);  // Internalizable
129
72187
  value_.reset(value);
130
72187
}
131
132
template <typename T>
133
72208
NgHeader<T>::NgHeader(NgHeader<T>&& other) noexcept
134
72208
    : name_(std::move(other.name_)),
135
72208
      value_(std::move(other.value_)),
136
72208
      token_(other.token_),
137
288832
      flags_(other.flags_) {
138
72208
  other.token_ = -1;
139
72208
  other.flags_ = 0;
140
72208
  other.env_ = nullptr;
141
72208
}
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
72073
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
72073
  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
72073
  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
72073
  return rcbufferpointer_t::External::New(allocator, name_);
170
}
171
172
template <typename T>
173
72073
v8::MaybeLocal<v8::String> NgHeader<T>::GetValue(
174
    NgHeader<T>::allocator_t* allocator) const {
175
72073
  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
72187
size_t NgHeader<T>::length() const {
190
72187
  return name_.len() + value_.len();
191
}
192
193
template <typename T>
194
72073
uint8_t NgHeader<T>::flags() const {
195
72073
  return flags_;
196
}
197
198
}  // namespace node
199
200
#endif  // SRC_NODE_HTTP_COMMON_INL_H_