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
db2f612a
Commit
db2f612a
authored
Aug 06, 2019
by
Tatsuhiro Tsujikawa
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
nghttpx: Fix request stall
Fix request stall if backend connection is reused and buffer is full.
parent
7ffc239b
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
63 additions
and
6 deletions
+63
-6
integration-tests/nghttpx_http1_test.go
integration-tests/nghttpx_http1_test.go
+29
-0
integration-tests/server_tester.go
integration-tests/server_tester.go
+3
-1
src/shrpx_downstream.cc
src/shrpx_downstream.cc
+11
-1
src/shrpx_downstream.h
src/shrpx_downstream.h
+4
-0
src/shrpx_http_downstream_connection.cc
src/shrpx_http_downstream_connection.cc
+15
-1
src/shrpx_https_upstream.cc
src/shrpx_https_upstream.cc
+1
-3
No files found.
integration-tests/nghttpx_http1_test.go
View file @
db2f612a
...
...
@@ -625,6 +625,35 @@ func TestH1H1HTTPSRedirectPort(t *testing.T) {
}
}
// TestH1H1POSTRequests tests that server can handle 2 requests with
// request body.
func
TestH1H1POSTRequests
(
t
*
testing
.
T
)
{
st
:=
newServerTester
(
nil
,
t
,
noopHandler
)
defer
st
.
Close
()
res
,
err
:=
st
.
http1
(
requestParam
{
name
:
"TestH1H1POSTRequestsNo1"
,
body
:
make
([]
byte
,
1
),
})
if
err
!=
nil
{
t
.
Fatalf
(
"Error st.http1() = %v"
,
err
)
}
if
got
,
want
:=
res
.
status
,
200
;
got
!=
want
{
t
.
Errorf
(
"res.status: %v; want %v"
,
got
,
want
)
}
res
,
err
=
st
.
http1
(
requestParam
{
name
:
"TestH1H1POSTRequestsNo2"
,
body
:
make
([]
byte
,
65536
),
})
if
err
!=
nil
{
t
.
Fatalf
(
"Error st.http1() = %v"
,
err
)
}
if
got
,
want
:=
res
.
status
,
200
;
got
!=
want
{
t
.
Errorf
(
"res.status: %v; want %v"
,
got
,
want
)
}
}
// // TestH1H2ConnectFailure tests that server handles the situation that
// // connection attempt to HTTP/2 backend failed.
// func TestH1H2ConnectFailure(t *testing.T) {
...
...
integration-tests/server_tester.go
View file @
db2f612a
...
...
@@ -662,7 +662,9 @@ func cloneHeader(h http.Header) http.Header {
return
h2
}
func
noopHandler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{}
func
noopHandler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
ioutil
.
ReadAll
(
r
.
Body
)
}
type
APIResponse
struct
{
Status
string
`json:"status,omitempty"`
...
...
src/shrpx_downstream.cc
View file @
db2f612a
...
...
@@ -144,7 +144,8 @@ Downstream::Downstream(Upstream *upstream, MemchunkPool *mcpool,
request_header_sent_
(
false
),
accesslog_written_
(
false
),
new_affinity_cookie_
(
false
),
blocked_request_data_eof_
(
false
)
{
blocked_request_data_eof_
(
false
),
expect_100_continue_
(
false
)
{
auto
&
timeoutconf
=
get_config
()
->
http2
.
timeout
;
...
...
@@ -857,6 +858,11 @@ void Downstream::inspect_http1_request() {
chunked_request_
=
true
;
}
}
auto
expect
=
req_
.
fs
.
header
(
http2
::
HD_EXPECT
);
expect_100_continue_
=
expect
&&
util
::
strieq
(
expect
->
value
,
StringRef
::
from_lit
(
"100-continue"
));
}
void
Downstream
::
inspect_http1_response
()
{
...
...
@@ -1159,4 +1165,8 @@ void Downstream::set_blocked_request_data_eof(bool f) {
void
Downstream
::
set_ws_key
(
const
StringRef
&
key
)
{
ws_key_
=
key
;
}
bool
Downstream
::
get_expect_100_continue
()
const
{
return
expect_100_continue_
;
}
}
// namespace shrpx
src/shrpx_downstream.h
View file @
db2f612a
...
...
@@ -511,6 +511,8 @@ public:
void
set_ws_key
(
const
StringRef
&
key
);
bool
get_expect_100_continue
()
const
;
enum
{
EVENT_ERROR
=
0x1
,
EVENT_TIMEOUT
=
0x2
,
...
...
@@ -602,6 +604,8 @@ private:
// true if eof is received from client before sending header fields
// to backend.
bool
blocked_request_data_eof_
;
// true if request contains "expect: 100-continue" header field.
bool
expect_100_continue_
;
};
}
// namespace shrpx
...
...
src/shrpx_http_downstream_connection.cc
View file @
db2f612a
...
...
@@ -694,7 +694,8 @@ int HttpDownstreamConnection::push_request_headers() {
// enables us to send headers and data in one writev system call.
if
(
req
.
method
==
HTTP_CONNECT
||
downstream_
->
get_blocked_request_buf
()
->
rleft
()
||
(
!
req
.
http2_expect_body
&&
req
.
fs
.
content_length
==
0
))
{
(
!
req
.
http2_expect_body
&&
req
.
fs
.
content_length
==
0
)
||
downstream_
->
get_expect_100_continue
())
{
signal_write
();
}
...
...
@@ -1177,6 +1178,19 @@ int HttpDownstreamConnection::write_first() {
auto
buf
=
downstream_
->
get_blocked_request_buf
();
buf
->
reset
();
// upstream->resume_read() might be called in
// write_tls()/write_clear(), but before blocked_request_buf_ is
// reset. So upstream read might still be blocked. Let's do it
// again here.
auto
input
=
downstream_
->
get_request_buf
();
if
(
input
->
rleft
()
==
0
)
{
auto
upstream
=
downstream_
->
get_upstream
();
auto
&
req
=
downstream_
->
request
();
upstream
->
resume_read
(
SHRPX_NO_BUFFER
,
downstream_
,
req
.
unconsumed_body_length
);
}
return
0
;
}
...
...
src/shrpx_https_upstream.cc
View file @
db2f612a
...
...
@@ -505,9 +505,7 @@ int htp_hdrs_completecb(llhttp_t *htp) {
// and let them decide whether responds with 100 Continue or not.
// For alternative mode, we have no backend, so just send 100
// Continue here to make the client happy.
auto
expect
=
req
.
fs
.
header
(
http2
::
HD_EXPECT
);
if
(
expect
&&
util
::
strieq
(
expect
->
value
,
StringRef
::
from_lit
(
"100-continue"
)))
{
if
(
downstream
->
get_expect_100_continue
())
{
auto
output
=
downstream
->
get_response_buf
();
constexpr
auto
res
=
StringRef
::
from_lit
(
"HTTP/1.1 100 Continue
\r\n\r\n
"
);
output
->
append
(
res
);
...
...
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