Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
nghttp2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
nghttp2
Commits
b1edb1f3
Commit
b1edb1f3
authored
Apr 03, 2014
by
Tatsuhiro Tsujikawa
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Don't index name/value pair bearing NO_INDEX flag when forwarding it
parent
c53c1dc6
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
276 additions
and
200 deletions
+276
-200
lib/includes/nghttp2/nghttp2.h
lib/includes/nghttp2/nghttp2.h
+4
-0
src/HttpServer.cc
src/HttpServer.cc
+16
-15
src/h2load.cc
src/h2load.cc
+4
-4
src/http2.cc
src/http2.cc
+60
-41
src/http2.h
src/http2.h
+37
-6
src/http2_test.cc
src/http2_test.cc
+22
-15
src/nghttp.cc
src/nghttp.cc
+28
-23
src/shrpx_downstream.cc
src/shrpx_downstream.cc
+41
-36
src/shrpx_downstream.h
src/shrpx_downstream.h
+4
-2
src/shrpx_downstream_test.cc
src/shrpx_downstream_test.cc
+17
-17
src/shrpx_http2_downstream_connection.cc
src/shrpx_http2_downstream_connection.cc
+5
-5
src/shrpx_http2_session.cc
src/shrpx_http2_session.cc
+4
-3
src/shrpx_http2_upstream.cc
src/shrpx_http2_upstream.cc
+8
-7
src/shrpx_http_downstream_connection.cc
src/shrpx_http_downstream_connection.cc
+11
-11
src/shrpx_https_upstream.cc
src/shrpx_https_upstream.cc
+6
-6
src/shrpx_spdy_upstream.cc
src/shrpx_spdy_upstream.cc
+9
-9
No files found.
lib/includes/nghttp2/nghttp2.h
View file @
b1edb1f3
...
@@ -1342,6 +1342,10 @@ typedef int (*nghttp2_on_begin_headers_callback)
...
@@ -1342,6 +1342,10 @@ typedef int (*nghttp2_on_begin_headers_callback)
* The |value| of length |valuelen| is header value. The |flags| is
* The |value| of length |valuelen| is header value. The |flags| is
* bitwise OR of one or more of :type:`nghttp2_nv_flag`.
* bitwise OR of one or more of :type:`nghttp2_nv_flag`.
*
*
* If :enum:`NGHTTP2_NV_FLAG_NO_INDEX` is set in |flags|, the receiver
* must not index this name/value pair when forwarding it to the next
* hop.
*
* When this callback is invoked, ``frame->hd.type`` is either
* When this callback is invoked, ``frame->hd.type`` is either
* :enum:`NGHTTP2_HEADERS` or :enum:`NGHTTP2_PUSH_PROMISE`. After all
* :enum:`NGHTTP2_HEADERS` or :enum:`NGHTTP2_PUSH_PROMISE`. After all
* header name/value pairs are processed with this callback, and no
* header name/value pairs are processed with this callback, and no
...
...
src/HttpServer.cc
View file @
b1edb1f3
...
@@ -805,7 +805,7 @@ int Http2Handler::submit_response
...
@@ -805,7 +805,7 @@ int Http2Handler::submit_response
http2
::
make_nv_ls
(
"date"
,
date_str
)
http2
::
make_nv_ls
(
"date"
,
date_str
)
};
};
for
(
size_t
i
=
0
;
i
<
headers
.
size
();
++
i
)
{
for
(
size_t
i
=
0
;
i
<
headers
.
size
();
++
i
)
{
nva
.
push_back
(
http2
::
make_nv
(
headers
[
i
].
first
,
headers
[
i
].
second
));
nva
.
push_back
(
http2
::
make_nv
(
headers
[
i
].
first
,
headers
[
i
].
second
,
false
));
}
}
int
r
=
nghttp2_submit_response
(
session_
,
stream_id
,
nva
.
data
(),
nva
.
size
(),
int
r
=
nghttp2_submit_response
(
session_
,
stream_id
,
nva
.
data
(),
nva
.
size
(),
data_prd
);
data_prd
);
...
@@ -830,21 +830,21 @@ int Http2Handler::submit_push_promise(Stream *stream,
...
@@ -830,21 +830,21 @@ int Http2Handler::submit_push_promise(Stream *stream,
std
::
string
authority
;
std
::
string
authority
;
auto
itr
=
std
::
lower_bound
(
std
::
begin
(
stream
->
headers
),
auto
itr
=
std
::
lower_bound
(
std
::
begin
(
stream
->
headers
),
std
::
end
(
stream
->
headers
),
std
::
end
(
stream
->
headers
),
std
::
make_pair
(
std
::
string
(
":authority"
),
Header
(
":authority"
,
""
));
std
::
string
(
""
)));
if
(
itr
==
std
::
end
(
stream
->
headers
)
||
(
*
itr
).
first
!=
":authority"
)
{
if
(
itr
==
std
::
end
(
stream
->
headers
)
||
(
*
itr
).
name
!=
":authority"
)
{
itr
=
std
::
lower_bound
(
std
::
begin
(
stream
->
headers
),
itr
=
std
::
lower_bound
(
std
::
begin
(
stream
->
headers
),
std
::
end
(
stream
->
headers
),
std
::
end
(
stream
->
headers
),
std
::
make_pair
(
std
::
string
(
"host"
),
Header
(
"host"
,
""
));
std
::
string
(
""
)));
}
}
auto
nva
=
std
::
vector
<
nghttp2_nv
>
{
auto
nva
=
std
::
vector
<
nghttp2_nv
>
{
http2
::
make_nv_ll
(
":method"
,
"GET"
),
http2
::
make_nv_ll
(
":method"
,
"GET"
),
http2
::
make_nv_ls
(
":path"
,
push_path
),
http2
::
make_nv_ls
(
":path"
,
push_path
),
get_config
()
->
no_tls
?
get_config
()
->
no_tls
?
http2
::
make_nv_ll
(
":scheme"
,
"http"
)
:
http2
::
make_nv_ll
(
":scheme"
,
"http"
)
:
http2
::
make_nv_ll
(
":scheme"
,
"https"
),
http2
::
make_nv_ll
(
":scheme"
,
"https"
),
http2
::
make_nv_ls
(
":authority"
,
(
*
itr
).
second
)
http2
::
make_nv_ls
(
":authority"
,
(
*
itr
).
value
)
};
};
return
nghttp2_submit_push_promise
(
session_
,
NGHTTP2_FLAG_END_HEADERS
,
return
nghttp2_submit_push_promise
(
session_
,
NGHTTP2_FLAG_END_HEADERS
,
stream
->
stream_id
,
nva
.
data
(),
nva
.
size
(),
stream
->
stream_id
,
nva
.
data
(),
nva
.
size
(),
...
@@ -1008,18 +1008,17 @@ void prepare_response(Stream *stream, Http2Handler *hd, bool allow_push = true)
...
@@ -1008,18 +1008,17 @@ void prepare_response(Stream *stream, Http2Handler *hd, bool allow_push = true)
int
rv
;
int
rv
;
auto
url
=
(
*
std
::
lower_bound
(
std
::
begin
(
stream
->
headers
),
auto
url
=
(
*
std
::
lower_bound
(
std
::
begin
(
stream
->
headers
),
std
::
end
(
stream
->
headers
),
std
::
end
(
stream
->
headers
),
std
::
make_pair
(
std
::
string
(
":path"
),
Header
(
":path"
,
""
))).
value
;
std
::
string
()))).
second
;
auto
ims
=
std
::
lower_bound
(
std
::
begin
(
stream
->
headers
),
auto
ims
=
std
::
lower_bound
(
std
::
begin
(
stream
->
headers
),
std
::
end
(
stream
->
headers
),
std
::
end
(
stream
->
headers
),
std
::
make_pair
(
std
::
string
(
"if-modified-since"
),
Header
(
"if-modified-since"
,
""
));
std
::
string
()));
time_t
last_mod
=
0
;
time_t
last_mod
=
0
;
bool
last_mod_found
=
false
;
bool
last_mod_found
=
false
;
if
(
ims
!=
std
::
end
(
stream
->
headers
)
&&
if
(
ims
!=
std
::
end
(
stream
->
headers
)
&&
(
*
ims
).
first
==
"if-modified-since"
)
{
(
*
ims
).
name
==
"if-modified-since"
)
{
last_mod_found
=
true
;
last_mod_found
=
true
;
last_mod
=
util
::
parse_http_date
((
*
ims
).
second
);
last_mod
=
util
::
parse_http_date
((
*
ims
).
value
);
}
}
auto
query_pos
=
url
.
find
(
"?"
);
auto
query_pos
=
url
.
find
(
"?"
);
if
(
query_pos
!=
std
::
string
::
npos
)
{
if
(
query_pos
!=
std
::
string
::
npos
)
{
...
@@ -1078,7 +1077,8 @@ void append_nv(Stream *stream, const std::vector<nghttp2_nv>& nva)
...
@@ -1078,7 +1077,8 @@ void append_nv(Stream *stream, const std::vector<nghttp2_nv>& nva)
{
{
for
(
auto
&
nv
:
nva
)
{
for
(
auto
&
nv
:
nva
)
{
http2
::
split_add_header
(
stream
->
headers
,
http2
::
split_add_header
(
stream
->
headers
,
nv
.
name
,
nv
.
namelen
,
nv
.
value
,
nv
.
valuelen
);
nv
.
name
,
nv
.
namelen
,
nv
.
value
,
nv
.
valuelen
,
nv
.
flags
&
NGHTTP2_NV_FLAG_NO_INDEX
);
}
}
}
}
}
// namespace
}
// namespace
...
@@ -1114,7 +1114,8 @@ int on_header_callback(nghttp2_session *session,
...
@@ -1114,7 +1114,8 @@ int on_header_callback(nghttp2_session *session,
if
(
!
http2
::
check_nv
(
name
,
namelen
,
value
,
valuelen
))
{
if
(
!
http2
::
check_nv
(
name
,
namelen
,
value
,
valuelen
))
{
return
0
;
return
0
;
}
}
http2
::
split_add_header
(
stream
->
headers
,
name
,
namelen
,
value
,
valuelen
);
http2
::
split_add_header
(
stream
->
headers
,
name
,
namelen
,
value
,
valuelen
,
flags
&
NGHTTP2_NV_FLAG_NO_INDEX
);
return
0
;
return
0
;
}
}
}
// namespace
}
// namespace
...
...
src/h2load.cc
View file @
b1edb1f3
...
@@ -792,7 +792,7 @@ int main(int argc, char **argv)
...
@@ -792,7 +792,7 @@ int main(int argc, char **argv)
nva
.
push_back
(
http2
::
make_nv_ls
(
":path"
,
req
));
nva
.
push_back
(
http2
::
make_nv_ls
(
":path"
,
req
));
for
(
auto
&
nv
:
shared_nva
)
{
for
(
auto
&
nv
:
shared_nva
)
{
nva
.
push_back
(
http2
::
make_nv
(
nv
.
first
,
nv
.
second
));
nva
.
push_back
(
http2
::
make_nv
(
nv
.
name
,
nv
.
value
,
false
));
}
}
config
.
nva
.
push_back
(
std
::
move
(
nva
));
config
.
nva
.
push_back
(
std
::
move
(
nva
));
...
@@ -804,12 +804,12 @@ int main(int argc, char **argv)
...
@@ -804,12 +804,12 @@ int main(int argc, char **argv)
cva
.
push_back
(
req
.
c_str
());
cva
.
push_back
(
req
.
c_str
());
for
(
auto
&
nv
:
shared_nva
)
{
for
(
auto
&
nv
:
shared_nva
)
{
if
(
nv
.
first
==
":authority"
)
{
if
(
nv
.
name
==
":authority"
)
{
cva
.
push_back
(
":host"
);
cva
.
push_back
(
":host"
);
}
else
{
}
else
{
cva
.
push_back
(
nv
.
first
.
c_str
());
cva
.
push_back
(
nv
.
name
.
c_str
());
}
}
cva
.
push_back
(
nv
.
second
.
c_str
());
cva
.
push_back
(
nv
.
value
.
c_str
());
}
}
cva
.
push_back
(
":version"
);
cva
.
push_back
(
":version"
);
cva
.
push_back
(
"HTTP/1.1"
);
cva
.
push_back
(
"HTTP/1.1"
);
...
...
src/http2.cc
View file @
b1edb1f3
...
@@ -206,14 +206,14 @@ auto nv_name_less = [](const nghttp2_nv& lhs, const nghttp2_nv& rhs)
...
@@ -206,14 +206,14 @@ auto nv_name_less = [](const nghttp2_nv& lhs, const nghttp2_nv& rhs)
bool
name_less
(
const
Headers
::
value_type
&
lhs
,
bool
name_less
(
const
Headers
::
value_type
&
lhs
,
const
Headers
::
value_type
&
rhs
)
const
Headers
::
value_type
&
rhs
)
{
{
return
lhs
.
first
<
rhs
.
first
;
return
lhs
.
name
<
rhs
.
name
;
}
}
bool
check_http2_headers
(
const
Headers
&
nva
)
bool
check_http2_headers
(
const
Headers
&
nva
)
{
{
for
(
size_t
i
=
0
;
i
<
DISALLOWED_HDLEN
;
++
i
)
{
for
(
size_t
i
=
0
;
i
<
DISALLOWED_HDLEN
;
++
i
)
{
if
(
std
::
binary_search
(
std
::
begin
(
nva
),
std
::
end
(
nva
),
if
(
std
::
binary_search
(
std
::
begin
(
nva
),
std
::
end
(
nva
),
std
::
make_pai
r
(
DISALLOWED_HD
[
i
],
""
),
name_less
))
{
Heade
r
(
DISALLOWED_HD
[
i
],
""
),
name_less
))
{
return
false
;
return
false
;
}
}
}
}
...
@@ -223,7 +223,7 @@ bool check_http2_headers(const Headers& nva)
...
@@ -223,7 +223,7 @@ bool check_http2_headers(const Headers& nva)
void
normalize_headers
(
Headers
&
nva
)
void
normalize_headers
(
Headers
&
nva
)
{
{
for
(
auto
&
kv
:
nva
)
{
for
(
auto
&
kv
:
nva
)
{
util
::
inp_strlower
(
kv
.
first
);
util
::
inp_strlower
(
kv
.
name
);
}
}
std
::
stable_sort
(
std
::
begin
(
nva
),
std
::
end
(
nva
),
name_less
);
std
::
stable_sort
(
std
::
begin
(
nva
),
std
::
end
(
nva
),
name_less
);
}
}
...
@@ -260,20 +260,23 @@ std::vector<nghttp2_nv> sort_nva(const nghttp2_nv *nva, size_t nvlen)
...
@@ -260,20 +260,23 @@ std::vector<nghttp2_nv> sort_nva(const nghttp2_nv *nva, size_t nvlen)
}
}
Headers
::
value_type
to_header
(
const
uint8_t
*
name
,
size_t
namelen
,
Headers
::
value_type
to_header
(
const
uint8_t
*
name
,
size_t
namelen
,
const
uint8_t
*
value
,
size_t
valuelen
)
const
uint8_t
*
value
,
size_t
valuelen
,
bool
no_index
)
{
{
return
std
::
make_pair
(
std
::
string
(
reinterpret_cast
<
const
char
*>
(
name
),
return
Header
(
std
::
string
(
reinterpret_cast
<
const
char
*>
(
name
),
namelen
),
namelen
),
std
::
string
(
reinterpret_cast
<
const
char
*>
(
value
),
std
::
string
(
reinterpret_cast
<
const
char
*>
(
value
),
valuelen
));
valuelen
),
no_index
);
}
}
void
split_add_header
(
Headers
&
nva
,
void
split_add_header
(
Headers
&
nva
,
const
uint8_t
*
name
,
size_t
namelen
,
const
uint8_t
*
name
,
size_t
namelen
,
const
uint8_t
*
value
,
size_t
valuelen
)
const
uint8_t
*
value
,
size_t
valuelen
,
bool
no_index
)
{
{
if
(
valuelen
==
0
)
{
if
(
valuelen
==
0
)
{
nva
.
push_back
(
to_header
(
name
,
namelen
,
value
,
valuelen
));
nva
.
push_back
(
to_header
(
name
,
namelen
,
value
,
valuelen
,
no_index
));
return
;
return
;
}
}
auto
j
=
value
;
auto
j
=
value
;
...
@@ -289,7 +292,7 @@ void split_add_header(Headers& nva,
...
@@ -289,7 +292,7 @@ void split_add_header(Headers& nva,
break
;
break
;
}
}
auto
l
=
std
::
find
(
j
,
end
,
'\0'
);
auto
l
=
std
::
find
(
j
,
end
,
'\0'
);
nva
.
push_back
(
to_header
(
name
,
namelen
,
j
,
l
-
j
));
nva
.
push_back
(
to_header
(
name
,
namelen
,
j
,
l
-
j
,
no_index
));
j
=
l
;
j
=
l
;
}
}
}
}
...
@@ -299,9 +302,9 @@ const Headers::value_type* get_unique_header(const Headers& nva,
...
@@ -299,9 +302,9 @@ const Headers::value_type* get_unique_header(const Headers& nva,
{
{
auto
nv
=
Headers
::
value_type
(
name
,
""
);
auto
nv
=
Headers
::
value_type
(
name
,
""
);
auto
i
=
std
::
lower_bound
(
std
::
begin
(
nva
),
std
::
end
(
nva
),
nv
,
name_less
);
auto
i
=
std
::
lower_bound
(
std
::
begin
(
nva
),
std
::
end
(
nva
),
nv
,
name_less
);
if
(
i
!=
std
::
end
(
nva
)
&&
(
*
i
).
first
==
nv
.
first
)
{
if
(
i
!=
std
::
end
(
nva
)
&&
(
*
i
).
name
==
nv
.
name
)
{
auto
j
=
i
+
1
;
auto
j
=
i
+
1
;
if
(
j
==
std
::
end
(
nva
)
||
(
*
j
).
first
!=
nv
.
first
)
{
if
(
j
==
std
::
end
(
nva
)
||
(
*
j
).
name
!=
nv
.
name
)
{
return
&
(
*
i
);
return
&
(
*
i
);
}
}
}
}
...
@@ -312,7 +315,7 @@ const Headers::value_type* get_header(const Headers& nva, const char *name)
...
@@ -312,7 +315,7 @@ const Headers::value_type* get_header(const Headers& nva, const char *name)
{
{
auto
nv
=
Headers
::
value_type
(
name
,
""
);
auto
nv
=
Headers
::
value_type
(
name
,
""
);
auto
i
=
std
::
lower_bound
(
std
::
begin
(
nva
),
std
::
end
(
nva
),
nv
,
name_less
);
auto
i
=
std
::
lower_bound
(
std
::
begin
(
nva
),
std
::
end
(
nva
),
nv
,
name_less
);
if
(
i
!=
std
::
end
(
nva
)
&&
(
*
i
).
first
==
nv
.
first
)
{
if
(
i
!=
std
::
end
(
nva
)
&&
(
*
i
).
name
==
nv
.
name
)
{
return
&
(
*
i
);
return
&
(
*
i
);
}
}
return
nullptr
;
return
nullptr
;
...
@@ -321,14 +324,14 @@ const Headers::value_type* get_header(const Headers& nva, const char *name)
...
@@ -321,14 +324,14 @@ const Headers::value_type* get_header(const Headers& nva, const char *name)
std
::
string
value_to_str
(
const
Headers
::
value_type
*
nv
)
std
::
string
value_to_str
(
const
Headers
::
value_type
*
nv
)
{
{
if
(
nv
)
{
if
(
nv
)
{
return
nv
->
second
;
return
nv
->
value
;
}
}
return
""
;
return
""
;
}
}
bool
value_lws
(
const
Headers
::
value_type
*
nv
)
bool
value_lws
(
const
Headers
::
value_type
*
nv
)
{
{
return
(
*
nv
).
second
.
find_first_not_of
(
"
\t
"
)
==
std
::
string
::
npos
;
return
(
*
nv
).
value
.
find_first_not_of
(
"
\t
"
)
==
std
::
string
::
npos
;
}
}
bool
non_empty_value
(
const
Headers
::
value_type
*
nv
)
bool
non_empty_value
(
const
Headers
::
value_type
*
nv
)
...
@@ -336,13 +339,18 @@ bool non_empty_value(const Headers::value_type *nv)
...
@@ -336,13 +339,18 @@ bool non_empty_value(const Headers::value_type *nv)
return
nv
&&
!
value_lws
(
nv
);
return
nv
&&
!
value_lws
(
nv
);
}
}
nghttp2_nv
make_nv
(
const
std
::
string
&
name
,
const
std
::
string
&
value
)
nghttp2_nv
make_nv
(
const
std
::
string
&
name
,
const
std
::
string
&
value
,
bool
no_index
)
{
{
uint8_t
flags
;
flags
=
no_index
?
NGHTTP2_NV_FLAG_NO_INDEX
:
NGHTTP2_NV_FLAG_NONE
;
return
{
return
{
(
uint8_t
*
)
name
.
c_str
(),
(
uint8_t
*
)
name
.
c_str
(),
(
uint8_t
*
)
value
.
c_str
(),
(
uint8_t
*
)
value
.
c_str
(),
(
uint16_t
)
name
.
size
(),
(
uint16_t
)
value
.
size
(),
(
uint16_t
)
name
.
size
(),
(
uint16_t
)
value
.
size
(),
NGHTTP2_NV_FLAG_NONE
flags
};
};
}
}
...
@@ -351,12 +359,17 @@ Headers concat_norm_headers(Headers headers)
...
@@ -351,12 +359,17 @@ Headers concat_norm_headers(Headers headers)
auto
res
=
Headers
();
auto
res
=
Headers
();
res
.
reserve
(
headers
.
size
());
res
.
reserve
(
headers
.
size
());
for
(
auto
&
kv
:
headers
)
{
for
(
auto
&
kv
:
headers
)
{
if
(
!
res
.
empty
()
&&
res
.
back
().
first
==
kv
.
first
&&
if
(
!
res
.
empty
()
&&
res
.
back
().
name
==
kv
.
name
&&
kv
.
first
!=
"cookie"
&&
kv
.
first
!=
"set-cookie"
)
{
kv
.
name
!=
"cookie"
&&
kv
.
name
!=
"set-cookie"
)
{
if
(
!
kv
.
second
.
empty
())
{
res
.
back
().
second
.
append
(
1
,
'\0'
);
auto
&
last
=
res
.
back
();
res
.
back
().
second
+=
kv
.
second
;
if
(
!
kv
.
value
.
empty
())
{
last
.
value
.
append
(
1
,
'\0'
);
last
.
value
+=
kv
.
value
;
}
}
// We do ORing nv flags. This is done even if value is empty.
last
.
no_index
|=
kv
.
no_index
;
}
else
{
}
else
{
res
.
push_back
(
std
::
move
(
kv
));
res
.
push_back
(
std
::
move
(
kv
));
}
}
...
@@ -369,10 +382,11 @@ void copy_norm_headers_to_nva
...
@@ -369,10 +382,11 @@ void copy_norm_headers_to_nva
{
{
size_t
i
,
j
;
size_t
i
,
j
;
for
(
i
=
0
,
j
=
0
;
i
<
headers
.
size
()
&&
j
<
IGN_HDLEN
;)
{
for
(
i
=
0
,
j
=
0
;
i
<
headers
.
size
()
&&
j
<
IGN_HDLEN
;)
{
int
rv
=
strcmp
(
headers
[
i
].
first
.
c_str
(),
IGN_HD
[
j
]);
auto
&
kv
=
headers
[
i
];
int
rv
=
strcmp
(
kv
.
name
.
c_str
(),
IGN_HD
[
j
]);
if
(
rv
<
0
)
{
if
(
rv
<
0
)
{
if
(
!
headers
[
i
].
first
.
empty
()
&&
headers
[
i
].
first
.
c_str
()[
0
]
!=
':'
)
{
if
(
!
kv
.
name
.
empty
()
&&
kv
.
name
.
c_str
()[
0
]
!=
':'
)
{
nva
.
push_back
(
make_nv
(
headers
[
i
].
first
,
headers
[
i
].
second
));
nva
.
push_back
(
make_nv
(
kv
.
name
,
kv
.
value
,
kv
.
no_index
));
}
}
++
i
;
++
i
;
}
else
if
(
rv
>
0
)
{
}
else
if
(
rv
>
0
)
{
...
@@ -382,8 +396,9 @@ void copy_norm_headers_to_nva
...
@@ -382,8 +396,9 @@ void copy_norm_headers_to_nva
}
}
}
}
for
(;
i
<
headers
.
size
();
++
i
)
{
for
(;
i
<
headers
.
size
();
++
i
)
{
if
(
!
headers
[
i
].
first
.
empty
()
&&
headers
[
i
].
first
.
c_str
()[
0
]
!=
':'
)
{
auto
&
kv
=
headers
[
i
];
nva
.
push_back
(
make_nv
(
headers
[
i
].
first
,
headers
[
i
].
second
));
if
(
!
kv
.
name
.
empty
()
&&
kv
.
name
.
c_str
()[
0
]
!=
':'
)
{
nva
.
push_back
(
make_nv
(
kv
.
name
,
kv
.
value
,
kv
.
no_index
));
}
}
}
}
}
}
...
@@ -393,14 +408,16 @@ void build_http1_headers_from_norm_headers
...
@@ -393,14 +408,16 @@ void build_http1_headers_from_norm_headers
{
{
size_t
i
,
j
;
size_t
i
,
j
;
for
(
i
=
0
,
j
=
0
;
i
<
headers
.
size
()
&&
j
<
HTTP1_IGN_HDLEN
;)
{
for
(
i
=
0
,
j
=
0
;
i
<
headers
.
size
()
&&
j
<
HTTP1_IGN_HDLEN
;)
{
int
rv
=
strcmp
(
headers
[
i
].
first
.
c_str
(),
HTTP1_IGN_HD
[
j
]);
auto
&
kv
=
headers
[
i
];
auto
rv
=
strcmp
(
kv
.
name
.
c_str
(),
HTTP1_IGN_HD
[
j
]);
if
(
rv
<
0
)
{
if
(
rv
<
0
)
{
if
(
!
headers
[
i
].
first
.
empty
()
&&
headers
[
i
].
first
.
c_str
()[
0
]
!=
':'
)
{
if
(
!
kv
.
name
.
empty
()
&&
kv
.
name
.
c_str
()[
0
]
!=
':'
)
{
hdrs
+=
headers
[
i
].
first
;
hdrs
+=
kv
.
name
;
capitalize
(
hdrs
,
hdrs
.
size
()
-
headers
[
i
].
first
.
size
());
capitalize
(
hdrs
,
hdrs
.
size
()
-
kv
.
name
.
size
());
hdrs
+=
": "
;
hdrs
+=
": "
;
hdrs
+=
headers
[
i
].
second
;
hdrs
+=
kv
.
value
;
sanitize_header_value
(
hdrs
,
hdrs
.
size
()
-
headers
[
i
].
second
.
size
());
sanitize_header_value
(
hdrs
,
hdrs
.
size
()
-
kv
.
value
.
size
());
hdrs
+=
"
\r\n
"
;
hdrs
+=
"
\r\n
"
;
}
}
++
i
;
++
i
;
...
@@ -411,12 +428,14 @@ void build_http1_headers_from_norm_headers
...
@@ -411,12 +428,14 @@ void build_http1_headers_from_norm_headers
}
}
}
}
for
(;
i
<
headers
.
size
();
++
i
)
{
for
(;
i
<
headers
.
size
();
++
i
)
{
if
(
!
headers
[
i
].
first
.
empty
()
&&
headers
[
i
].
first
.
c_str
()[
0
]
!=
':'
)
{
auto
&
kv
=
headers
[
i
];
hdrs
+=
headers
[
i
].
first
;
capitalize
(
hdrs
,
hdrs
.
size
()
-
headers
[
i
].
first
.
size
());
if
(
!
kv
.
name
.
empty
()
&&
kv
.
name
.
c_str
()[
0
]
!=
':'
)
{
hdrs
+=
kv
.
name
;
capitalize
(
hdrs
,
hdrs
.
size
()
-
kv
.
name
.
size
());
hdrs
+=
": "
;
hdrs
+=
": "
;
hdrs
+=
headers
[
i
].
second
;
hdrs
+=
kv
.
value
;
sanitize_header_value
(
hdrs
,
hdrs
.
size
()
-
headers
[
i
].
second
.
size
());
sanitize_header_value
(
hdrs
,
hdrs
.
size
()
-
kv
.
value
.
size
());
hdrs
+=
"
\r\n
"
;
hdrs
+=
"
\r\n
"
;
}
}
}
}
...
@@ -472,9 +491,9 @@ void dump_nv(FILE *out, const nghttp2_nv *nva, size_t nvlen)
...
@@ -472,9 +491,9 @@ void dump_nv(FILE *out, const nghttp2_nv *nva, size_t nvlen)
void
dump_nv
(
FILE
*
out
,
const
Headers
&
nva
)
void
dump_nv
(
FILE
*
out
,
const
Headers
&
nva
)
{
{
for
(
auto
&
nv
:
nva
)
{
for
(
auto
&
nv
:
nva
)
{
fwrite
(
nv
.
first
.
c_str
(),
nv
.
first
.
size
(),
1
,
out
);
fwrite
(
nv
.
name
.
c_str
(),
nv
.
name
.
size
(),
1
,
out
);
fwrite
(
": "
,
2
,
1
,
out
);
fwrite
(
": "
,
2
,
1
,
out
);
fwrite
(
nv
.
second
.
c_str
(),
nv
.
second
.
size
(),
1
,
out
);
fwrite
(
nv
.
value
.
c_str
(),
nv
.
value
.
size
(),
1
,
out
);
fwrite
(
"
\n
"
,
1
,
1
,
out
);
fwrite
(
"
\n
"
,
1
,
1
,
out
);
}
}
fwrite
(
"
\n
"
,
1
,
1
,
out
);
fwrite
(
"
\n
"
,
1
,
1
,
out
);
...
...
src/http2.h
View file @
b1edb1f3
...
@@ -38,7 +38,33 @@
...
@@ -38,7 +38,33 @@
namespace
nghttp2
{
namespace
nghttp2
{
typedef
std
::
vector
<
std
::
pair
<
std
::
string
,
std
::
string
>>
Headers
;
struct
Header
{
Header
(
std
::
string
name
,
std
::
string
value
,
bool
no_index
=
false
)
:
name
(
std
::
move
(
name
)),
value
(
std
::
move
(
value
)),
no_index
(
no_index
)
{}
Header
()
:
no_index
(
false
)
{}
bool
operator
==
(
const
Header
&
other
)
const
{
return
name
==
other
.
name
&&
value
==
other
.
value
;
}
bool
operator
<
(
const
Header
&
rhs
)
const
{
return
name
<
rhs
.
name
||
(
name
==
rhs
.
name
&&
value
<
rhs
.
value
);
}
std
::
string
name
;
std
::
string
value
;
bool
no_index
;
};
typedef
std
::
vector
<
Header
>
Headers
;
namespace
http2
{
namespace
http2
{
...
@@ -75,15 +101,18 @@ bool name_less(const Headers::value_type& lhs, const Headers::value_type& rhs);
...
@@ -75,15 +101,18 @@ bool name_less(const Headers::value_type& lhs, const Headers::value_type& rhs);
void
normalize_headers
(
Headers
&
nva
);
void
normalize_headers
(
Headers
&
nva
);
Headers
::
value_type
to_header
(
const
uint8_t
*
name
,
size_t
namelen
,
Headers
::
value_type
to_header
(
const
uint8_t
*
name
,
size_t
namelen
,
const
uint8_t
*
value
,
size_t
valuelen
);
const
uint8_t
*
value
,
size_t
valuelen
,
bool
no_index
);
// Add name/value pairs to |nva|. The name is given in the |name| with
// Add name/value pairs to |nva|. The name is given in the |name| with
// |namelen| bytes. This function inspects the |value| and split it
// |namelen| bytes. This function inspects the |value| and split it
// using '\0' as delimiter. Each token is added to the |nva| with the
// using '\0' as delimiter. Each token is added to the |nva| with the
// name |name|.
// name |name|. If |no_index| is true, this name/value pair won't be
// indexed when it is forwarded to the next hop.
void
split_add_header
(
Headers
&
nva
,
void
split_add_header
(
Headers
&
nva
,
const
uint8_t
*
name
,
size_t
namelen
,
const
uint8_t
*
name
,
size_t
namelen
,
const
uint8_t
*
value
,
size_t
valuelen
);
const
uint8_t
*
value
,
size_t
valuelen
,
bool
no_index
);
// Returns sorted |nva| with |nvlen| elements. The headers are sorted
// Returns sorted |nva| with |nvlen| elements. The headers are sorted
// by name only and not necessarily stable. In addition to the
// by name only and not necessarily stable. In addition to the
...
@@ -122,8 +151,10 @@ Headers concat_norm_headers(Headers headers);
...
@@ -122,8 +151,10 @@ Headers concat_norm_headers(Headers headers);
// Creates nghttp2_nv using |name| and |value| and returns it. The
// Creates nghttp2_nv using |name| and |value| and returns it. The
// returned value only references the data pointer to name.c_str() and
// returned value only references the data pointer to name.c_str() and
// value.c_str().
// value.c_str(). If |no_index| is true, nghttp2_nv flags member has
nghttp2_nv
make_nv
(
const
std
::
string
&
name
,
const
std
::
string
&
value
);
// NGHTTP2_NV_FLAG_NO_INDEX flag set.
nghttp2_nv
make_nv
(
const
std
::
string
&
name
,
const
std
::
string
&
value
,
bool
no_index
);
// Create nghttp2_nv from string literal |name| and |value|.
// Create nghttp2_nv from string literal |name| and |value|.
template
<
size_t
N
,
size_t
M
>
template
<
size_t
N
,
size_t
M
>
...
...
src/http2_test.cc
View file @
b1edb1f3
...
@@ -44,13 +44,12 @@ using namespace nghttp2;
...
@@ -44,13 +44,12 @@ using namespace nghttp2;
namespace
shrpx
{
namespace
shrpx
{
namespace
{
namespace
{
void
check_nv
(
const
std
::
pair
<
std
::
string
,
std
::
string
>&
a
,
void
check_nv
(
const
Header
&
a
,
const
nghttp2_nv
*
b
)
const
nghttp2_nv
*
b
)
{
{
CU_ASSERT
(
a
.
first
.
size
()
==
b
->
namelen
);
CU_ASSERT
(
a
.
name
.
size
()
==
b
->
namelen
);
CU_ASSERT
(
a
.
second
.
size
()
==
b
->
valuelen
);
CU_ASSERT
(
a
.
value
.
size
()
==
b
->
valuelen
);
CU_ASSERT
(
memcmp
(
a
.
first
.
c_str
(),
b
->
name
,
b
->
namelen
)
==
0
);
CU_ASSERT
(
memcmp
(
a
.
name
.
c_str
(),
b
->
name
,
b
->
namelen
)
==
0
);
CU_ASSERT
(
memcmp
(
a
.
second
.
c_str
(),
b
->
value
,
b
->
valuelen
)
==
0
);
CU_ASSERT
(
memcmp
(
a
.
value
.
c_str
(),
b
->
value
,
b
->
valuelen
)
==
0
);
}
}
}
// namespace
}
// namespace
...
@@ -78,7 +77,7 @@ void test_http2_split_add_header(void)
...
@@ -78,7 +77,7 @@ void test_http2_split_add_header(void)
const
uint8_t
concatval
[]
=
{
'4'
,
0x00
,
0x00
,
'6'
,
0x00
,
'5'
,
'9'
,
0x00
};
const
uint8_t
concatval
[]
=
{
'4'
,
0x00
,
0x00
,
'6'
,
0x00
,
'5'
,
'9'
,
0x00
};
auto
nva
=
Headers
();
auto
nva
=
Headers
();
http2
::
split_add_header
(
nva
,
(
const
uint8_t
*
)
"delta"
,
5
,
http2
::
split_add_header
(
nva
,
(
const
uint8_t
*
)
"delta"
,
5
,
concatval
,
sizeof
(
concatval
));
concatval
,
sizeof
(
concatval
)
,
false
);
CU_ASSERT
(
Headers
::
value_type
(
"delta"
,
"4"
)
==
nva
[
0
]);
CU_ASSERT
(
Headers
::
value_type
(
"delta"
,
"4"
)
==
nva
[
0
]);
CU_ASSERT
(
Headers
::
value_type
(
"delta"
,
"6"
)
==
nva
[
1
]);
CU_ASSERT
(
Headers
::
value_type
(
"delta"
,
"6"
)
==
nva
[
1
]);
CU_ASSERT
(
Headers
::
value_type
(
"delta"
,
"59"
)
==
nva
[
2
]);
CU_ASSERT
(
Headers
::
value_type
(
"delta"
,
"59"
)
==
nva
[
2
]);
...
@@ -86,14 +85,16 @@ void test_http2_split_add_header(void)
...
@@ -86,14 +85,16 @@ void test_http2_split_add_header(void)
nva
.
clear
();
nva
.
clear
();
http2
::
split_add_header
(
nva
,
(
const
uint8_t
*
)
"alpha"
,
5
,
http2
::
split_add_header
(
nva
,
(
const
uint8_t
*
)
"alpha"
,
5
,
(
const
uint8_t
*
)
"123"
,
3
);
(
const
uint8_t
*
)
"123"
,
3
,
false
);
CU_ASSERT
(
Headers
::
value_type
(
"alpha"
,
"123"
)
==
nva
[
0
]);
CU_ASSERT
(
Headers
::
value_type
(
"alpha"
,
"123"
)
==
nva
[
0
]);
CU_ASSERT
(
!
nva
[
0
].
no_index
);
nva
.
clear
();
nva
.
clear
();
http2
::
split_add_header
(
nva
,
(
const
uint8_t
*
)
"alpha"
,
5
,
http2
::
split_add_header
(
nva
,
(
const
uint8_t
*
)
"alpha"
,
5
,
(
const
uint8_t
*
)
""
,
0
);
(
const
uint8_t
*
)
""
,
0
,
true
);
CU_ASSERT
(
Headers
::
value_type
(
"alpha"
,
""
)
==
nva
[
0
]);
CU_ASSERT
(
Headers
::
value_type
(
"alpha"
,
""
)
==
nva
[
0
]);
CU_ASSERT
(
nva
[
0
].
no_index
);
}
}
void
test_http2_check_http2_headers
(
void
)
void
test_http2_check_http2_headers
(
void
)
...
@@ -133,7 +134,7 @@ void test_http2_get_unique_header(void)
...
@@ -133,7 +134,7 @@ void test_http2_get_unique_header(void)
const
Headers
::
value_type
*
rv
;
const
Headers
::
value_type
*
rv
;
rv
=
http2
::
get_unique_header
(
nva
,
"delta"
);
rv
=
http2
::
get_unique_header
(
nva
,
"delta"
);
CU_ASSERT
(
rv
!=
nullptr
);
CU_ASSERT
(
rv
!=
nullptr
);
CU_ASSERT
(
"delta"
==
rv
->
first
);
CU_ASSERT
(
"delta"
==
rv
->
name
);
rv
=
http2
::
get_unique_header
(
nva
,
"bravo"
);
rv
=
http2
::
get_unique_header
(
nva
,
"bravo"
);
CU_ASSERT
(
rv
==
nullptr
);
CU_ASSERT
(
rv
==
nullptr
);
...
@@ -155,11 +156,11 @@ void test_http2_get_header(void)
...
@@ -155,11 +156,11 @@ void test_http2_get_header(void)
const
Headers
::
value_type
*
rv
;
const
Headers
::
value_type
*
rv
;
rv
=
http2
::
get_header
(
nva
,
"delta"
);
rv
=
http2
::
get_header
(
nva
,
"delta"
);
CU_ASSERT
(
rv
!=
nullptr
);
CU_ASSERT
(
rv
!=
nullptr
);
CU_ASSERT
(
"delta"
==
rv
->
first
);
CU_ASSERT
(
"delta"
==
rv
->
name
);
rv
=
http2
::
get_header
(
nva
,
"bravo"
);
rv
=
http2
::
get_header
(
nva
,
"bravo"
);
CU_ASSERT
(
rv
!=
nullptr
);
CU_ASSERT
(
rv
!=
nullptr
);
CU_ASSERT
(
"bravo"
==
rv
->
first
);
CU_ASSERT
(
"bravo"
==
rv
->
name
);
rv
=
http2
::
get_header
(
nva
,
"foxtrot"
);
rv
=
http2
::
get_header
(
nva
,
"foxtrot"
);
CU_ASSERT
(
rv
==
nullptr
);
CU_ASSERT
(
rv
==
nullptr
);
...
@@ -182,8 +183,8 @@ void test_http2_value_lws(void)
...
@@ -182,8 +183,8 @@ void test_http2_value_lws(void)
}
}
namespace
{
namespace
{
auto
headers
=
std
::
vector
<
std
::
pair
<
std
::
string
,
std
::
string
>>
auto
headers
=
Headers
{{
"alpha"
,
"0"
},
{{
"alpha"
,
"0"
,
true
},
{
"bravo"
,
"1"
},
{
"bravo"
,
"1"
},
{
"connection"
,
"2"
},
{
"connection"
,
"2"
},
{
"connection"
,
"3"
},
{
"connection"
,
"3"
},
...
@@ -207,7 +208,7 @@ void test_http2_concat_norm_headers(void)
...
@@ -207,7 +208,7 @@ void test_http2_concat_norm_headers(void)
hds
.
emplace_back
(
"set-cookie"
,
"buzz"
);
hds
.
emplace_back
(
"set-cookie"
,
"buzz"
);
auto
res
=
http2
::
concat_norm_headers
(
hds
);
auto
res
=
http2
::
concat_norm_headers
(
hds
);
CU_ASSERT
(
14
==
res
.
size
());
CU_ASSERT
(
14
==
res
.
size
());
CU_ASSERT
(
std
::
string
(
"2"
)
+
'\0'
+
std
::
string
(
"3"
)
==
res
[
2
].
second
);
CU_ASSERT
(
std
::
string
(
"2"
)
+
'\0'
+
std
::
string
(
"3"
)
==
res
[
2
].
value
);
}
}
void
test_http2_copy_norm_headers_to_nva
(
void
)
void
test_http2_copy_norm_headers_to_nva
(
void
)
...
@@ -218,6 +219,12 @@ void test_http2_copy_norm_headers_to_nva(void)
...
@@ -218,6 +219,12 @@ void test_http2_copy_norm_headers_to_nva(void)
auto
ans
=
std
::
vector
<
int
>
{
0
,
1
,
4
,
6
,
7
,
12
};
auto
ans
=
std
::
vector
<
int
>
{
0
,
1
,
4
,
6
,
7
,
12
};
for
(
size_t
i
=
0
;
i
<
ans
.
size
();
++
i
)
{
for
(
size_t
i
=
0
;
i
<
ans
.
size
();
++
i
)
{
check_nv
(
headers
[
ans
[
i
]],
&
nva
[
i
]);
check_nv
(
headers
[
ans
[
i
]],
&
nva
[
i
]);
if
(
ans
[
i
]
==
0
)
{
CU_ASSERT
(
nva
[
i
].
flags
&
NGHTTP2_NV_FLAG_NO_INDEX
);
}
else
{
CU_ASSERT
(
NGHTTP2_NV_FLAG_NONE
==
nva
[
i
].
flags
);
}
}
}
}
}
...
...
src/nghttp.cc
View file @
b1edb1f3
...
@@ -921,7 +921,7 @@ int submit_request
...
@@ -921,7 +921,7 @@ int submit_request
{
{
auto
path
=
req
->
make_reqpath
();
auto
path
=
req
->
make_reqpath
();
auto
scheme
=
util
::
get_uri_field
(
req
->
uri
.
c_str
(),
req
->
u
,
UF_SCHEMA
);
auto
scheme
=
util
::
get_uri_field
(
req
->
uri
.
c_str
(),
req
->
u
,
UF_SCHEMA
);
auto
build_headers
=
std
::
vector
<
std
::
pair
<
std
::
string
,
std
::
string
>>
auto
build_headers
=
Headers
{{
":method"
,
req
->
data_prd
?
"POST"
:
"GET"
},
{{
":method"
,
req
->
data_prd
?
"POST"
:
"GET"
},
{
":path"
,
path
},
{
":path"
,
path
},
{
":scheme"
,
scheme
},
{
":scheme"
,
scheme
},
...
@@ -942,27 +942,30 @@ int submit_request
...
@@ -942,27 +942,30 @@ int submit_request
for
(
auto
&
kv
:
headers
)
{
for
(
auto
&
kv
:
headers
)
{
size_t
i
;
size_t
i
;
for
(
i
=
0
;
i
<
num_initial_headers
;
++
i
)
{
for
(
i
=
0
;
i
<
num_initial_headers
;
++
i
)
{
if
(
util
::
strieq
(
kv
.
first
,
build_headers
[
i
].
first
))
{
if
(
util
::
strieq
(
kv
.
first
,
build_headers
[
i
].
name
))
{
build_headers
[
i
].
second
=
kv
.
second
;
build_headers
[
i
].
value
=
kv
.
second
;
break
;
break
;
}
}
}
}
if
(
i
<
num_initial_headers
)
{
if
(
i
<
num_initial_headers
)
{
continue
;
continue
;
}
}
build_headers
.
push_back
(
kv
);
build_headers
.
emplace_back
(
kv
.
first
,
kv
.
second
);
}
}
std
::
stable_sort
(
std
::
begin
(
build_headers
),
std
::
end
(
build_headers
),
std
::
stable_sort
(
std
::
begin
(
build_headers
),
std
::
end
(
build_headers
),
[](
const
std
::
pair
<
std
::
string
,
std
::
string
>
&
lhs
,
[](
const
Headers
::
value_type
&
lhs
,
const
std
::
pair
<
std
::
string
,
std
::
string
>
&
rhs
)
const
Headers
::
value_type
&
rhs
)
{
{
return
lhs
.
first
<
rhs
.
first
;
return
lhs
.
name
<
rhs
.
name
;
});
});
build_headers
=
http2
::
concat_norm_headers
(
std
::
move
(
build_headers
));
build_headers
=
http2
::
concat_norm_headers
(
std
::
move
(
build_headers
));
auto
nva
=
std
::
vector
<
nghttp2_nv
>
();
auto
nva
=
std
::
vector
<
nghttp2_nv
>
();
nva
.
reserve
(
build_headers
.
size
());
nva
.
reserve
(
build_headers
.
size
());
for
(
auto
&
kv
:
build_headers
)
{
for
(
auto
&
kv
:
build_headers
)
{
nva
.
push_back
(
http2
::
make_nv
(
kv
.
first
,
kv
.
second
));
nva
.
push_back
(
http2
::
make_nv
(
kv
.
name
,
kv
.
value
,
false
));
}
}
auto
rv
=
nghttp2_submit_request
(
client
->
session
,
&
req
->
pri_spec
,
auto
rv
=
nghttp2_submit_request
(
client
->
session
,
&
req
->
pri_spec
,
...
@@ -1157,13 +1160,13 @@ void check_response_header(nghttp2_session *session, Request* req)
...
@@ -1157,13 +1160,13 @@ void check_response_header(nghttp2_session *session, Request* req)
{
{
bool
gzip
=
false
;
bool
gzip
=
false
;
for
(
auto
&
nv
:
req
->
res_nva
)
{
for
(
auto
&
nv
:
req
->
res_nva
)
{
if
(
"content-encoding"
==
nv
.
first
)
{
if
(
"content-encoding"
==
nv
.
name
)
{
gzip
=
util
::
strieq
(
"gzip"
,
nv
.
second
)
||
gzip
=
util
::
strieq
(
"gzip"
,
nv
.
value
)
||
util
::
strieq
(
"deflate"
,
nv
.
second
);
util
::
strieq
(
"deflate"
,
nv
.
value
);
continue
;
continue
;
}
}
if
(
":status"
==
nv
.
first
)
{
if
(
":status"
==
nv
.
name
)
{
req
->
status
.
assign
(
nv
.
second
);
req
->
status
.
assign
(
nv
.
value
);
}
}
}
}
if
(
gzip
)
{
if
(
gzip
)
{
...
@@ -1228,7 +1231,8 @@ int on_header_callback(nghttp2_session *session,
...
@@ -1228,7 +1231,8 @@ int on_header_callback(nghttp2_session *session,
if
(
!
req
)
{
if
(
!
req
)
{
break
;
break
;
}
}
http2
::
split_add_header
(
req
->
res_nva
,
name
,
namelen
,
value
,
valuelen
);
http2
::
split_add_header
(
req
->
res_nva
,
name
,
namelen
,
value
,
valuelen
,
flags
&
NGHTTP2_NV_FLAG_NO_INDEX
);
break
;
break
;
}
}
case
NGHTTP2_PUSH_PROMISE
:
{
case
NGHTTP2_PUSH_PROMISE
:
{
...
@@ -1237,7 +1241,8 @@ int on_header_callback(nghttp2_session *session,
...
@@ -1237,7 +1241,8 @@ int on_header_callback(nghttp2_session *session,
if
(
!
req
)
{
if
(
!
req
)
{
break
;
break
;
}
}
http2
::
split_add_header
(
req
->
push_req_nva
,
name
,
namelen
,
value
,
valuelen
);
http2
::
split_add_header
(
req
->
push_req_nva
,
name
,
namelen
,
value
,
valuelen
,
flags
&
NGHTTP2_NV_FLAG_NO_INDEX
);
break
;
break
;
}
}
}
}
...
@@ -1284,20 +1289,20 @@ int on_frame_recv_callback2
...
@@ -1284,20 +1289,20 @@ int on_frame_recv_callback2
}
}
std
::
string
scheme
,
authority
,
method
,
path
;
std
::
string
scheme
,
authority
,
method
,
path
;
for
(
auto
&
nv
:
req
->
push_req_nva
)
{
for
(
auto
&
nv
:
req
->
push_req_nva
)
{
if
(
nv
.
first
==
":scheme"
)
{
if
(
nv
.
name
==
":scheme"
)
{
scheme
=
nv
.
second
;
scheme
=
nv
.
value
;
continue
;
continue
;
}
}
if
(
nv
.
first
==
":authority"
||
nv
.
first
==
"host"
)
{
if
(
nv
.
name
==
":authority"
||
nv
.
name
==
"host"
)
{
authority
=
nv
.
second
;
authority
=
nv
.
value
;
continue
;
continue
;
}
}
if
(
nv
.
first
==
":method"
)
{
if
(
nv
.
name
==
":method"
)
{
method
=
nv
.
second
;
method
=
nv
.
value
;
continue
;
continue
;
}
}
if
(
nv
.
first
==
":path"
)
{
if
(
nv
.
name
==
":path"
)
{
path
=
nv
.
second
;
path
=
nv
.
value
;
continue
;
continue
;
}
}
}
}
...
...
src/shrpx_downstream.cc
View file @
b1edb1f3
...
@@ -121,8 +121,8 @@ namespace {
...
@@ -121,8 +121,8 @@ namespace {
void
check_header_field
(
bool
*
result
,
const
Headers
::
value_type
&
item
,
void
check_header_field
(
bool
*
result
,
const
Headers
::
value_type
&
item
,
const
char
*
name
,
const
char
*
value
)
const
char
*
name
,
const
char
*
value
)
{
{
if
(
util
::
strieq
(
item
.
first
.
c_str
(),
name
))
{
if
(
util
::
strieq
(
item
.
name
.
c_str
(),
name
))
{
if
(
util
::
strifind
(
item
.
second
.
c_str
(),
value
))
{
if
(
util
::
strifind
(
item
.
value
.
c_str
(),
value
))
{
*
result
=
true
;
*
result
=
true
;
}
}
}
}
...
@@ -150,8 +150,8 @@ Headers::const_iterator get_norm_header(const Headers& headers,
...
@@ -150,8 +150,8 @@ Headers::const_iterator get_norm_header(const Headers& headers,
const
std
::
string
&
name
)
const
std
::
string
&
name
)
{
{
auto
i
=
std
::
lower_bound
(
std
::
begin
(
headers
),
std
::
end
(
headers
),
auto
i
=
std
::
lower_bound
(
std
::
begin
(
headers
),
std
::
end
(
headers
),
std
::
make_pai
r
(
name
,
""
),
http2
::
name_less
);
Heade
r
(
name
,
""
),
http2
::
name_less
);
if
(
i
!=
std
::
end
(
headers
)
&&
(
*
i
).
first
==
name
)
{
if
(
i
!=
std
::
end
(
headers
)
&&
(
*
i
).
name
==
name
)
{
return
i
;
return
i
;
}
}
return
std
::
end
(
headers
);
return
std
::
end
(
headers
);
...
@@ -162,8 +162,8 @@ namespace {
...
@@ -162,8 +162,8 @@ namespace {
Headers
::
iterator
get_norm_header
(
Headers
&
headers
,
const
std
::
string
&
name
)
Headers
::
iterator
get_norm_header
(
Headers
&
headers
,
const
std
::
string
&
name
)
{
{
auto
i
=
std
::
lower_bound
(
std
::
begin
(
headers
),
std
::
end
(
headers
),
auto
i
=
std
::
lower_bound
(
std
::
begin
(
headers
),
std
::
end
(
headers
),
std
::
make_pai
r
(
name
,
""
),
http2
::
name_less
);
Heade
r
(
name
,
""
),
http2
::
name_less
);
if
(
i
!=
std
::
end
(
headers
)
&&
(
*
i
).
first
==
name
)
{
if
(
i
!=
std
::
end
(
headers
)
&&
(
*
i
).
name
==
name
)
{
return
i
;
return
i
;
}
}
return
std
::
end
(
headers
);
return
std
::
end
(
headers
);
...
@@ -180,12 +180,12 @@ void Downstream::assemble_request_cookie()
...
@@ -180,12 +180,12 @@ void Downstream::assemble_request_cookie()
std
::
string
&
cookie
=
assembled_request_cookie_
;
std
::
string
&
cookie
=
assembled_request_cookie_
;
cookie
=
""
;
cookie
=
""
;
for
(
auto
&
kv
:
request_headers_
)
{
for
(
auto
&
kv
:
request_headers_
)
{
if
(
util
::
strieq
(
"cookie"
,
kv
.
first
.
c_str
()))
{
if
(
util
::
strieq
(
"cookie"
,
kv
.
name
.
c_str
()))
{
auto
end
=
kv
.
second
.
find_last_not_of
(
" ;"
);
auto
end
=
kv
.
value
.
find_last_not_of
(
" ;"
);
if
(
end
==
std
::
string
::
npos
)
{
if
(
end
==
std
::
string
::
npos
)
{
cookie
+=
kv
.
second
;
cookie
+=
kv
.
value
;
}
else
{
}
else
{
cookie
.
append
(
std
::
begin
(
kv
.
second
),
std
::
begin
(
kv
.
second
)
+
end
+
1
);
cookie
.
append
(
std
::
begin
(
kv
.
value
),
std
::
begin
(
kv
.
value
)
+
end
+
1
);
}
}
cookie
+=
"; "
;
cookie
+=
"; "
;
}
}
...
@@ -199,19 +199,19 @@ void Downstream::crumble_request_cookie()
...
@@ -199,19 +199,19 @@ void Downstream::crumble_request_cookie()
{
{
Headers
cookie_hdrs
;
Headers
cookie_hdrs
;
for
(
auto
&
kv
:
request_headers_
)
{
for
(
auto
&
kv
:
request_headers_
)
{
if
(
util
::
strieq
(
"cookie"
,
kv
.
first
.
c_str
()))
{
if
(
util
::
strieq
(
"cookie"
,
kv
.
name
.
c_str
()))
{
size_t
last
=
kv
.
second
.
size
();
size_t
last
=
kv
.
value
.
size
();
size_t
num
=
0
;
size_t
num
=
0
;
std
::
string
rep_cookie
;
std
::
string
rep_cookie
;
for
(
size_t
j
=
0
;
j
<
last
;)
{
for
(
size_t
j
=
0
;
j
<
last
;)
{
j
=
kv
.
second
.
find_first_not_of
(
"
\t
;"
,
j
);
j
=
kv
.
value
.
find_first_not_of
(
"
\t
;"
,
j
);
if
(
j
==
std
::
string
::
npos
)
{
if
(
j
==
std
::
string
::
npos
)
{
break
;
break
;
}
}
auto
first
=
j
;
auto
first
=
j
;
j
=
kv
.
second
.
find
(
';'
,
j
);
j
=
kv
.
value
.
find
(
';'
,
j
);
if
(
j
==
std
::
string
::
npos
)
{
if
(
j
==
std
::
string
::
npos
)
{
j
=
last
;
j
=
last
;
}
}
...
@@ -220,15 +220,16 @@ void Downstream::crumble_request_cookie()
...
@@ -220,15 +220,16 @@ void Downstream::crumble_request_cookie()
if
(
first
==
0
&&
j
==
last
)
{
if
(
first
==
0
&&
j
==
last
)
{
break
;
break
;
}
}
rep_cookie
=
kv
.
second
.
substr
(
first
,
j
-
first
);
rep_cookie
=
kv
.
value
.
substr
(
first
,
j
-
first
);
}
else
{
}
else
{
cookie_hdrs
.
push_back
cookie_hdrs
.
push_back
(
std
::
make_pair
(
"cookie"
,
kv
.
second
.
substr
(
first
,
j
-
first
)));
(
Header
(
"cookie"
,
kv
.
value
.
substr
(
first
,
j
-
first
),
kv
.
no_index
));
}
}
++
num
;
++
num
;
}
}
if
(
num
>
0
)
{
if
(
num
>
0
)
{
kv
.
second
=
std
::
move
(
rep_cookie
);
kv
.
value
=
std
::
move
(
rep_cookie
);
}
}
}
}
}
}
...
@@ -269,17 +270,19 @@ void Downstream::set_last_request_header_value(std::string value)
...
@@ -269,17 +270,19 @@ void Downstream::set_last_request_header_value(std::string value)
request_header_key_prev_
=
false
;
request_header_key_prev_
=
false
;
request_headers_sum_
+=
value
.
size
();
request_headers_sum_
+=
value
.
size
();
Headers
::
value_type
&
item
=
request_headers_
.
back
();
Headers
::
value_type
&
item
=
request_headers_
.
back
();
item
.
second
=
std
::
move
(
value
);
item
.
value
=
std
::
move
(
value
);
check_transfer_encoding_chunked
(
&
chunked_request_
,
item
);
check_transfer_encoding_chunked
(
&
chunked_request_
,
item
);
check_expect_100_continue
(
&
request_expect_100_continue_
,
item
);
check_expect_100_continue
(
&
request_expect_100_continue_
,
item
);
}
}
void
Downstream
::
split_add_request_header
void
Downstream
::
split_add_request_header
(
const
uint8_t
*
name
,
size_t
namelen
,
(
const
uint8_t
*
name
,
size_t
namelen
,
const
uint8_t
*
value
,
size_t
valuelen
)
const
uint8_t
*
value
,
size_t
valuelen
,
bool
no_index
)
{
{
request_headers_sum_
+=
namelen
+
valuelen
;
request_headers_sum_
+=
namelen
+
valuelen
;
http2
::
split_add_header
(
request_headers_
,
name
,
namelen
,
value
,
valuelen
);
http2
::
split_add_header
(
request_headers_
,
name
,
namelen
,
value
,
valuelen
,
no_index
);
}
}
bool
Downstream
::
get_request_header_key_prev
()
const
bool
Downstream
::
get_request_header_key_prev
()
const
...
@@ -292,7 +295,7 @@ void Downstream::append_last_request_header_key(const char *data, size_t len)
...
@@ -292,7 +295,7 @@ void Downstream::append_last_request_header_key(const char *data, size_t len)
assert
(
request_header_key_prev_
);
assert
(
request_header_key_prev_
);
request_headers_sum_
+=
len
;
request_headers_sum_
+=
len
;
auto
&
item
=
request_headers_
.
back
();
auto
&
item
=
request_headers_
.
back
();
item
.
first
.
append
(
data
,
len
);
item
.
name
.
append
(
data
,
len
);
}
}
void
Downstream
::
append_last_request_header_value
(
const
char
*
data
,
size_t
len
)
void
Downstream
::
append_last_request_header_value
(
const
char
*
data
,
size_t
len
)
...
@@ -300,7 +303,7 @@ void Downstream::append_last_request_header_value(const char *data, size_t len)
...
@@ -300,7 +303,7 @@ void Downstream::append_last_request_header_value(const char *data, size_t len)
assert
(
!
request_header_key_prev_
);
assert
(
!
request_header_key_prev_
);
request_headers_sum_
+=
len
;
request_headers_sum_
+=
len
;
auto
&
item
=
request_headers_
.
back
();
auto
&
item
=
request_headers_
.
back
();
item
.
second
.
append
(
data
,
len
);
item
.
value
.
append
(
data
,
len
);
}
}
size_t
Downstream
::
get_request_headers_sum
()
const
size_t
Downstream
::
get_request_headers_sum
()
const
...
@@ -498,14 +501,14 @@ void Downstream::rewrite_norm_location_response_header
...
@@ -498,14 +501,14 @@ void Downstream::rewrite_norm_location_response_header
}
}
http_parser_url
u
;
http_parser_url
u
;
memset
(
&
u
,
0
,
sizeof
(
u
));
memset
(
&
u
,
0
,
sizeof
(
u
));
int
rv
=
http_parser_parse_url
((
*
hd
).
second
.
c_str
(),
(
*
hd
).
second
.
size
(),
int
rv
=
http_parser_parse_url
((
*
hd
).
value
.
c_str
(),
(
*
hd
).
value
.
size
(),
0
,
&
u
);
0
,
&
u
);
if
(
rv
!=
0
)
{
if
(
rv
!=
0
)
{
return
;
return
;
}
}
std
::
string
new_uri
;
std
::
string
new_uri
;
if
(
!
request_http2_authority_
.
empty
())
{
if
(
!
request_http2_authority_
.
empty
())
{
new_uri
=
http2
::
rewrite_location_uri
((
*
hd
).
second
,
u
,
new_uri
=
http2
::
rewrite_location_uri
((
*
hd
).
value
,
u
,
request_http2_authority_
,
request_http2_authority_
,
upstream_scheme
,
upstream_port
);
upstream_scheme
,
upstream_port
);
}
}
...
@@ -514,11 +517,11 @@ void Downstream::rewrite_norm_location_response_header
...
@@ -514,11 +517,11 @@ void Downstream::rewrite_norm_location_response_header
if
(
host
==
std
::
end
(
request_headers_
))
{
if
(
host
==
std
::
end
(
request_headers_
))
{
return
;
return
;
}
}
new_uri
=
http2
::
rewrite_location_uri
((
*
hd
).
second
,
u
,
(
*
host
).
second
,
new_uri
=
http2
::
rewrite_location_uri
((
*
hd
).
value
,
u
,
(
*
host
).
value
,
upstream_scheme
,
upstream_port
);
upstream_scheme
,
upstream_port
);
}
}
if
(
!
new_uri
.
empty
())
{
if
(
!
new_uri
.
empty
())
{
(
*
hd
).
second
=
std
::
move
(
new_uri
);
(
*
hd
).
value
=
std
::
move
(
new_uri
);
}
}
}
}
...
@@ -536,16 +539,18 @@ void Downstream::set_last_response_header_value(std::string value)
...
@@ -536,16 +539,18 @@ void Downstream::set_last_response_header_value(std::string value)
response_header_key_prev_
=
false
;
response_header_key_prev_
=
false
;
response_headers_sum_
+=
value
.
size
();
response_headers_sum_
+=
value
.
size
();
auto
&
item
=
response_headers_
.
back
();
auto
&
item
=
response_headers_
.
back
();
item
.
second
=
std
::
move
(
value
);
item
.
value
=
std
::
move
(
value
);
check_transfer_encoding_chunked
(
&
chunked_response_
,
item
);
check_transfer_encoding_chunked
(
&
chunked_response_
,
item
);
}
}
void
Downstream
::
split_add_response_header
void
Downstream
::
split_add_response_header
(
const
uint8_t
*
name
,
size_t
namelen
,
(
const
uint8_t
*
name
,
size_t
namelen
,
const
uint8_t
*
value
,
size_t
valuelen
)
const
uint8_t
*
value
,
size_t
valuelen
,
bool
no_index
)
{
{
response_headers_sum_
+=
namelen
+
valuelen
;
response_headers_sum_
+=
namelen
+
valuelen
;
http2
::
split_add_header
(
response_headers_
,
name
,
namelen
,
value
,
valuelen
);
http2
::
split_add_header
(
response_headers_
,
name
,
namelen
,
value
,
valuelen
,
no_index
);
}
}
bool
Downstream
::
get_response_header_key_prev
()
const
bool
Downstream
::
get_response_header_key_prev
()
const
...
@@ -558,7 +563,7 @@ void Downstream::append_last_response_header_key(const char *data, size_t len)
...
@@ -558,7 +563,7 @@ void Downstream::append_last_response_header_key(const char *data, size_t len)
assert
(
response_header_key_prev_
);
assert
(
response_header_key_prev_
);
response_headers_sum_
+=
len
;
response_headers_sum_
+=
len
;
auto
&
item
=
response_headers_
.
back
();
auto
&
item
=
response_headers_
.
back
();
item
.
first
.
append
(
data
,
len
);
item
.
name
.
append
(
data
,
len
);
}
}
void
Downstream
::
append_last_response_header_value
(
const
char
*
data
,
void
Downstream
::
append_last_response_header_value
(
const
char
*
data
,
...
@@ -567,7 +572,7 @@ void Downstream::append_last_response_header_value(const char *data,
...
@@ -567,7 +572,7 @@ void Downstream::append_last_response_header_value(const char *data,
assert
(
!
response_header_key_prev_
);
assert
(
!
response_header_key_prev_
);
response_headers_sum_
+=
len
;
response_headers_sum_
+=
len
;
auto
&
item
=
response_headers_
.
back
();
auto
&
item
=
response_headers_
.
back
();
item
.
second
.
append
(
data
,
len
);
item
.
value
.
append
(
data
,
len
);
}
}
size_t
Downstream
::
get_response_headers_sum
()
const
size_t
Downstream
::
get_response_headers_sum
()
const
...
@@ -692,7 +697,7 @@ void Downstream::check_upgrade_fulfilled()
...
@@ -692,7 +697,7 @@ void Downstream::check_upgrade_fulfilled()
// TODO Do more strict checking for upgrade headers
// TODO Do more strict checking for upgrade headers
if
(
response_http_status_
==
101
)
{
if
(
response_http_status_
==
101
)
{
for
(
auto
&
hd
:
request_headers_
)
{
for
(
auto
&
hd
:
request_headers_
)
{
if
(
util
::
strieq
(
"upgrade"
,
hd
.
first
.
c_str
()))
{
if
(
util
::
strieq
(
"upgrade"
,
hd
.
name
.
c_str
()))
{
upgraded_
=
true
;
upgraded_
=
true
;
break
;
break
;
}
}
...
@@ -713,7 +718,7 @@ void Downstream::check_upgrade_request()
...
@@ -713,7 +718,7 @@ void Downstream::check_upgrade_request()
}
else
{
}
else
{
// TODO Do more strict checking for upgrade headers
// TODO Do more strict checking for upgrade headers
for
(
auto
&
hd
:
request_headers_
)
{
for
(
auto
&
hd
:
request_headers_
)
{
if
(
util
::
strieq
(
"upgrade"
,
hd
.
first
.
c_str
()))
{
if
(
util
::
strieq
(
"upgrade"
,
hd
.
name
.
c_str
()))
{
upgrade_request_
=
true
;
upgrade_request_
=
true
;
break
;
break
;
}
}
...
@@ -737,12 +742,12 @@ bool Downstream::http2_upgrade_request() const
...
@@ -737,12 +742,12 @@ bool Downstream::http2_upgrade_request() const
// For now just check NGHTTP2_CLEARTEXT_PROTO_VERSION_ID in
// For now just check NGHTTP2_CLEARTEXT_PROTO_VERSION_ID in
// Upgrade header field and existence of HTTP2-Settings header
// Upgrade header field and existence of HTTP2-Settings header
// field.
// field.
if
(
util
::
strieq
(
hd
.
first
.
c_str
(),
"upgrade"
))
{
if
(
util
::
strieq
(
hd
.
name
.
c_str
(),
"upgrade"
))
{
if
(
util
::
strieq
(
hd
.
second
.
c_str
(),
if
(
util
::
strieq
(
hd
.
value
.
c_str
(),
NGHTTP2_CLEARTEXT_PROTO_VERSION_ID
))
{
NGHTTP2_CLEARTEXT_PROTO_VERSION_ID
))
{
upgrade_seen
=
true
;
upgrade_seen
=
true
;
}
}
}
else
if
(
util
::
strieq
(
hd
.
first
.
c_str
(),
"http2-settings"
))
{
}
else
if
(
util
::
strieq
(
hd
.
name
.
c_str
(),
"http2-settings"
))
{
http2_settings_seen
=
true
;
http2_settings_seen
=
true
;
}
}
}
}
...
...
src/shrpx_downstream.h
View file @
b1edb1f3
...
@@ -103,7 +103,8 @@ public:
...
@@ -103,7 +103,8 @@ public:
void
set_last_request_header_value
(
std
::
string
value
);
void
set_last_request_header_value
(
std
::
string
value
);
void
split_add_request_header
(
const
uint8_t
*
name
,
size_t
namelen
,
void
split_add_request_header
(
const
uint8_t
*
name
,
size_t
namelen
,
const
uint8_t
*
value
,
size_t
valuelen
);
const
uint8_t
*
value
,
size_t
valuelen
,
bool
no_index
);
bool
get_request_header_key_prev
()
const
;
bool
get_request_header_key_prev
()
const
;
void
append_last_request_header_key
(
const
char
*
data
,
size_t
len
);
void
append_last_request_header_key
(
const
char
*
data
,
size_t
len
);
...
@@ -171,7 +172,8 @@ public:
...
@@ -171,7 +172,8 @@ public:
void
set_last_response_header_value
(
std
::
string
value
);
void
set_last_response_header_value
(
std
::
string
value
);
void
split_add_response_header
(
const
uint8_t
*
name
,
size_t
namelen
,
void
split_add_response_header
(
const
uint8_t
*
name
,
size_t
namelen
,
const
uint8_t
*
value
,
size_t
valuelen
);
const
uint8_t
*
value
,
size_t
valuelen
,
bool
no_index
);
bool
get_response_header_key_prev
()
const
;
bool
get_response_header_key_prev
()
const
;
void
append_last_response_header_key
(
const
char
*
data
,
size_t
len
);
void
append_last_response_header_key
(
const
char
*
data
,
size_t
len
);
...
...
src/shrpx_downstream_test.cc
View file @
b1edb1f3
...
@@ -78,13 +78,13 @@ void test_downstream_get_norm_request_header(void)
...
@@ -78,13 +78,13 @@ void test_downstream_get_norm_request_header(void)
d
.
add_request_header
(
"delta"
,
"4"
);
d
.
add_request_header
(
"delta"
,
"4"
);
d
.
add_request_header
(
"echo"
,
"5"
);
d
.
add_request_header
(
"echo"
,
"5"
);
auto
i
=
d
.
get_norm_request_header
(
"alpha"
);
auto
i
=
d
.
get_norm_request_header
(
"alpha"
);
CU_ASSERT
(
std
::
make_pair
(
std
::
string
(
"alpha"
),
std
::
string
(
"0"
)
)
==
*
i
);
CU_ASSERT
(
Header
(
"alpha"
,
"0"
)
==
*
i
);
i
=
d
.
get_norm_request_header
(
"bravo"
);
i
=
d
.
get_norm_request_header
(
"bravo"
);
CU_ASSERT
(
std
::
make_pair
(
std
::
string
(
"bravo"
),
std
::
string
(
"1"
)
)
==
*
i
);
CU_ASSERT
(
Header
(
"bravo"
,
"1"
)
==
*
i
);
i
=
d
.
get_norm_request_header
(
"delta"
);
i
=
d
.
get_norm_request_header
(
"delta"
);
CU_ASSERT
(
std
::
make_pair
(
std
::
string
(
"delta"
),
std
::
string
(
"4"
)
)
==
*
i
);
CU_ASSERT
(
Header
(
"delta"
,
"4"
)
==
*
i
);
i
=
d
.
get_norm_request_header
(
"echo"
);
i
=
d
.
get_norm_request_header
(
"echo"
);
CU_ASSERT
(
std
::
make_pair
(
std
::
string
(
"echo"
),
std
::
string
(
"5"
)
)
==
*
i
);
CU_ASSERT
(
Header
(
"echo"
,
"5"
)
==
*
i
);
i
=
d
.
get_norm_request_header
(
"foxtrot"
);
i
=
d
.
get_norm_request_header
(
"foxtrot"
);
CU_ASSERT
(
i
==
std
::
end
(
d
.
get_request_headers
()));
CU_ASSERT
(
i
==
std
::
end
(
d
.
get_request_headers
()));
}
}
...
@@ -99,13 +99,13 @@ void test_downstream_get_norm_response_header(void)
...
@@ -99,13 +99,13 @@ void test_downstream_get_norm_response_header(void)
d
.
add_response_header
(
"delta"
,
"4"
);
d
.
add_response_header
(
"delta"
,
"4"
);
d
.
add_response_header
(
"echo"
,
"5"
);
d
.
add_response_header
(
"echo"
,
"5"
);
auto
i
=
d
.
get_norm_response_header
(
"alpha"
);
auto
i
=
d
.
get_norm_response_header
(
"alpha"
);
CU_ASSERT
(
std
::
make_pair
(
std
::
string
(
"alpha"
),
std
::
string
(
"0"
)
)
==
*
i
);
CU_ASSERT
(
Header
(
"alpha"
,
"0"
)
==
*
i
);
i
=
d
.
get_norm_response_header
(
"bravo"
);
i
=
d
.
get_norm_response_header
(
"bravo"
);
CU_ASSERT
(
std
::
make_pair
(
std
::
string
(
"bravo"
),
std
::
string
(
"1"
)
)
==
*
i
);
CU_ASSERT
(
Header
(
"bravo"
,
"1"
)
==
*
i
);
i
=
d
.
get_norm_response_header
(
"delta"
);
i
=
d
.
get_norm_response_header
(
"delta"
);
CU_ASSERT
(
std
::
make_pair
(
std
::
string
(
"delta"
),
std
::
string
(
"4"
)
)
==
*
i
);
CU_ASSERT
(
Header
(
"delta"
,
"4"
)
==
*
i
);
i
=
d
.
get_norm_response_header
(
"echo"
);
i
=
d
.
get_norm_response_header
(
"echo"
);
CU_ASSERT
(
std
::
make_pair
(
std
::
string
(
"echo"
),
std
::
string
(
"5"
)
)
==
*
i
);
CU_ASSERT
(
Header
(
"echo"
,
"5"
)
==
*
i
);
i
=
d
.
get_norm_response_header
(
"foxtrot"
);
i
=
d
.
get_norm_response_header
(
"foxtrot"
);
CU_ASSERT
(
i
==
std
::
end
(
d
.
get_response_headers
()));
CU_ASSERT
(
i
==
std
::
end
(
d
.
get_response_headers
()));
}
}
...
@@ -120,13 +120,13 @@ void test_downstream_crumble_request_cookie(void)
...
@@ -120,13 +120,13 @@ void test_downstream_crumble_request_cookie(void)
d
.
add_request_header
(
"cookie"
,
"echo"
);
d
.
add_request_header
(
"cookie"
,
"echo"
);
d
.
crumble_request_cookie
();
d
.
crumble_request_cookie
();
Headers
ans
=
{
Headers
ans
=
{
std
::
make_pair
(
":method"
,
"get"
)
,
{
":method"
,
"get"
}
,
std
::
make_pair
(
":path"
,
"/"
)
,
{
":path"
,
"/"
}
,
std
::
make_pair
(
"cookie"
,
"alpha"
)
,
{
"cookie"
,
"alpha"
}
,
std
::
make_pair
(
"cookie"
,
"delta"
)
,
{
"cookie"
,
"delta"
}
,
std
::
make_pair
(
"cookie"
,
"echo"
)
,
{
"cookie"
,
"echo"
}
,
std
::
make_pair
(
"cookie"
,
"bravo"
)
,
{
"cookie"
,
"bravo"
}
,
std
::
make_pair
(
"cookie"
,
"charlie"
)
{
"cookie"
,
"charlie"
}
};
};
CU_ASSERT
(
ans
==
d
.
get_request_headers
());
CU_ASSERT
(
ans
==
d
.
get_request_headers
());
}
}
...
@@ -154,7 +154,7 @@ void test_downstream_rewrite_norm_location_response_header(void)
...
@@ -154,7 +154,7 @@ void test_downstream_rewrite_norm_location_response_header(void)
d
.
add_response_header
(
"location"
,
"http://localhost:3000/"
);
d
.
add_response_header
(
"location"
,
"http://localhost:3000/"
);
d
.
rewrite_norm_location_response_header
(
"https"
,
443
);
d
.
rewrite_norm_location_response_header
(
"https"
,
443
);
auto
location
=
d
.
get_norm_response_header
(
"location"
);
auto
location
=
d
.
get_norm_response_header
(
"location"
);
CU_ASSERT
(
"https://localhost/"
==
(
*
location
).
second
);
CU_ASSERT
(
"https://localhost/"
==
(
*
location
).
value
);
}
}
{
{
Downstream
d
(
nullptr
,
0
,
0
);
Downstream
d
(
nullptr
,
0
,
0
);
...
@@ -162,7 +162,7 @@ void test_downstream_rewrite_norm_location_response_header(void)
...
@@ -162,7 +162,7 @@ void test_downstream_rewrite_norm_location_response_header(void)
d
.
add_response_header
(
"location"
,
"http://localhost/"
);
d
.
add_response_header
(
"location"
,
"http://localhost/"
);
d
.
rewrite_norm_location_response_header
(
"https"
,
443
);
d
.
rewrite_norm_location_response_header
(
"https"
,
443
);
auto
location
=
d
.
get_norm_response_header
(
"location"
);
auto
location
=
d
.
get_norm_response_header
(
"location"
);
CU_ASSERT
(
"https://localhost/"
==
(
*
location
).
second
);
CU_ASSERT
(
"https://localhost/"
==
(
*
location
).
value
);
}
}
}
}
...
...
src/shrpx_http2_downstream_connection.cc
View file @
b1edb1f3
...
@@ -356,21 +356,21 @@ int Http2DownstreamConnection::push_request_headers()
...
@@ -356,21 +356,21 @@ int Http2DownstreamConnection::push_request_headers()
auto
transfer_encoding
=
auto
transfer_encoding
=
downstream_
->
get_norm_request_header
(
"transfer-encoding"
);
downstream_
->
get_norm_request_header
(
"transfer-encoding"
);
if
(
transfer_encoding
!=
end_headers
&&
if
(
transfer_encoding
!=
end_headers
&&
util
::
strieq
((
*
transfer_encoding
).
second
.
c_str
(),
"chunked"
))
{
util
::
strieq
((
*
transfer_encoding
).
value
.
c_str
(),
"chunked"
))
{
chunked_encoding
=
true
;
chunked_encoding
=
true
;
}
}
auto
xff
=
downstream_
->
get_norm_request_header
(
"x-forwarded-for"
);
auto
xff
=
downstream_
->
get_norm_request_header
(
"x-forwarded-for"
);
if
(
get_config
()
->
add_x_forwarded_for
)
{
if
(
get_config
()
->
add_x_forwarded_for
)
{
if
(
xff
!=
end_headers
)
{
if
(
xff
!=
end_headers
)
{
xff_value
=
(
*
xff
).
second
;
xff_value
=
(
*
xff
).
value
;
xff_value
+=
", "
;
xff_value
+=
", "
;
}
}
xff_value
+=
downstream_
->
get_upstream
()
->
get_client_handler
()
->
xff_value
+=
downstream_
->
get_upstream
()
->
get_client_handler
()
->
get_ipaddr
();
get_ipaddr
();
nva
.
push_back
(
http2
::
make_nv_ls
(
"x-forwarded-for"
,
xff_value
));
nva
.
push_back
(
http2
::
make_nv_ls
(
"x-forwarded-for"
,
xff_value
));
}
else
if
(
xff
!=
end_headers
)
{
}
else
if
(
xff
!=
end_headers
)
{
nva
.
push_back
(
http2
::
make_nv_ls
(
"x-forwarded-for"
,
(
*
xff
).
second
));
nva
.
push_back
(
http2
::
make_nv_ls
(
"x-forwarded-for"
,
(
*
xff
).
value
));
}
}
if
(
downstream_
->
get_request_method
()
!=
"CONNECT"
)
{
if
(
downstream_
->
get_request_method
()
!=
"CONNECT"
)
{
...
@@ -389,11 +389,11 @@ int Http2DownstreamConnection::push_request_headers()
...
@@ -389,11 +389,11 @@ int Http2DownstreamConnection::push_request_headers()
auto
via
=
downstream_
->
get_norm_request_header
(
"via"
);
auto
via
=
downstream_
->
get_norm_request_header
(
"via"
);
if
(
get_config
()
->
no_via
)
{
if
(
get_config
()
->
no_via
)
{
if
(
via
!=
end_headers
)
{
if
(
via
!=
end_headers
)
{
nva
.
push_back
(
http2
::
make_nv_ls
(
"via"
,
(
*
via
).
second
));
nva
.
push_back
(
http2
::
make_nv_ls
(
"via"
,
(
*
via
).
value
));
}
}
}
else
{
}
else
{
if
(
via
!=
end_headers
)
{
if
(
via
!=
end_headers
)
{
via_value
=
(
*
via
).
second
;
via_value
=
(
*
via
).
value
;
via_value
+=
", "
;
via_value
+=
", "
;
}
}
via_value
+=
http
::
create_via_header_value
via_value
+=
http
::
create_via_header_value
...
...
src/shrpx_http2_session.cc
View file @
b1edb1f3
...
@@ -814,7 +814,8 @@ int on_header_callback(nghttp2_session *session,
...
@@ -814,7 +814,8 @@ int on_header_callback(nghttp2_session *session,
if
(
!
http2
::
check_nv
(
name
,
namelen
,
value
,
valuelen
))
{
if
(
!
http2
::
check_nv
(
name
,
namelen
,
value
,
valuelen
))
{
return
0
;
return
0
;
}
}
downstream
->
split_add_response_header
(
name
,
namelen
,
value
,
valuelen
);
downstream
->
split_add_response_header
(
name
,
namelen
,
value
,
valuelen
,
flags
&
NGHTTP2_NV_FLAG_NO_INDEX
);
return
0
;
return
0
;
}
}
}
// namespace
}
// namespace
...
@@ -886,7 +887,7 @@ int on_response_headers(Http2Session *http2session,
...
@@ -886,7 +887,7 @@ int on_response_headers(Http2Session *http2session,
call_downstream_readcb
(
http2session
,
downstream
);
call_downstream_readcb
(
http2session
,
downstream
);
return
0
;
return
0
;
}
}
downstream
->
set_response_http_status
(
strtoul
(
status
->
second
.
c_str
(),
downstream
->
set_response_http_status
(
strtoul
(
status
->
value
.
c_str
(),
nullptr
,
10
));
nullptr
,
10
));
downstream
->
set_response_major
(
2
);
downstream
->
set_response_major
(
2
);
downstream
->
set_response_minor
(
0
);
downstream
->
set_response_minor
(
0
);
...
@@ -916,7 +917,7 @@ int on_response_headers(Http2Session *http2session,
...
@@ -916,7 +917,7 @@ int on_response_headers(Http2Session *http2session,
if
(
LOG_ENABLED
(
INFO
))
{
if
(
LOG_ENABLED
(
INFO
))
{
std
::
stringstream
ss
;
std
::
stringstream
ss
;
for
(
auto
&
nv
:
nva
)
{
for
(
auto
&
nv
:
nva
)
{
ss
<<
TTY_HTTP_HD
<<
nv
.
first
<<
TTY_RST
<<
": "
<<
nv
.
second
<<
"
\n
"
;
ss
<<
TTY_HTTP_HD
<<
nv
.
name
<<
TTY_RST
<<
": "
<<
nv
.
value
<<
"
\n
"
;
}
}
SSLOG
(
INFO
,
http2session
)
<<
"HTTP response headers. stream_id="
SSLOG
(
INFO
,
http2session
)
<<
"HTTP response headers. stream_id="
<<
frame
->
hd
.
stream_id
<<
frame
->
hd
.
stream_id
...
...
src/shrpx_http2_upstream.cc
View file @
b1edb1f3
...
@@ -101,8 +101,8 @@ int Http2Upstream::upgrade_upstream(HttpsUpstream *http)
...
@@ -101,8 +101,8 @@ int Http2Upstream::upgrade_upstream(HttpsUpstream *http)
std
::
string
settings_payload
;
std
::
string
settings_payload
;
auto
downstream
=
http
->
get_downstream
();
auto
downstream
=
http
->
get_downstream
();
for
(
auto
&
hd
:
downstream
->
get_request_headers
())
{
for
(
auto
&
hd
:
downstream
->
get_request_headers
())
{
if
(
util
::
strieq
(
hd
.
first
.
c_str
(),
"http2-settings"
))
{
if
(
util
::
strieq
(
hd
.
name
.
c_str
(),
"http2-settings"
))
{
auto
val
=
hd
.
second
;
auto
val
=
hd
.
value
;
util
::
to_base64
(
val
);
util
::
to_base64
(
val
);
settings_payload
=
base64
::
decode
(
std
::
begin
(
val
),
std
::
end
(
val
));
settings_payload
=
base64
::
decode
(
std
::
begin
(
val
),
std
::
end
(
val
));
break
;
break
;
...
@@ -205,7 +205,8 @@ int on_header_callback(nghttp2_session *session,
...
@@ -205,7 +205,8 @@ int on_header_callback(nghttp2_session *session,
if
(
!
http2
::
check_nv
(
name
,
namelen
,
value
,
valuelen
))
{
if
(
!
http2
::
check_nv
(
name
,
namelen
,
value
,
valuelen
))
{
return
0
;
return
0
;
}
}
downstream
->
split_add_request_header
(
name
,
namelen
,
value
,
valuelen
);
downstream
->
split_add_request_header
(
name
,
namelen
,
value
,
valuelen
,
flags
&
NGHTTP2_NV_FLAG_NO_INDEX
);
return
0
;
return
0
;
}
}
}
// namespace
}
// namespace
...
@@ -259,7 +260,7 @@ int on_request_headers(Http2Upstream *upstream,
...
@@ -259,7 +260,7 @@ int on_request_headers(Http2Upstream *upstream,
if
(
LOG_ENABLED
(
INFO
))
{
if
(
LOG_ENABLED
(
INFO
))
{
std
::
stringstream
ss
;
std
::
stringstream
ss
;
for
(
auto
&
nv
:
nva
)
{
for
(
auto
&
nv
:
nva
)
{
ss
<<
TTY_HTTP_HD
<<
nv
.
first
<<
TTY_RST
<<
": "
<<
nv
.
second
<<
"
\n
"
;
ss
<<
TTY_HTTP_HD
<<
nv
.
name
<<
TTY_RST
<<
": "
<<
nv
.
value
<<
"
\n
"
;
}
}
ULOG
(
INFO
,
upstream
)
<<
"HTTP request headers. stream_id="
ULOG
(
INFO
,
upstream
)
<<
"HTTP request headers. stream_id="
<<
downstream
->
get_stream_id
()
<<
downstream
->
get_stream_id
()
...
@@ -280,7 +281,7 @@ int on_request_headers(Http2Upstream *upstream,
...
@@ -280,7 +281,7 @@ int on_request_headers(Http2Upstream *upstream,
auto
path
=
http2
::
get_unique_header
(
nva
,
":path"
);
auto
path
=
http2
::
get_unique_header
(
nva
,
":path"
);
auto
method
=
http2
::
get_unique_header
(
nva
,
":method"
);
auto
method
=
http2
::
get_unique_header
(
nva
,
":method"
);
auto
scheme
=
http2
::
get_unique_header
(
nva
,
":scheme"
);
auto
scheme
=
http2
::
get_unique_header
(
nva
,
":scheme"
);
bool
is_connect
=
method
&&
"CONNECT"
==
method
->
second
;
bool
is_connect
=
method
&&
"CONNECT"
==
method
->
value
;
bool
having_host
=
http2
::
non_empty_value
(
host
);
bool
having_host
=
http2
::
non_empty_value
(
host
);
bool
having_authority
=
http2
::
non_empty_value
(
authority
);
bool
having_authority
=
http2
::
non_empty_value
(
authority
);
...
@@ -1014,11 +1015,11 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream)
...
@@ -1014,11 +1015,11 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream)
auto
via
=
downstream
->
get_norm_response_header
(
"via"
);
auto
via
=
downstream
->
get_norm_response_header
(
"via"
);
if
(
get_config
()
->
no_via
)
{
if
(
get_config
()
->
no_via
)
{
if
(
via
!=
end_headers
)
{
if
(
via
!=
end_headers
)
{
nva
.
push_back
(
http2
::
make_nv_ls
(
"via"
,
(
*
via
).
second
));
nva
.
push_back
(
http2
::
make_nv_ls
(
"via"
,
(
*
via
).
value
));
}
}
}
else
{
}
else
{
if
(
via
!=
end_headers
)
{
if
(
via
!=
end_headers
)
{
via_value
=
(
*
via
).
second
;
via_value
=
(
*
via
).
value
;
via_value
+=
", "
;
via_value
+=
", "
;
}
}
via_value
+=
http
::
create_via_header_value
via_value
+=
http
::
create_via_header_value
...
...
src/shrpx_http_downstream_connection.cc
View file @
b1edb1f3
...
@@ -171,16 +171,16 @@ int HttpDownstreamConnection::push_request_headers()
...
@@ -171,16 +171,16 @@ int HttpDownstreamConnection::push_request_headers()
if
(
get_config
()
->
add_x_forwarded_for
)
{
if
(
get_config
()
->
add_x_forwarded_for
)
{
hdrs
+=
"X-Forwarded-For: "
;
hdrs
+=
"X-Forwarded-For: "
;
if
(
xff
!=
end_headers
)
{
if
(
xff
!=
end_headers
)
{
hdrs
+=
(
*
xff
).
second
;
hdrs
+=
(
*
xff
).
value
;
http2
::
sanitize_header_value
(
hdrs
,
hdrs
.
size
()
-
(
*
xff
).
second
.
size
());
http2
::
sanitize_header_value
(
hdrs
,
hdrs
.
size
()
-
(
*
xff
).
value
.
size
());
hdrs
+=
", "
;
hdrs
+=
", "
;
}
}
hdrs
+=
client_handler_
->
get_ipaddr
();
hdrs
+=
client_handler_
->
get_ipaddr
();
hdrs
+=
"
\r\n
"
;
hdrs
+=
"
\r\n
"
;
}
else
if
(
xff
!=
end_headers
)
{
}
else
if
(
xff
!=
end_headers
)
{
hdrs
+=
"X-Forwarded-For: "
;
hdrs
+=
"X-Forwarded-For: "
;
hdrs
+=
(
*
xff
).
second
;
hdrs
+=
(
*
xff
).
value
;
http2
::
sanitize_header_value
(
hdrs
,
hdrs
.
size
()
-
(
*
xff
).
second
.
size
());
http2
::
sanitize_header_value
(
hdrs
,
hdrs
.
size
()
-
(
*
xff
).
value
.
size
());
hdrs
+=
"
\r\n
"
;
hdrs
+=
"
\r\n
"
;
}
}
if
(
downstream_
->
get_request_method
()
!=
"CONNECT"
)
{
if
(
downstream_
->
get_request_method
()
!=
"CONNECT"
)
{
...
@@ -196,25 +196,25 @@ int HttpDownstreamConnection::push_request_headers()
...
@@ -196,25 +196,25 @@ int HttpDownstreamConnection::push_request_headers()
}
}
auto
expect
=
downstream_
->
get_norm_request_header
(
"expect"
);
auto
expect
=
downstream_
->
get_norm_request_header
(
"expect"
);
if
(
expect
!=
end_headers
&&
if
(
expect
!=
end_headers
&&
!
util
::
strifind
((
*
expect
).
second
.
c_str
(),
"100-continue"
))
{
!
util
::
strifind
((
*
expect
).
value
.
c_str
(),
"100-continue"
))
{
hdrs
+=
"Expect: "
;
hdrs
+=
"Expect: "
;
hdrs
+=
(
*
expect
).
second
;
hdrs
+=
(
*
expect
).
value
;
http2
::
sanitize_header_value
(
hdrs
,
hdrs
.
size
()
-
(
*
expect
).
second
.
size
());
http2
::
sanitize_header_value
(
hdrs
,
hdrs
.
size
()
-
(
*
expect
).
value
.
size
());
hdrs
+=
"
\r\n
"
;
hdrs
+=
"
\r\n
"
;
}
}
auto
via
=
downstream_
->
get_norm_request_header
(
"via"
);
auto
via
=
downstream_
->
get_norm_request_header
(
"via"
);
if
(
get_config
()
->
no_via
)
{
if
(
get_config
()
->
no_via
)
{
if
(
via
!=
end_headers
)
{
if
(
via
!=
end_headers
)
{
hdrs
+=
"Via: "
;
hdrs
+=
"Via: "
;
hdrs
+=
(
*
via
).
second
;
hdrs
+=
(
*
via
).
value
;
http2
::
sanitize_header_value
(
hdrs
,
hdrs
.
size
()
-
(
*
via
).
second
.
size
());
http2
::
sanitize_header_value
(
hdrs
,
hdrs
.
size
()
-
(
*
via
).
value
.
size
());
hdrs
+=
"
\r\n
"
;
hdrs
+=
"
\r\n
"
;
}
}
}
else
{
}
else
{
hdrs
+=
"Via: "
;
hdrs
+=
"Via: "
;
if
(
via
!=
end_headers
)
{
if
(
via
!=
end_headers
)
{
hdrs
+=
(
*
via
).
second
;
hdrs
+=
(
*
via
).
value
;
http2
::
sanitize_header_value
(
hdrs
,
hdrs
.
size
()
-
(
*
via
).
second
.
size
());
http2
::
sanitize_header_value
(
hdrs
,
hdrs
.
size
()
-
(
*
via
).
value
.
size
());
hdrs
+=
", "
;
hdrs
+=
", "
;
}
}
hdrs
+=
http
::
create_via_header_value
(
downstream_
->
get_request_major
(),
hdrs
+=
http
::
create_via_header_value
(
downstream_
->
get_request_major
(),
...
...
src/shrpx_https_upstream.cc
View file @
b1edb1f3
...
@@ -159,8 +159,8 @@ int htp_hdrs_completecb(http_parser *htp)
...
@@ -159,8 +159,8 @@ int htp_hdrs_completecb(http_parser *htp)
<<
downstream
->
get_request_minor
()
<<
"
\n
"
;
<<
downstream
->
get_request_minor
()
<<
"
\n
"
;
const
auto
&
headers
=
downstream
->
get_request_headers
();
const
auto
&
headers
=
downstream
->
get_request_headers
();
for
(
size_t
i
=
0
;
i
<
headers
.
size
();
++
i
)
{
for
(
size_t
i
=
0
;
i
<
headers
.
size
();
++
i
)
{
ss
<<
TTY_HTTP_HD
<<
headers
[
i
].
first
<<
TTY_RST
<<
": "
ss
<<
TTY_HTTP_HD
<<
headers
[
i
].
name
<<
TTY_RST
<<
": "
<<
headers
[
i
].
second
<<
"
\n
"
;
<<
headers
[
i
].
value
<<
"
\n
"
;
}
}
ULOG
(
INFO
,
upstream
)
<<
"HTTP request headers
\n
"
<<
ss
.
str
();
ULOG
(
INFO
,
upstream
)
<<
"HTTP request headers
\n
"
<<
ss
.
str
();
}
}
...
@@ -682,15 +682,15 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream)
...
@@ -682,15 +682,15 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream)
if
(
get_config
()
->
no_via
)
{
if
(
get_config
()
->
no_via
)
{
if
(
via
!=
end_headers
)
{
if
(
via
!=
end_headers
)
{
hdrs
+=
"Via: "
;
hdrs
+=
"Via: "
;
hdrs
+=
(
*
via
).
second
;
hdrs
+=
(
*
via
).
value
;
http2
::
sanitize_header_value
(
hdrs
,
hdrs
.
size
()
-
(
*
via
).
second
.
size
());
http2
::
sanitize_header_value
(
hdrs
,
hdrs
.
size
()
-
(
*
via
).
value
.
size
());
hdrs
+=
"
\r\n
"
;
hdrs
+=
"
\r\n
"
;
}
}
}
else
{
}
else
{
hdrs
+=
"Via: "
;
hdrs
+=
"Via: "
;
if
(
via
!=
end_headers
)
{
if
(
via
!=
end_headers
)
{
hdrs
+=
(
*
via
).
second
;
hdrs
+=
(
*
via
).
value
;
http2
::
sanitize_header_value
(
hdrs
,
hdrs
.
size
()
-
(
*
via
).
second
.
size
());
http2
::
sanitize_header_value
(
hdrs
,
hdrs
.
size
()
-
(
*
via
).
value
.
size
());
hdrs
+=
", "
;
hdrs
+=
", "
;
}
}
hdrs
+=
http
::
create_via_header_value
hdrs
+=
http
::
create_via_header_value
...
...
src/shrpx_spdy_upstream.cc
View file @
b1edb1f3
...
@@ -864,18 +864,18 @@ int SpdyUpstream::on_downstream_header_complete(Downstream *downstream)
...
@@ -864,18 +864,18 @@ int SpdyUpstream::on_downstream_header_complete(Downstream *downstream)
nv
[
hdidx
++
]
=
":version"
;
nv
[
hdidx
++
]
=
":version"
;
nv
[
hdidx
++
]
=
"HTTP/1.1"
;
nv
[
hdidx
++
]
=
"HTTP/1.1"
;
for
(
auto
&
hd
:
downstream
->
get_response_headers
())
{
for
(
auto
&
hd
:
downstream
->
get_response_headers
())
{
if
(
hd
.
first
.
empty
()
||
hd
.
first
.
c_str
()[
0
]
==
':'
||
if
(
hd
.
name
.
empty
()
||
hd
.
name
.
c_str
()[
0
]
==
':'
||
util
::
strieq
(
hd
.
first
.
c_str
(),
"transfer-encoding"
)
||
util
::
strieq
(
hd
.
name
.
c_str
(),
"transfer-encoding"
)
||
util
::
strieq
(
hd
.
first
.
c_str
(),
"keep-alive"
)
||
// HTTP/1.0?
util
::
strieq
(
hd
.
name
.
c_str
(),
"keep-alive"
)
||
// HTTP/1.0?
util
::
strieq
(
hd
.
first
.
c_str
(),
"connection"
)
||
util
::
strieq
(
hd
.
name
.
c_str
(),
"connection"
)
||
util
::
strieq
(
hd
.
first
.
c_str
(),
"proxy-connection"
))
{
util
::
strieq
(
hd
.
name
.
c_str
(),
"proxy-connection"
))
{
// These are ignored
// These are ignored
}
else
if
(
!
get_config
()
->
no_via
&&
}
else
if
(
!
get_config
()
->
no_via
&&
util
::
strieq
(
hd
.
first
.
c_str
(),
"via"
))
{
util
::
strieq
(
hd
.
name
.
c_str
(),
"via"
))
{
via_value
=
hd
.
second
;
via_value
=
hd
.
value
;
}
else
{
}
else
{
nv
[
hdidx
++
]
=
hd
.
first
.
c_str
();
nv
[
hdidx
++
]
=
hd
.
name
.
c_str
();
nv
[
hdidx
++
]
=
hd
.
second
.
c_str
();
nv
[
hdidx
++
]
=
hd
.
value
.
c_str
();
}
}
}
}
if
(
!
get_config
()
->
no_via
)
{
if
(
!
get_config
()
->
no_via
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment