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
905e16cb
Commit
905e16cb
authored
Sep 11, 2016
by
Tatsuhiro Tsujikawa
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Simplify session_after_frame_sent1
parent
9d4e8eeb
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
178 additions
and
182 deletions
+178
-182
lib/nghttp2_session.c
lib/nghttp2_session.c
+178
-182
No files found.
lib/nghttp2_session.c
View file @
905e16cb
...
...
@@ -2483,260 +2483,256 @@ static int session_after_frame_sent1(nghttp2_session *session) {
nghttp2_outbound_item
*
item
=
aob
->
item
;
nghttp2_bufs
*
framebufs
=
&
aob
->
framebufs
;
nghttp2_frame
*
frame
;
nghttp2_stream
*
stream
;
frame
=
&
item
->
frame
;
if
(
frame
->
hd
.
type
!=
NGHTTP2_DATA
)
{
if
(
frame
->
hd
.
type
==
NGHTTP2_DATA
)
{
nghttp2_data_aux_data
*
aux_data
;
if
(
frame
->
hd
.
type
==
NGHTTP2_HEADERS
||
frame
->
hd
.
type
==
NGHTTP2_PUSH_PROMISE
)
{
aux_data
=
&
item
->
aux_data
.
data
;
if
(
nghttp2_bufs_next_present
(
framebufs
))
{
DEBUGF
(
fprintf
(
stderr
,
"send: CONTINUATION exists, just return
\n
"
));
return
0
;
}
}
rv
=
session_call_on_frame_send
(
session
,
frame
);
if
(
nghttp2_is_fatal
(
rv
))
{
return
rv
;
stream
=
nghttp2_session_get_stream
(
session
,
frame
->
hd
.
stream_id
);
/* We update flow control window after a frame was completely
sent. This is possible because we choose payload length not to
exceed the window */
session
->
remote_window_size
-=
(
int32_t
)
frame
->
hd
.
length
;
if
(
stream
)
{
stream
->
remote_window_size
-=
(
int32_t
)
frame
->
hd
.
length
;
}
switch
(
frame
->
hd
.
type
)
{
case
NGHTTP2_HEADERS
:
{
nghttp2_headers_aux_data
*
aux_data
;
nghttp2_stream
*
stream
;
stream
=
nghttp2_session_get_stream
(
session
,
frame
->
hd
.
stream_id
);
if
(
!
stream
)
{
break
;
if
(
stream
&&
aux_data
->
eof
)
{
rv
=
nghttp2_stream_detach_item
(
stream
);
if
(
nghttp2_is_fatal
(
rv
))
{
return
rv
;
}
switch
(
frame
->
headers
.
cat
)
{
case
NGHTTP2_HCAT_REQUEST
:
{
stream
->
state
=
NGHTTP2_STREAM_OPENING
;
if
(
frame
->
hd
.
flags
&
NGHTTP2_FLAG_END_STREAM
)
{
nghttp2_stream_shutdown
(
stream
,
NGHTTP2_SHUT_WR
);
}
rv
=
nghttp2_session_close_stream_if_shut_rdwr
(
session
,
stream
);
/* Call on_frame_send_callback after
nghttp2_stream_detach_item(), so that application can issue
nghttp2_submit_data() in the callback. */
if
(
session
->
callbacks
.
on_frame_send_callback
)
{
rv
=
session_call_on_frame_send
(
session
,
frame
);
if
(
nghttp2_is_fatal
(
rv
))
{
return
rv
;
}
/* We assume aux_data is a pointer to nghttp2_headers_aux_data */
aux_data
=
&
item
->
aux_data
.
headers
;
if
(
aux_data
->
data_prd
.
read_callback
)
{
/* nghttp2_submit_data() makes a copy of aux_data->data_prd */
rv
=
nghttp2_submit_data
(
session
,
NGHTTP2_FLAG_END_STREAM
,
frame
->
hd
.
stream_id
,
&
aux_data
->
data_prd
);
if
(
nghttp2_is_fatal
(
rv
))
{
return
rv
;
}
/* TODO nghttp2_submit_data() may fail if stream has already
DATA frame item. We might have to handle it here. */
}
break
;
}
case
NGHTTP2_HCAT_PUSH_RESPONSE
:
stream
->
flags
=
(
uint8_t
)(
stream
->
flags
&
~
NGHTTP2_STREAM_FLAG_PUSH
);
++
session
->
num_outgoing_streams
;
/* Fall through */
case
NGHTTP2_HCAT_RESPONSE
:
stream
->
state
=
NGHTTP2_STREAM_OPENED
;
/* Fall through */
case
NGHTTP2_HCAT_HEADERS
:
if
(
frame
->
hd
.
flags
&
NGHTTP2_FLAG_END_STREAM
)
{
nghttp2_stream_shutdown
(
stream
,
NGHTTP2_SHUT_WR
);
}
if
(
frame
->
hd
.
flags
&
NGHTTP2_FLAG_END_STREAM
)
{
int
stream_closed
;
stream_closed
=
(
stream
->
shut_flags
&
NGHTTP2_SHUT_RDWR
)
==
NGHTTP2_SHUT_RDWR
;
nghttp2_stream_shutdown
(
stream
,
NGHTTP2_SHUT_WR
);
rv
=
nghttp2_session_close_stream_if_shut_rdwr
(
session
,
stream
);
if
(
nghttp2_is_fatal
(
rv
))
{
return
rv
;
}
/* We assume aux_data is a pointer to nghttp2_headers_aux_data */
aux_data
=
&
item
->
aux_data
.
headers
;
if
(
aux_data
->
data_prd
.
read_callback
)
{
rv
=
nghttp2_submit_data
(
session
,
NGHTTP2_FLAG_END_STREAM
,
frame
->
hd
.
stream_id
,
&
aux_data
->
data_prd
);
if
(
nghttp2_is_fatal
(
rv
))
{
return
rv
;
}
/* TODO nghttp2_submit_data() may fail if stream has already
DATA frame item. We might have to handle it here. */
/* stream may be NULL if it was closed */
if
(
stream_closed
)
{
stream
=
NULL
;
}
break
;
}
break
;
return
0
;
}
case
NGHTTP2_PRIORITY
:
{
nghttp2_stream
*
stream
;
if
(
session
->
server
)
{
break
;
if
(
session
->
callbacks
.
on_frame_send_callback
)
{
rv
=
session_call_on_frame_send
(
session
,
frame
);
if
(
nghttp2_is_fatal
(
rv
))
{
return
rv
;
}
}
stream
=
nghttp2_session_get_stream_raw
(
session
,
frame
->
hd
.
stream_id
);
return
0
;
}
if
(
!
stream
)
{
if
(
!
session_detect_idle_stream
(
session
,
frame
->
hd
.
stream_id
))
{
break
;
}
/* non-DATA frame */
stream
=
nghttp2_session_open_stream
(
session
,
frame
->
hd
.
stream_id
,
NGHTTP2_FLAG_NONE
,
&
frame
->
priority
.
pri_spec
,
NGHTTP2_STREAM_IDLE
,
NULL
);
if
(
!
stream
)
{
return
NGHTTP2_ERR_NOMEM
;
}
}
else
{
rv
=
nghttp2_session_reprioritize_stream
(
session
,
stream
,
&
frame
->
priority
.
pri_spec
);
if
(
nghttp2_is_fatal
(
rv
))
{
return
rv
;
}
}
if
(
frame
->
hd
.
type
==
NGHTTP2_HEADERS
||
frame
->
hd
.
type
==
NGHTTP2_PUSH_PROMISE
)
{
if
(
nghttp2_bufs_next_present
(
framebufs
))
{
DEBUGF
(
fprintf
(
stderr
,
"send: CONTINUATION exists, just return
\n
"
));
return
0
;
}
}
rv
=
session_call_on_frame_send
(
session
,
frame
);
if
(
nghttp2_is_fatal
(
rv
))
{
return
rv
;
}
switch
(
frame
->
hd
.
type
)
{
case
NGHTTP2_HEADERS
:
{
nghttp2_headers_aux_data
*
aux_data
;
rv
=
nghttp2_session_adjust_idle_stream
(
session
);
stream
=
nghttp2_session_get_stream
(
session
,
frame
->
hd
.
stream_id
);
if
(
!
stream
)
{
return
0
;
}
switch
(
frame
->
headers
.
cat
)
{
case
NGHTTP2_HCAT_REQUEST
:
{
stream
->
state
=
NGHTTP2_STREAM_OPENING
;
if
(
frame
->
hd
.
flags
&
NGHTTP2_FLAG_END_STREAM
)
{
nghttp2_stream_shutdown
(
stream
,
NGHTTP2_SHUT_WR
);
}
rv
=
nghttp2_session_close_stream_if_shut_rdwr
(
session
,
stream
);
if
(
nghttp2_is_fatal
(
rv
))
{
return
rv
;
}
break
;
/* We assume aux_data is a pointer to nghttp2_headers_aux_data */
aux_data
=
&
item
->
aux_data
.
headers
;
if
(
aux_data
->
data_prd
.
read_callback
)
{
/* nghttp2_submit_data() makes a copy of aux_data->data_prd */
rv
=
nghttp2_submit_data
(
session
,
NGHTTP2_FLAG_END_STREAM
,
frame
->
hd
.
stream_id
,
&
aux_data
->
data_prd
);
if
(
nghttp2_is_fatal
(
rv
))
{
return
rv
;
}
/* TODO nghttp2_submit_data() may fail if stream has already
DATA frame item. We might have to handle it here. */
}
return
0
;
}
case
NGHTTP2_RST_STREAM
:
rv
=
nghttp2_session_close_stream
(
session
,
frame
->
hd
.
stream_id
,
frame
->
rst_stream
.
error_code
);
case
NGHTTP2_HCAT_PUSH_RESPONSE
:
stream
->
flags
=
(
uint8_t
)(
stream
->
flags
&
~
NGHTTP2_STREAM_FLAG_PUSH
);
++
session
->
num_outgoing_streams
;
/* Fall through */
case
NGHTTP2_HCAT_RESPONSE
:
stream
->
state
=
NGHTTP2_STREAM_OPENED
;
/* Fall through */
case
NGHTTP2_HCAT_HEADERS
:
if
(
frame
->
hd
.
flags
&
NGHTTP2_FLAG_END_STREAM
)
{
nghttp2_stream_shutdown
(
stream
,
NGHTTP2_SHUT_WR
);
}
rv
=
nghttp2_session_close_stream_if_shut_rdwr
(
session
,
stream
);
if
(
nghttp2_is_fatal
(
rv
))
{
return
rv
;
}
break
;
case
NGHTTP2_GOAWAY
:
{
nghttp2_goaway_aux_data
*
aux_data
;
aux_data
=
&
item
->
aux_data
.
goaway
;
if
((
aux_data
->
flags
&
NGHTTP2_GOAWAY_AUX_SHUTDOWN_NOTICE
)
==
0
)
{
if
(
aux_data
->
flags
&
NGHTTP2_GOAWAY_AUX_TERM_ON_SEND
)
{
session
->
goaway_flags
|=
NGHTTP2_GOAWAY_TERM_SENT
;
}
session
->
goaway_flags
|=
NGHTTP2_GOAWAY_SENT
;
rv
=
session_close_stream_on_goaway
(
session
,
frame
->
goaway
.
last_stream_id
,
1
);
/* We assume aux_data is a pointer to nghttp2_headers_aux_data */
aux_data
=
&
item
->
aux_data
.
headers
;
if
(
aux_data
->
data_prd
.
read_callback
)
{
rv
=
nghttp2_submit_data
(
session
,
NGHTTP2_FLAG_END_STREAM
,
frame
->
hd
.
stream_id
,
&
aux_data
->
data_prd
);
if
(
nghttp2_is_fatal
(
rv
))
{
return
rv
;
}
/* TODO nghttp2_submit_data() may fail if stream has already
DATA frame item. We might have to handle it here. */
}
break
;
return
0
;
default:
/* Unreachable */
assert
(
0
);
return
0
;
}
}
case
NGHTTP2_PRIORITY
:
if
(
session
->
server
)
{
return
0
;
;
}
case
NGHTTP2_WINDOW_UPDATE
:
if
(
frame
->
hd
.
stream_id
==
0
)
{
session
->
window_update_queued
=
0
;
if
(
session
->
opt_flags
&
NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE
)
{
rv
=
session_update_connection_consumed_size
(
session
,
0
);
}
else
{
rv
=
session_update_recv_connection_window_size
(
session
,
0
);
}
}
else
{
nghttp2_stream
*
stream
;
stream
=
nghttp2_session_get_stream
(
session
,
frame
->
hd
.
stream_id
);
if
(
!
stream
)
{
break
;
}
stream
->
window_update_queued
=
0
;
/* We don't have to send WINDOW_UPDATE if END_STREAM from peer
is seen. */
if
(
stream
->
shut_flags
&
NGHTTP2_SHUT_RD
)
{
break
;
}
stream
=
nghttp2_session_get_stream_raw
(
session
,
frame
->
hd
.
stream_id
);
if
(
session
->
opt_flags
&
NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE
)
{
rv
=
session_update_stream_consumed_size
(
session
,
stream
,
0
);
}
else
{
rv
=
session_update_recv_stream_window_size
(
session
,
stream
,
0
,
1
);
}
if
(
!
stream
)
{
if
(
!
session_detect_idle_stream
(
session
,
frame
->
hd
.
stream_id
))
{
return
0
;
}
stream
=
nghttp2_session_open_stream
(
session
,
frame
->
hd
.
stream_id
,
NGHTTP2_FLAG_NONE
,
&
frame
->
priority
.
pri_spec
,
NGHTTP2_STREAM_IDLE
,
NULL
);
if
(
!
stream
)
{
return
NGHTTP2_ERR_NOMEM
;
}
}
else
{
rv
=
nghttp2_session_reprioritize_stream
(
session
,
stream
,
&
frame
->
priority
.
pri_spec
);
if
(
nghttp2_is_fatal
(
rv
))
{
return
rv
;
}
}
break
;
default:
break
;
rv
=
nghttp2_session_adjust_idle_stream
(
session
);
if
(
nghttp2_is_fatal
(
rv
))
{
return
rv
;
}
return
0
;
}
else
{
nghttp2_stream
*
stream
;
nghttp2_data_aux_data
*
aux_data
;
case
NGHTTP2_RST_STREAM
:
rv
=
nghttp2_session_close_stream
(
session
,
frame
->
hd
.
stream_id
,
frame
->
rst_stream
.
error_code
);
if
(
nghttp2_is_fatal
(
rv
))
{
return
rv
;
}
return
0
;
case
NGHTTP2_GOAWAY
:
{
nghttp2_goaway_aux_data
*
aux_data
;
aux_data
=
&
item
->
aux_data
.
data
;
aux_data
=
&
item
->
aux_data
.
goaway
;
stream
=
nghttp2_session_get_stream
(
session
,
frame
->
hd
.
stream_id
);
/* We update flow control window after a frame was completely
sent. This is possible because we choose payload length not to
exceed the window */
session
->
remote_window_size
-=
(
int32_t
)
frame
->
hd
.
length
;
if
(
stream
)
{
stream
->
remote_window_size
-=
(
int32_t
)
frame
->
hd
.
length
;
}
if
((
aux_data
->
flags
&
NGHTTP2_GOAWAY_AUX_SHUTDOWN_NOTICE
)
==
0
)
{
if
(
stream
&&
aux_data
->
eof
)
{
rv
=
nghttp2_stream_detach_item
(
stream
);
if
(
aux_data
->
flags
&
NGHTTP2_GOAWAY_AUX_TERM_ON_SEND
)
{
session
->
goaway_flags
|=
NGHTTP2_GOAWAY_TERM_SENT
;
}
session
->
goaway_flags
|=
NGHTTP2_GOAWAY_SENT
;
rv
=
session_close_stream_on_goaway
(
session
,
frame
->
goaway
.
last_stream_id
,
1
);
if
(
nghttp2_is_fatal
(
rv
))
{
return
rv
;
}
}
/* Call on_frame_send_callback after
nghttp2_stream_detach_item(), so that application can issue
nghttp2_submit_data() in the callback. */
if
(
session
->
callbacks
.
on_frame_send_callback
)
{
rv
=
session_call_on_frame_send
(
session
,
frame
);
return
0
;
}
case
NGHTTP2_WINDOW_UPDATE
:
if
(
frame
->
hd
.
stream_id
==
0
)
{
session
->
window_update_queued
=
0
;
if
(
session
->
opt_flags
&
NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE
)
{
rv
=
session_update_connection_consumed_size
(
session
,
0
);
}
else
{
rv
=
session_update_recv_connection_window_size
(
session
,
0
);
}
if
(
nghttp2_is_fatal
(
rv
))
{
return
rv
;
}
if
(
nghttp2_is_fatal
(
rv
))
{
return
rv
;
}
if
(
frame
->
hd
.
flags
&
NGHTTP2_FLAG_END_STREAM
)
{
int
stream_closed
;
return
0
;
}
stream_closed
=
(
stream
->
shut_flags
&
NGHTTP2_SHUT_RDWR
)
==
NGHTTP2_SHUT_RDWR
;
stream
=
nghttp2_session_get_stream
(
session
,
frame
->
hd
.
stream_id
);
if
(
!
stream
)
{
return
0
;
}
nghttp2_stream_shutdown
(
stream
,
NGHTTP2_SHUT_WR
)
;
stream
->
window_update_queued
=
0
;
rv
=
nghttp2_session_close_stream_if_shut_rdwr
(
session
,
stream
);
if
(
nghttp2_is_fatal
(
rv
))
{
return
rv
;
}
/* stream may be NULL if it was closed */
if
(
stream_closed
)
{
stream
=
NULL
;
}
}
/* We don't have to send WINDOW_UPDATE if END_STREAM from peer
is seen. */
if
(
stream
->
shut_flags
&
NGHTTP2_SHUT_RD
)
{
return
0
;
}
if
(
session
->
callbacks
.
on_frame_send_callback
)
{
rv
=
session_call_on_frame_send
(
session
,
frame
);
if
(
session
->
opt_flags
&
NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE
)
{
rv
=
session_update_stream_consumed_size
(
session
,
stream
,
0
);
}
else
{
rv
=
session_update_recv_stream_window_size
(
session
,
stream
,
0
,
1
);
}
if
(
nghttp2_is_fatal
(
rv
))
{
return
rv
;
}
if
(
nghttp2_is_fatal
(
rv
))
{
return
rv
;
}
return
0
;
default:
return
0
;
}
/* Unreachable */
assert
(
0
);
return
0
;
}
/*
...
...
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