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
7e217511
Commit
7e217511
authored
Jun 01, 2014
by
Tatsuhiro Tsujikawa
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
nghttpx: Code cleanup
Mainly make nested code block to rather flat style.
parent
8c67bbe3
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
436 additions
and
321 deletions
+436
-321
src/shrpx_http2_session.cc
src/shrpx_http2_session.cc
+36
-14
src/shrpx_http2_upstream.cc
src/shrpx_http2_upstream.cc
+132
-100
src/shrpx_https_upstream.cc
src/shrpx_https_upstream.cc
+118
-79
src/shrpx_spdy_upstream.cc
src/shrpx_spdy_upstream.cc
+150
-128
No files found.
src/shrpx_http2_session.cc
View file @
7e217511
...
@@ -272,19 +272,25 @@ void eventcb(bufferevent *bev, short events, void *ptr)
...
@@ -272,19 +272,25 @@ void eventcb(bufferevent *bev, short events, void *ptr)
return
;
return
;
}
}
int
fd
=
bufferevent_getfd
(
bev
);
auto
fd
=
bufferevent_getfd
(
bev
);
int
val
=
1
;
int
val
=
1
;
if
(
setsockopt
(
fd
,
IPPROTO_TCP
,
TCP_NODELAY
,
if
(
setsockopt
(
fd
,
IPPROTO_TCP
,
TCP_NODELAY
,
reinterpret_cast
<
char
*>
(
&
val
),
sizeof
(
val
))
==
-
1
)
{
reinterpret_cast
<
char
*>
(
&
val
),
sizeof
(
val
))
==
-
1
)
{
SSLOG
(
WARNING
,
http2session
)
SSLOG
(
WARNING
,
http2session
)
<<
"Setting option TCP_NODELAY failed: errno="
<<
errno
;
<<
"Setting option TCP_NODELAY failed: errno="
<<
errno
;
}
}
}
else
if
(
events
&
BEV_EVENT_EOF
)
{
return
;
}
if
(
events
&
BEV_EVENT_EOF
)
{
if
(
LOG_ENABLED
(
INFO
))
{
if
(
LOG_ENABLED
(
INFO
))
{
SSLOG
(
INFO
,
http2session
)
<<
"EOF"
;
SSLOG
(
INFO
,
http2session
)
<<
"EOF"
;
}
}
http2session
->
disconnect
();
http2session
->
disconnect
();
}
else
if
(
events
&
(
BEV_EVENT_ERROR
|
BEV_EVENT_TIMEOUT
))
{
return
;
}
if
(
events
&
(
BEV_EVENT_ERROR
|
BEV_EVENT_TIMEOUT
))
{
if
(
LOG_ENABLED
(
INFO
))
{
if
(
LOG_ENABLED
(
INFO
))
{
if
(
events
&
BEV_EVENT_ERROR
)
{
if
(
events
&
BEV_EVENT_ERROR
)
{
SSLOG
(
INFO
,
http2session
)
<<
"Network error"
;
SSLOG
(
INFO
,
http2session
)
<<
"Network error"
;
...
@@ -293,6 +299,7 @@ void eventcb(bufferevent *bev, short events, void *ptr)
...
@@ -293,6 +299,7 @@ void eventcb(bufferevent *bev, short events, void *ptr)
}
}
}
}
http2session
->
disconnect
();
http2session
->
disconnect
();
return
;
}
}
}
}
}
// namespace
}
// namespace
...
@@ -350,12 +357,18 @@ void proxy_eventcb(bufferevent *bev, short events, void *ptr)
...
@@ -350,12 +357,18 @@ void proxy_eventcb(bufferevent *bev, short events, void *ptr)
SSLOG
(
ERROR
,
http2session
)
<<
"bufferevent_write() failed"
;
SSLOG
(
ERROR
,
http2session
)
<<
"bufferevent_write() failed"
;
http2session
->
disconnect
();
http2session
->
disconnect
();
}
}
}
else
if
(
events
&
BEV_EVENT_EOF
)
{
return
;
}
if
(
events
&
BEV_EVENT_EOF
)
{
if
(
LOG_ENABLED
(
INFO
))
{
if
(
LOG_ENABLED
(
INFO
))
{
SSLOG
(
INFO
,
http2session
)
<<
"Proxy EOF"
;
SSLOG
(
INFO
,
http2session
)
<<
"Proxy EOF"
;
}
}
http2session
->
disconnect
();
http2session
->
disconnect
();
}
else
if
(
events
&
(
BEV_EVENT_ERROR
|
BEV_EVENT_TIMEOUT
))
{
return
;
}
if
(
events
&
(
BEV_EVENT_ERROR
|
BEV_EVENT_TIMEOUT
))
{
if
(
LOG_ENABLED
(
INFO
))
{
if
(
LOG_ENABLED
(
INFO
))
{
if
(
events
&
BEV_EVENT_ERROR
)
{
if
(
events
&
BEV_EVENT_ERROR
)
{
SSLOG
(
INFO
,
http2session
)
<<
"Network error"
;
SSLOG
(
INFO
,
http2session
)
<<
"Network error"
;
...
@@ -364,6 +377,7 @@ void proxy_eventcb(bufferevent *bev, short events, void *ptr)
...
@@ -364,6 +377,7 @@ void proxy_eventcb(bufferevent *bev, short events, void *ptr)
}
}
}
}
http2session
->
disconnect
();
http2session
->
disconnect
();
return
;
}
}
}
}
}
// namespace
}
// namespace
...
@@ -409,7 +423,11 @@ int Http2Session::initiate_connection()
...
@@ -409,7 +423,11 @@ int Http2Session::initiate_connection()
proxy_htp_
->
data
=
this
;
proxy_htp_
->
data
=
this
;
state_
=
PROXY_CONNECTING
;
state_
=
PROXY_CONNECTING
;
}
else
if
(
state_
==
DISCONNECTED
||
state_
==
PROXY_CONNECTED
)
{
return
0
;
}
if
(
state_
==
DISCONNECTED
||
state_
==
PROXY_CONNECTED
)
{
if
(
LOG_ENABLED
(
INFO
))
{
if
(
LOG_ENABLED
(
INFO
))
{
SSLOG
(
INFO
,
this
)
<<
"Connecting to downstream server"
;
SSLOG
(
INFO
,
this
)
<<
"Connecting to downstream server"
;
}
}
...
@@ -492,11 +510,12 @@ int Http2Session::initiate_connection()
...
@@ -492,11 +510,12 @@ int Http2Session::initiate_connection()
if
(
state_
!=
CONNECTED
)
{
if
(
state_
!=
CONNECTED
)
{
state_
=
CONNECTING
;
state_
=
CONNECTING
;
}
}
}
else
{
return
0
;
}
// Unreachable
// Unreachable
DIE
();
DIE
();
}
return
0
;
}
}
void
Http2Session
::
unwrap_free_bev
()
void
Http2Session
::
unwrap_free_bev
()
...
@@ -517,10 +536,13 @@ int htp_hdrs_completecb(http_parser *htp)
...
@@ -517,10 +536,13 @@ int htp_hdrs_completecb(http_parser *htp)
SSLOG
(
INFO
,
http2session
)
<<
"Tunneling success"
;
SSLOG
(
INFO
,
http2session
)
<<
"Tunneling success"
;
}
}
http2session
->
set_state
(
Http2Session
::
PROXY_CONNECTED
);
http2session
->
set_state
(
Http2Session
::
PROXY_CONNECTED
);
}
else
{
return
0
;
}
SSLOG
(
WARNING
,
http2session
)
<<
"Tunneling failed"
;
SSLOG
(
WARNING
,
http2session
)
<<
"Tunneling failed"
;
http2session
->
set_state
(
Http2Session
::
PROXY_FAILED
);
http2session
->
set_state
(
Http2Session
::
PROXY_FAILED
);
}
return
0
;
return
0
;
}
}
}
// namespace
}
// namespace
...
...
src/shrpx_http2_upstream.cc
View file @
7e217511
...
@@ -61,25 +61,40 @@ int on_stream_close_callback
...
@@ -61,25 +61,40 @@ int on_stream_close_callback
<<
" is being closed"
;
<<
" is being closed"
;
}
}
auto
downstream
=
upstream
->
find_downstream
(
stream_id
);
auto
downstream
=
upstream
->
find_downstream
(
stream_id
);
if
(
downstream
)
{
if
(
!
downstream
)
{
return
0
;
}
if
(
downstream
->
get_request_state
()
==
Downstream
::
CONNECT_FAIL
)
{
if
(
downstream
->
get_request_state
()
==
Downstream
::
CONNECT_FAIL
)
{
upstream
->
remove_downstream
(
downstream
);
upstream
->
remove_downstream
(
downstream
);
delete
downstream
;
delete
downstream
;
}
else
{
return
0
;
}
downstream
->
set_request_state
(
Downstream
::
STREAM_CLOSED
);
downstream
->
set_request_state
(
Downstream
::
STREAM_CLOSED
);
if
(
downstream
->
get_response_state
()
==
Downstream
::
MSG_COMPLETE
)
{
if
(
downstream
->
get_response_state
()
==
Downstream
::
MSG_COMPLETE
)
{
// At this point, downstream response was read
// At this point, downstream response was read
if
(
!
downstream
->
get_upgraded
()
&&
if
(
!
downstream
->
get_upgraded
()
&&
!
downstream
->
get_response_connection_close
())
{
!
downstream
->
get_response_connection_close
())
{
// Keep-alive
// Keep-alive
auto
dconn
=
downstream
->
get_downstream_connection
();
auto
dconn
=
downstream
->
get_downstream_connection
();
if
(
dconn
)
{
if
(
dconn
)
{
dconn
->
detach_downstream
(
downstream
);
dconn
->
detach_downstream
(
downstream
);
}
}
}
}
upstream
->
remove_downstream
(
downstream
);
upstream
->
remove_downstream
(
downstream
);
delete
downstream
;
delete
downstream
;
}
else
{
return
0
;
}
// At this point, downstream read may be paused.
// At this point, downstream read may be paused.
// If shrpx_downstream::push_request_headers() failed, the
// If shrpx_downstream::push_request_headers() failed, the
...
@@ -89,9 +104,7 @@ int on_stream_close_callback
...
@@ -89,9 +104,7 @@ int on_stream_close_callback
// How to test this case? Request sufficient large download
// How to test this case? Request sufficient large download
// and make client send RST_STREAM after it gets first DATA
// and make client send RST_STREAM after it gets first DATA
// frame chunk.
// frame chunk.
}
}
}
return
0
;
return
0
;
}
}
}
// namespace
}
// namespace
...
@@ -423,12 +436,16 @@ int on_data_chunk_recv_callback(nghttp2_session *session,
...
@@ -423,12 +436,16 @@ int on_data_chunk_recv_callback(nghttp2_session *session,
{
{
auto
upstream
=
static_cast
<
Http2Upstream
*>
(
user_data
);
auto
upstream
=
static_cast
<
Http2Upstream
*>
(
user_data
);
auto
downstream
=
upstream
->
find_downstream
(
stream_id
);
auto
downstream
=
upstream
->
find_downstream
(
stream_id
);
if
(
downstream
)
{
if
(
!
downstream
)
{
return
0
;
}
if
(
downstream
->
push_upload_data_chunk
(
data
,
len
)
!=
0
)
{
if
(
downstream
->
push_upload_data_chunk
(
data
,
len
)
!=
0
)
{
upstream
->
rst_stream
(
downstream
,
NGHTTP2_INTERNAL_ERROR
);
upstream
->
rst_stream
(
downstream
,
NGHTTP2_INTERNAL_ERROR
);
return
0
;
return
0
;
}
}
}
return
0
;
return
0
;
}
}
}
// namespace
}
// namespace
...
@@ -691,6 +708,7 @@ void downstream_readcb(bufferevent *bev, void *ptr)
...
@@ -691,6 +708,7 @@ void downstream_readcb(bufferevent *bev, void *ptr)
auto
dconn
=
static_cast
<
DownstreamConnection
*>
(
ptr
);
auto
dconn
=
static_cast
<
DownstreamConnection
*>
(
ptr
);
auto
downstream
=
dconn
->
get_downstream
();
auto
downstream
=
dconn
->
get_downstream
();
auto
upstream
=
static_cast
<
Http2Upstream
*>
(
downstream
->
get_upstream
());
auto
upstream
=
static_cast
<
Http2Upstream
*>
(
downstream
->
get_upstream
());
if
(
downstream
->
get_request_state
()
==
Downstream
::
STREAM_CLOSED
)
{
if
(
downstream
->
get_request_state
()
==
Downstream
::
STREAM_CLOSED
)
{
// If upstream HTTP2 stream was closed, we just close downstream,
// If upstream HTTP2 stream was closed, we just close downstream,
// because there is no consumer now. Downstream connection is also
// because there is no consumer now. Downstream connection is also
...
@@ -707,11 +725,11 @@ void downstream_readcb(bufferevent *bev, void *ptr)
...
@@ -707,11 +725,11 @@ void downstream_readcb(bufferevent *bev, void *ptr)
// on_stream_close_callback.
// on_stream_close_callback.
upstream
->
rst_stream
(
downstream
,
infer_upstream_rst_stream_error_code
upstream
->
rst_stream
(
downstream
,
infer_upstream_rst_stream_error_code
(
downstream
->
get_response_rst_stream_error_code
()));
(
downstream
->
get_response_rst_stream_error_code
()));
downstream
->
set_downstream_connection
(
0
);
downstream
->
set_downstream_connection
(
nullptr
);
delete
dconn
;
delete
dconn
;
dconn
=
0
;
dconn
=
nullptr
;
}
else
{
}
else
{
int
rv
=
downstream
->
on_read
();
auto
rv
=
downstream
->
on_read
();
if
(
rv
!=
0
)
{
if
(
rv
!=
0
)
{
if
(
LOG_ENABLED
(
INFO
))
{
if
(
LOG_ENABLED
(
INFO
))
{
DCLOG
(
INFO
,
dconn
)
<<
"HTTP parser failure"
;
DCLOG
(
INFO
,
dconn
)
<<
"HTTP parser failure"
;
...
@@ -728,9 +746,9 @@ void downstream_readcb(bufferevent *bev, void *ptr)
...
@@ -728,9 +746,9 @@ void downstream_readcb(bufferevent *bev, void *ptr)
downstream
->
set_response_state
(
Downstream
::
MSG_COMPLETE
);
downstream
->
set_response_state
(
Downstream
::
MSG_COMPLETE
);
// Clearly, we have to close downstream connection on http parser
// Clearly, we have to close downstream connection on http parser
// failure.
// failure.
downstream
->
set_downstream_connection
(
0
);
downstream
->
set_downstream_connection
(
nullptr
);
delete
dconn
;
delete
dconn
;
dconn
=
0
;
dconn
=
nullptr
;
}
}
}
}
if
(
upstream
->
send
()
!=
0
)
{
if
(
upstream
->
send
()
!=
0
)
{
...
@@ -765,14 +783,18 @@ void downstream_eventcb(bufferevent *bev, short events, void *ptr)
...
@@ -765,14 +783,18 @@ void downstream_eventcb(bufferevent *bev, short events, void *ptr)
DCLOG
(
INFO
,
dconn
)
<<
"Connection established. stream_id="
DCLOG
(
INFO
,
dconn
)
<<
"Connection established. stream_id="
<<
downstream
->
get_stream_id
();
<<
downstream
->
get_stream_id
();
}
}
int
fd
=
bufferevent_getfd
(
bev
);
auto
fd
=
bufferevent_getfd
(
bev
);
int
val
=
1
;
int
val
=
1
;
if
(
setsockopt
(
fd
,
IPPROTO_TCP
,
TCP_NODELAY
,
if
(
setsockopt
(
fd
,
IPPROTO_TCP
,
TCP_NODELAY
,
reinterpret_cast
<
char
*>
(
&
val
),
sizeof
(
val
))
==
-
1
)
{
reinterpret_cast
<
char
*>
(
&
val
),
sizeof
(
val
))
==
-
1
)
{
DCLOG
(
WARNING
,
dconn
)
<<
"Setting option TCP_NODELAY failed: errno="
DCLOG
(
WARNING
,
dconn
)
<<
"Setting option TCP_NODELAY failed: errno="
<<
errno
;
<<
errno
;
}
}
}
else
if
(
events
&
BEV_EVENT_EOF
)
{
return
;
}
if
(
events
&
BEV_EVENT_EOF
)
{
if
(
LOG_ENABLED
(
INFO
))
{
if
(
LOG_ENABLED
(
INFO
))
{
DCLOG
(
INFO
,
dconn
)
<<
"EOF. stream_id="
<<
downstream
->
get_stream_id
();
DCLOG
(
INFO
,
dconn
)
<<
"EOF. stream_id="
<<
downstream
->
get_stream_id
();
}
}
...
@@ -781,12 +803,15 @@ void downstream_eventcb(bufferevent *bev, short events, void *ptr)
...
@@ -781,12 +803,15 @@ void downstream_eventcb(bufferevent *bev, short events, void *ptr)
// the first place. We can delete downstream.
// the first place. We can delete downstream.
upstream
->
remove_downstream
(
downstream
);
upstream
->
remove_downstream
(
downstream
);
delete
downstream
;
delete
downstream
;
}
else
{
return
;
}
// Delete downstream connection. If we don't delete it here, it
// Delete downstream connection. If we don't delete it here, it
// will be pooled in on_stream_close_callback.
// will be pooled in on_stream_close_callback.
downstream
->
set_downstream_connection
(
0
);
downstream
->
set_downstream_connection
(
nullptr
);
delete
dconn
;
delete
dconn
;
dconn
=
0
;
dconn
=
nullptr
;
// downstream wil be deleted in on_stream_close_callback.
// downstream wil be deleted in on_stream_close_callback.
if
(
downstream
->
get_response_state
()
==
Downstream
::
HEADER_COMPLETE
)
{
if
(
downstream
->
get_response_state
()
==
Downstream
::
HEADER_COMPLETE
)
{
// Server may indicate the end of the request by EOF
// Server may indicate the end of the request by EOF
...
@@ -814,8 +839,10 @@ void downstream_eventcb(bufferevent *bev, short events, void *ptr)
...
@@ -814,8 +839,10 @@ void downstream_eventcb(bufferevent *bev, short events, void *ptr)
return
;
return
;
}
}
// At this point, downstream may be deleted.
// At this point, downstream may be deleted.
return
;
}
}
}
else
if
(
events
&
(
BEV_EVENT_ERROR
|
BEV_EVENT_TIMEOUT
))
{
if
(
events
&
(
BEV_EVENT_ERROR
|
BEV_EVENT_TIMEOUT
))
{
if
(
LOG_ENABLED
(
INFO
))
{
if
(
LOG_ENABLED
(
INFO
))
{
if
(
events
&
BEV_EVENT_ERROR
)
{
if
(
events
&
BEV_EVENT_ERROR
)
{
DCLOG
(
INFO
,
dconn
)
<<
"Downstream network error: "
DCLOG
(
INFO
,
dconn
)
<<
"Downstream network error: "
...
@@ -828,15 +855,20 @@ void downstream_eventcb(bufferevent *bev, short events, void *ptr)
...
@@ -828,15 +855,20 @@ void downstream_eventcb(bufferevent *bev, short events, void *ptr)
DCLOG
(
INFO
,
dconn
)
<<
"Note: this is tunnel connection"
;
DCLOG
(
INFO
,
dconn
)
<<
"Note: this is tunnel connection"
;
}
}
}
}
if
(
downstream
->
get_request_state
()
==
Downstream
::
STREAM_CLOSED
)
{
if
(
downstream
->
get_request_state
()
==
Downstream
::
STREAM_CLOSED
)
{
upstream
->
remove_downstream
(
downstream
);
upstream
->
remove_downstream
(
downstream
);
delete
downstream
;
delete
downstream
;
}
else
{
return
;
}
// Delete downstream connection. If we don't delete it here, it
// Delete downstream connection. If we don't delete it here, it
// will be pooled in on_stream_close_callback.
// will be pooled in on_stream_close_callback.
downstream
->
set_downstream_connection
(
0
);
downstream
->
set_downstream_connection
(
nullptr
);
delete
dconn
;
delete
dconn
;
dconn
=
0
;
dconn
=
nullptr
;
if
(
downstream
->
get_response_state
()
==
Downstream
::
MSG_COMPLETE
)
{
if
(
downstream
->
get_response_state
()
==
Downstream
::
MSG_COMPLETE
)
{
// For SSL tunneling, we issue RST_STREAM. For other types of
// For SSL tunneling, we issue RST_STREAM. For other types of
// stream, we don't have to do anything since response was
// stream, we don't have to do anything since response was
...
@@ -866,7 +898,7 @@ void downstream_eventcb(bufferevent *bev, short events, void *ptr)
...
@@ -866,7 +898,7 @@ void downstream_eventcb(bufferevent *bev, short events, void *ptr)
return
;
return
;
}
}
// At this point, downstream may be deleted.
// At this point, downstream may be deleted.
}
return
;
}
}
}
}
}
// namespace
}
// namespace
...
...
src/shrpx_https_upstream.cc
View file @
7e217511
...
@@ -193,19 +193,23 @@ int htp_hdrs_completecb(http_parser *htp)
...
@@ -193,19 +193,23 @@ int htp_hdrs_completecb(http_parser *htp)
}
}
rv
=
dconn
->
attach_downstream
(
downstream
);
rv
=
dconn
->
attach_downstream
(
downstream
);
if
(
rv
!=
0
)
{
if
(
rv
!=
0
)
{
downstream
->
set_request_state
(
Downstream
::
CONNECT_FAIL
);
downstream
->
set_request_state
(
Downstream
::
CONNECT_FAIL
);
downstream
->
set_downstream_connection
(
0
);
downstream
->
set_downstream_connection
(
nullptr
);
delete
dconn
;
delete
dconn
;
return
-
1
;
return
-
1
;
}
else
{
}
rv
=
downstream
->
push_request_headers
();
rv
=
downstream
->
push_request_headers
();
if
(
rv
!=
0
)
{
if
(
rv
!=
0
)
{
return
-
1
;
return
-
1
;
}
}
downstream
->
set_request_state
(
Downstream
::
HEADER_COMPLETE
);
downstream
->
set_request_state
(
Downstream
::
HEADER_COMPLETE
);
return
0
;
return
0
;
}
}
}
}
// namespace
}
// namespace
...
@@ -431,9 +435,9 @@ int HttpsUpstream::resume_read(IOCtrlReason reason, Downstream *downstream)
...
@@ -431,9 +435,9 @@ int HttpsUpstream::resume_read(IOCtrlReason reason, Downstream *downstream)
// are not notified by readcb until new data arrive.
// are not notified by readcb until new data arrive.
http_parser_pause
(
&
htp_
,
0
);
http_parser_pause
(
&
htp_
,
0
);
return
on_read
();
return
on_read
();
}
else
{
return
0
;
}
}
return
0
;
}
}
namespace
{
namespace
{
...
@@ -443,22 +447,67 @@ void https_downstream_readcb(bufferevent *bev, void *ptr)
...
@@ -443,22 +447,67 @@ void https_downstream_readcb(bufferevent *bev, void *ptr)
auto
downstream
=
dconn
->
get_downstream
();
auto
downstream
=
dconn
->
get_downstream
();
auto
upstream
=
static_cast
<
HttpsUpstream
*>
(
downstream
->
get_upstream
());
auto
upstream
=
static_cast
<
HttpsUpstream
*>
(
downstream
->
get_upstream
());
int
rv
;
int
rv
;
rv
=
downstream
->
on_read
();
rv
=
downstream
->
on_read
();
if
(
downstream
->
get_response_state
()
==
Downstream
::
MSG_RESET
)
{
if
(
downstream
->
get_response_state
()
==
Downstream
::
MSG_RESET
)
{
delete
upstream
->
get_client_handler
();
delete
upstream
->
get_client_handler
();
}
else
if
(
rv
==
0
)
{
return
;
}
if
(
rv
!=
0
)
{
if
(
downstream
->
get_response_state
()
==
Downstream
::
HEADER_COMPLETE
)
{
// We already sent HTTP response headers to upstream
// client. Just close the upstream connection.
delete
upstream
->
get_client_handler
();
return
;
}
// We did not sent any HTTP response, so sent error
// response. Cannot reuse downstream connection in this case.
if
(
upstream
->
error_reply
(
502
)
!=
0
)
{
delete
upstream
->
get_client_handler
();
return
;
}
if
(
downstream
->
get_request_state
()
==
Downstream
::
MSG_COMPLETE
)
{
upstream
->
delete_downstream
();
// Process next HTTP request
if
(
upstream
->
resume_read
(
SHRPX_MSG_BLOCK
,
0
)
==
-
1
)
{
return
;
}
}
return
;
}
auto
handler
=
upstream
->
get_client_handler
();
auto
handler
=
upstream
->
get_client_handler
();
if
(
downstream
->
get_response_state
()
==
Downstream
::
MSG_COMPLETE
)
{
if
(
downstream
->
get_response_state
()
!=
Downstream
::
MSG_COMPLETE
)
{
if
(
handler
->
get_outbuf_length
()
>=
OUTBUF_MAX_THRES
)
{
downstream
->
pause_read
(
SHRPX_NO_BUFFER
);
}
return
;
}
if
(
downstream
->
get_response_connection_close
())
{
if
(
downstream
->
get_response_connection_close
())
{
// Connection close
// Connection close
downstream
->
set_downstream_connection
(
0
);
downstream
->
set_downstream_connection
(
nullptr
);
delete
dconn
;
delete
dconn
;
dconn
=
0
;
dconn
=
nullptr
;
}
else
{
}
else
{
// Keep-alive
// Keep-alive
dconn
->
detach_downstream
(
downstream
);
dconn
->
detach_downstream
(
downstream
);
}
}
if
(
downstream
->
get_request_state
()
==
Downstream
::
MSG_COMPLETE
)
{
if
(
downstream
->
get_request_state
()
==
Downstream
::
MSG_COMPLETE
)
{
if
(
handler
->
get_should_close_after_write
()
&&
if
(
handler
->
get_should_close_after_write
()
&&
handler
->
get_outbuf_length
()
==
0
)
{
handler
->
get_outbuf_length
()
==
0
)
{
...
@@ -466,15 +515,21 @@ void https_downstream_readcb(bufferevent *bev, void *ptr)
...
@@ -466,15 +515,21 @@ void https_downstream_readcb(bufferevent *bev, void *ptr)
// the peer, we cannot use writecb for ClientHandler. In
// the peer, we cannot use writecb for ClientHandler. In
// this case, we just delete handler here.
// this case, we just delete handler here.
delete
handler
;
delete
handler
;
return
;
return
;
}
else
{
}
upstream
->
delete_downstream
();
upstream
->
delete_downstream
();
// Process next HTTP request
// Process next HTTP request
if
(
upstream
->
resume_read
(
SHRPX_MSG_BLOCK
,
0
)
==
-
1
)
{
if
(
upstream
->
resume_read
(
SHRPX_MSG_BLOCK
,
0
)
==
-
1
)
{
return
;
return
;
}
}
return
;
}
}
}
else
if
(
downstream
->
get_upgraded
())
{
if
(
downstream
->
get_upgraded
())
{
// This path is effectively only taken for HTTP2 downstream
// This path is effectively only taken for HTTP2 downstream
// because only HTTP2 downstream sets response_state to
// because only HTTP2 downstream sets response_state to
// MSG_COMPLETE and this function. For HTTP downstream, EOF
// MSG_COMPLETE and this function. For HTTP downstream, EOF
...
@@ -486,38 +541,16 @@ void https_downstream_readcb(bufferevent *bev, void *ptr)
...
@@ -486,38 +541,16 @@ void https_downstream_readcb(bufferevent *bev, void *ptr)
// For tunneled connection, if there is no pending data,
// For tunneled connection, if there is no pending data,
// delete handler because on_write will not be called.
// delete handler because on_write will not be called.
delete
handler
;
delete
handler
;
}
else
{
return
;
}
if
(
LOG_ENABLED
(
INFO
))
{
if
(
LOG_ENABLED
(
INFO
))
{
DLOG
(
INFO
,
downstream
)
<<
"Tunneled connection has pending data"
;
DLOG
(
INFO
,
downstream
)
<<
"Tunneled connection has pending data"
;
}
}
}
}
}
else
{
if
(
handler
->
get_outbuf_length
()
>=
OUTBUF_MAX_THRES
)
{
downstream
->
pause_read
(
SHRPX_NO_BUFFER
);
}
}
}
else
{
if
(
downstream
->
get_response_state
()
==
Downstream
::
HEADER_COMPLETE
)
{
// We already sent HTTP response headers to upstream
// client. Just close the upstream connection.
delete
upstream
->
get_client_handler
();
}
else
{
// We did not sent any HTTP response, so sent error
// response. Cannot reuse downstream connection in this case.
if
(
upstream
->
error_reply
(
502
)
!=
0
)
{
delete
upstream
->
get_client_handler
();
return
;
}
if
(
downstream
->
get_request_state
()
==
Downstream
::
MSG_COMPLETE
)
{
upstream
->
delete_downstream
();
// Process next HTTP request
if
(
upstream
->
resume_read
(
SHRPX_MSG_BLOCK
,
0
)
==
-
1
)
{
return
;
return
;
}
}
}
}
}
}
}
}
// namespace
}
// namespace
...
@@ -545,7 +578,11 @@ void https_downstream_eventcb(bufferevent *bev, short events, void *ptr)
...
@@ -545,7 +578,11 @@ void https_downstream_eventcb(bufferevent *bev, short events, void *ptr)
if
(
LOG_ENABLED
(
INFO
))
{
if
(
LOG_ENABLED
(
INFO
))
{
DCLOG
(
INFO
,
dconn
)
<<
"Connection established"
;
DCLOG
(
INFO
,
dconn
)
<<
"Connection established"
;
}
}
}
else
if
(
events
&
BEV_EVENT_EOF
)
{
return
;
}
if
(
events
&
BEV_EVENT_EOF
)
{
if
(
LOG_ENABLED
(
INFO
))
{
if
(
LOG_ENABLED
(
INFO
))
{
DCLOG
(
INFO
,
dconn
)
<<
"EOF"
;
DCLOG
(
INFO
,
dconn
)
<<
"EOF"
;
}
}
...
@@ -567,9 +604,7 @@ void https_downstream_eventcb(bufferevent *bev, short events, void *ptr)
...
@@ -567,9 +604,7 @@ void https_downstream_eventcb(bufferevent *bev, short events, void *ptr)
delete
handler
;
delete
handler
;
return
;
return
;
}
}
}
else
if
(
downstream
->
get_response_state
()
==
Downstream
::
MSG_COMPLETE
)
{
}
else
if
(
downstream
->
get_response_state
()
!=
Downstream
::
MSG_COMPLETE
)
{
// Nothing to do
}
else
{
// error
// error
if
(
LOG_ENABLED
(
INFO
))
{
if
(
LOG_ENABLED
(
INFO
))
{
DCLOG
(
INFO
,
dconn
)
<<
"Treated as error"
;
DCLOG
(
INFO
,
dconn
)
<<
"Treated as error"
;
...
@@ -585,7 +620,11 @@ void https_downstream_eventcb(bufferevent *bev, short events, void *ptr)
...
@@ -585,7 +620,11 @@ void https_downstream_eventcb(bufferevent *bev, short events, void *ptr)
return
;
return
;
}
}
}
}
}
else
if
(
events
&
(
BEV_EVENT_ERROR
|
BEV_EVENT_TIMEOUT
))
{
return
;
}
if
(
events
&
(
BEV_EVENT_ERROR
|
BEV_EVENT_TIMEOUT
))
{
if
(
LOG_ENABLED
(
INFO
))
{
if
(
LOG_ENABLED
(
INFO
))
{
if
(
events
&
BEV_EVENT_ERROR
)
{
if
(
events
&
BEV_EVENT_ERROR
)
{
DCLOG
(
INFO
,
dconn
)
<<
"Network error"
;
DCLOG
(
INFO
,
dconn
)
<<
"Network error"
;
...
...
src/shrpx_spdy_upstream.cc
View file @
7e217511
...
@@ -103,11 +103,16 @@ void on_stream_close_callback
...
@@ -103,11 +103,16 @@ void on_stream_close_callback
<<
" is being closed"
;
<<
" is being closed"
;
}
}
auto
downstream
=
upstream
->
find_downstream
(
stream_id
);
auto
downstream
=
upstream
->
find_downstream
(
stream_id
);
if
(
downstream
)
{
if
(
!
downstream
)
{
return
;
}
if
(
downstream
->
get_request_state
()
==
Downstream
::
CONNECT_FAIL
)
{
if
(
downstream
->
get_request_state
()
==
Downstream
::
CONNECT_FAIL
)
{
upstream
->
remove_downstream
(
downstream
);
upstream
->
remove_downstream
(
downstream
);
delete
downstream
;
delete
downstream
;
}
else
{
return
;
}
downstream
->
set_request_state
(
Downstream
::
STREAM_CLOSED
);
downstream
->
set_request_state
(
Downstream
::
STREAM_CLOSED
);
if
(
downstream
->
get_response_state
()
==
Downstream
::
MSG_COMPLETE
)
{
if
(
downstream
->
get_response_state
()
==
Downstream
::
MSG_COMPLETE
)
{
// At this point, downstream response was read
// At this point, downstream response was read
...
@@ -121,7 +126,9 @@ void on_stream_close_callback
...
@@ -121,7 +126,9 @@ void on_stream_close_callback
}
}
upstream
->
remove_downstream
(
downstream
);
upstream
->
remove_downstream
(
downstream
);
delete
downstream
;
delete
downstream
;
}
else
{
return
;
}
// At this point, downstream read may be paused.
// At this point, downstream read may be paused.
// If shrpx_downstream::push_request_headers() failed, the
// If shrpx_downstream::push_request_headers() failed, the
...
@@ -131,9 +138,6 @@ void on_stream_close_callback
...
@@ -131,9 +138,6 @@ void on_stream_close_callback
// How to test this case? Request sufficient large download
// How to test this case? Request sufficient large download
// and make client send RST_STREAM after it gets first DATA
// and make client send RST_STREAM after it gets first DATA
// frame chunk.
// frame chunk.
}
}
}
}
}
}
// namespace
}
// namespace
...
@@ -245,12 +249,20 @@ void on_data_chunk_recv_callback(spdylay_session *session,
...
@@ -245,12 +249,20 @@ void on_data_chunk_recv_callback(spdylay_session *session,
{
{
auto
upstream
=
static_cast
<
SpdyUpstream
*>
(
user_data
);
auto
upstream
=
static_cast
<
SpdyUpstream
*>
(
user_data
);
auto
downstream
=
upstream
->
find_downstream
(
stream_id
);
auto
downstream
=
upstream
->
find_downstream
(
stream_id
);
if
(
downstream
)
{
if
(
!
downstream
)
{
return
;
}
if
(
downstream
->
push_upload_data_chunk
(
data
,
len
)
!=
0
)
{
if
(
downstream
->
push_upload_data_chunk
(
data
,
len
)
!=
0
)
{
upstream
->
rst_stream
(
downstream
,
SPDYLAY_INTERNAL_ERROR
);
upstream
->
rst_stream
(
downstream
,
SPDYLAY_INTERNAL_ERROR
);
return
;
return
;
}
}
if
(
upstream
->
get_flow_control
())
{
if
(
!
upstream
->
get_flow_control
())
{
return
;
}
// If connection-level window control is not enabled (e.g,
// If connection-level window control is not enabled (e.g,
// spdy/3), spdylay_session_get_recv_data_length() is always
// spdy/3), spdylay_session_get_recv_data_length() is always
// returns 0.
// returns 0.
...
@@ -281,8 +293,6 @@ void on_data_chunk_recv_callback(spdylay_session *session,
...
@@ -281,8 +293,6 @@ void on_data_chunk_recv_callback(spdylay_session *session,
upstream
->
rst_stream
(
downstream
,
SPDYLAY_FLOW_CONTROL_ERROR
);
upstream
->
rst_stream
(
downstream
,
SPDYLAY_FLOW_CONTROL_ERROR
);
return
;
return
;
}
}
}
}
}
}
}
// namespace
}
// namespace
...
@@ -520,11 +530,11 @@ void spdy_downstream_readcb(bufferevent *bev, void *ptr)
...
@@ -520,11 +530,11 @@ void spdy_downstream_readcb(bufferevent *bev, void *ptr)
// on_stream_close_callback.
// on_stream_close_callback.
upstream
->
rst_stream
(
downstream
,
infer_upstream_rst_stream_status_code
upstream
->
rst_stream
(
downstream
,
infer_upstream_rst_stream_status_code
(
downstream
->
get_response_rst_stream_error_code
()));
(
downstream
->
get_response_rst_stream_error_code
()));
downstream
->
set_downstream_connection
(
0
);
downstream
->
set_downstream_connection
(
nullptr
);
delete
dconn
;
delete
dconn
;
dconn
=
0
;
dconn
=
nullptr
;
}
else
{
}
else
{
int
rv
=
downstream
->
on_read
();
auto
rv
=
downstream
->
on_read
();
if
(
rv
!=
0
)
{
if
(
rv
!=
0
)
{
if
(
LOG_ENABLED
(
INFO
))
{
if
(
LOG_ENABLED
(
INFO
))
{
DCLOG
(
INFO
,
dconn
)
<<
"HTTP parser failure"
;
DCLOG
(
INFO
,
dconn
)
<<
"HTTP parser failure"
;
...
@@ -541,9 +551,9 @@ void spdy_downstream_readcb(bufferevent *bev, void *ptr)
...
@@ -541,9 +551,9 @@ void spdy_downstream_readcb(bufferevent *bev, void *ptr)
downstream
->
set_response_state
(
Downstream
::
MSG_COMPLETE
);
downstream
->
set_response_state
(
Downstream
::
MSG_COMPLETE
);
// Clearly, we have to close downstream connection on http parser
// Clearly, we have to close downstream connection on http parser
// failure.
// failure.
downstream
->
set_downstream_connection
(
0
);
downstream
->
set_downstream_connection
(
nullptr
);
delete
dconn
;
delete
dconn
;
dconn
=
0
;
dconn
=
nullptr
;
}
}
}
}
if
(
upstream
->
send
()
!=
0
)
{
if
(
upstream
->
send
()
!=
0
)
{
...
@@ -573,6 +583,7 @@ void spdy_downstream_eventcb(bufferevent *bev, short events, void *ptr)
...
@@ -573,6 +583,7 @@ void spdy_downstream_eventcb(bufferevent *bev, short events, void *ptr)
auto
dconn
=
static_cast
<
DownstreamConnection
*>
(
ptr
);
auto
dconn
=
static_cast
<
DownstreamConnection
*>
(
ptr
);
auto
downstream
=
dconn
->
get_downstream
();
auto
downstream
=
dconn
->
get_downstream
();
auto
upstream
=
static_cast
<
SpdyUpstream
*>
(
downstream
->
get_upstream
());
auto
upstream
=
static_cast
<
SpdyUpstream
*>
(
downstream
->
get_upstream
());
if
(
events
&
BEV_EVENT_CONNECTED
)
{
if
(
events
&
BEV_EVENT_CONNECTED
)
{
if
(
LOG_ENABLED
(
INFO
))
{
if
(
LOG_ENABLED
(
INFO
))
{
DCLOG
(
INFO
,
dconn
)
<<
"Connection established. stream_id="
DCLOG
(
INFO
,
dconn
)
<<
"Connection established. stream_id="
...
@@ -585,7 +596,10 @@ void spdy_downstream_eventcb(bufferevent *bev, short events, void *ptr)
...
@@ -585,7 +596,10 @@ void spdy_downstream_eventcb(bufferevent *bev, short events, void *ptr)
DCLOG
(
WARNING
,
dconn
)
<<
"Setting option TCP_NODELAY failed: errno="
DCLOG
(
WARNING
,
dconn
)
<<
"Setting option TCP_NODELAY failed: errno="
<<
errno
;
<<
errno
;
}
}
}
else
if
(
events
&
BEV_EVENT_EOF
)
{
return
;
}
if
(
events
&
BEV_EVENT_EOF
)
{
if
(
LOG_ENABLED
(
INFO
))
{
if
(
LOG_ENABLED
(
INFO
))
{
DCLOG
(
INFO
,
dconn
)
<<
"EOF. stream_id="
<<
downstream
->
get_stream_id
();
DCLOG
(
INFO
,
dconn
)
<<
"EOF. stream_id="
<<
downstream
->
get_stream_id
();
}
}
...
@@ -594,12 +608,14 @@ void spdy_downstream_eventcb(bufferevent *bev, short events, void *ptr)
...
@@ -594,12 +608,14 @@ void spdy_downstream_eventcb(bufferevent *bev, short events, void *ptr)
// the first place. We can delete downstream.
// the first place. We can delete downstream.
upstream
->
remove_downstream
(
downstream
);
upstream
->
remove_downstream
(
downstream
);
delete
downstream
;
delete
downstream
;
}
else
{
return
;
}
// Delete downstream connection. If we don't delete it here, it
// Delete downstream connection. If we don't delete it here, it
// will be pooled in on_stream_close_callback.
// will be pooled in on_stream_close_callback.
downstream
->
set_downstream_connection
(
0
);
downstream
->
set_downstream_connection
(
nullptr
);
delete
dconn
;
delete
dconn
;
dconn
=
0
;
dconn
=
nullptr
;
// downstream wil be deleted in on_stream_close_callback.
// downstream wil be deleted in on_stream_close_callback.
if
(
downstream
->
get_response_state
()
==
Downstream
::
HEADER_COMPLETE
)
{
if
(
downstream
->
get_response_state
()
==
Downstream
::
HEADER_COMPLETE
)
{
// Server may indicate the end of the request by EOF
// Server may indicate the end of the request by EOF
...
@@ -627,8 +643,11 @@ void spdy_downstream_eventcb(bufferevent *bev, short events, void *ptr)
...
@@ -627,8 +643,11 @@ void spdy_downstream_eventcb(bufferevent *bev, short events, void *ptr)
return
;
return
;
}
}
// At this point, downstream may be deleted.
// At this point, downstream may be deleted.
return
;
}
}
}
else
if
(
events
&
(
BEV_EVENT_ERROR
|
BEV_EVENT_TIMEOUT
))
{
if
(
events
&
(
BEV_EVENT_ERROR
|
BEV_EVENT_TIMEOUT
))
{
if
(
LOG_ENABLED
(
INFO
))
{
if
(
LOG_ENABLED
(
INFO
))
{
if
(
events
&
BEV_EVENT_ERROR
)
{
if
(
events
&
BEV_EVENT_ERROR
)
{
DCLOG
(
INFO
,
dconn
)
<<
"Downstream network error: "
DCLOG
(
INFO
,
dconn
)
<<
"Downstream network error: "
...
@@ -644,12 +663,15 @@ void spdy_downstream_eventcb(bufferevent *bev, short events, void *ptr)
...
@@ -644,12 +663,15 @@ void spdy_downstream_eventcb(bufferevent *bev, short events, void *ptr)
if
(
downstream
->
get_request_state
()
==
Downstream
::
STREAM_CLOSED
)
{
if
(
downstream
->
get_request_state
()
==
Downstream
::
STREAM_CLOSED
)
{
upstream
->
remove_downstream
(
downstream
);
upstream
->
remove_downstream
(
downstream
);
delete
downstream
;
delete
downstream
;
}
else
{
return
;
}
// Delete downstream connection. If we don't delete it here, it
// Delete downstream connection. If we don't delete it here, it
// will be pooled in on_stream_close_callback.
// will be pooled in on_stream_close_callback.
downstream
->
set_downstream_connection
(
0
);
downstream
->
set_downstream_connection
(
nullptr
);
delete
dconn
;
delete
dconn
;
dconn
=
0
;
dconn
=
nullptr
;
if
(
downstream
->
get_response_state
()
==
Downstream
::
MSG_COMPLETE
)
{
if
(
downstream
->
get_response_state
()
==
Downstream
::
MSG_COMPLETE
)
{
// For SSL tunneling, we issue RST_STREAM. For other types of
// For SSL tunneling, we issue RST_STREAM. For other types of
// stream, we don't have to do anything since response was
// stream, we don't have to do anything since response was
...
@@ -679,7 +701,7 @@ void spdy_downstream_eventcb(bufferevent *bev, short events, void *ptr)
...
@@ -679,7 +701,7 @@ void spdy_downstream_eventcb(bufferevent *bev, short events, void *ptr)
return
;
return
;
}
}
// At this point, downstream may be deleted.
// At this point, downstream may be deleted.
}
return
;
}
}
}
}
}
// namespace
}
// namespace
...
...
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