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
80342215
Commit
80342215
authored
May 10, 2018
by
Tatsuhiro Tsujikawa
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement ORIGIN frame
parent
2e6593e5
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
834 additions
and
3 deletions
+834
-3
doc/Makefile.am
doc/Makefile.am
+1
-0
lib/includes/nghttp2/nghttp2.h
lib/includes/nghttp2/nghttp2.h
+80
-1
lib/nghttp2_frame.c
lib/nghttp2_frame.c
+130
-0
lib/nghttp2_frame.h
lib/nghttp2_frame.h
+49
-0
lib/nghttp2_option.c
lib/nghttp2_option.c
+4
-0
lib/nghttp2_outbound_item.c
lib/nghttp2_outbound_item.c
+3
-0
lib/nghttp2_session.c
lib/nghttp2_session.c
+118
-1
lib/nghttp2_session.h
lib/nghttp2_session.h
+16
-1
lib/nghttp2_submit.c
lib/nghttp2_submit.c
+83
-0
tests/failmalloc_test.c
tests/failmalloc_test.c
+10
-0
tests/main.c
tests/main.c
+5
-0
tests/nghttp2_frame_test.c
tests/nghttp2_frame_test.c
+92
-0
tests/nghttp2_frame_test.h
tests/nghttp2_frame_test.h
+1
-0
tests/nghttp2_session_test.c
tests/nghttp2_session_test.c
+236
-0
tests/nghttp2_session_test.h
tests/nghttp2_session_test.h
+2
-0
tests/nghttp2_test_helper.c
tests/nghttp2_test_helper.c
+4
-0
No files found.
doc/Makefile.am
View file @
80342215
...
...
@@ -164,6 +164,7 @@ APIDOCS= \
nghttp2_submit_extension.rst
\
nghttp2_submit_goaway.rst
\
nghttp2_submit_headers.rst
\
nghttp2_submit_origin.rst
\
nghttp2_submit_ping.rst
\
nghttp2_submit_priority.rst
\
nghttp2_submit_push_promise.rst
\
...
...
lib/includes/nghttp2/nghttp2.h
View file @
80342215
...
...
@@ -611,7 +611,12 @@ typedef enum {
* The ALTSVC frame, which is defined in `RFC 7383
* <https://tools.ietf.org/html/rfc7838#section-4>`_.
*/
NGHTTP2_ALTSVC
=
0x0a
NGHTTP2_ALTSVC
=
0x0a
,
/**
* The ORIGIN frame, which is defined by `RFC 8336
* <https://tools.ietf.org/html/rfc8336>`_.
*/
NGHTTP2_ORIGIN
=
0x0c
}
nghttp2_frame_type
;
/**
...
...
@@ -4551,6 +4556,80 @@ NGHTTP2_EXTERN int nghttp2_submit_altsvc(nghttp2_session *session,
const
uint8_t
*
field_value
,
size_t
field_value_len
);
/**
* @struct
*
* The single entry of an origin.
*/
typedef
struct
{
/**
* The pointer to origin. No validation is made against this field
* by the library. This is not necessarily NULL-terminated.
*/
uint8_t
*
origin
;
/**
* The length of the |origin|.
*/
size_t
origin_len
;
}
nghttp2_origin_entry
;
/**
* @struct
*
* The payload of ORIGIN frame. ORIGIN frame is a non-critical
* extension to HTTP/2 and defined by `RFC 8336
* <https://tools.ietf.org/html/rfc8336>`_.
*
* If this frame is received, and
* `nghttp2_option_set_user_recv_extension_type()` is not set, and
* `nghttp2_option_set_builtin_recv_extension_type()` is set for
* :enum:`NGHTTP2_ORIGIN`, ``nghttp2_extension.payload`` will point to
* this struct.
*
* It has the following members:
*/
typedef
struct
{
/**
* The number of origins contained in |ov|.
*/
size_t
nov
;
/**
* The pointer to the array of origins contained in ORIGIN frame.
*/
nghttp2_origin_entry
*
ov
;
}
nghttp2_ext_origin
;
/**
* @function
*
* Submits ORIGIN frame.
*
* ORIGIN frame is a non-critical extension to HTTP/2 and defined by
* `RFC 8336 <https://tools.ietf.org/html/rfc8336>`_.
*
* The |flags| is currently ignored and should be
* :enum:`NGHTTP2_FLAG_NONE`.
*
* The |ov| points to the array of origins. The |nov| specifies the
* number of origins included in |ov|.
*
* The ORIGIN frame is only usable by a server. If this function is
* invoked with client side session, this function returns
* :enum:`NGHTTP2_ERR_INVALID_STATE`.
*
* :enum:`NGHTTP2_ERR_NOMEM`
* Out of memory
* :enum:`NGHTTP2_ERR_INVALID_STATE`
* The function is called from client side session.
* :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
* There are too many origins, or an origin is too large to fit
* into a default frame payload.
*/
NGHTTP2_EXTERN
int
nghttp2_submit_origin
(
nghttp2_session
*
session
,
uint8_t
flags
,
const
nghttp2_origin_entry
*
ov
,
size_t
nov
);
/**
* @function
*
...
...
lib/nghttp2_frame.c
View file @
80342215
...
...
@@ -223,6 +223,36 @@ void nghttp2_frame_altsvc_free(nghttp2_extension *frame, nghttp2_mem *mem) {
nghttp2_mem_free
(
mem
,
altsvc
->
origin
);
}
void
nghttp2_frame_origin_init
(
nghttp2_extension
*
frame
,
nghttp2_origin_entry
*
ov
,
size_t
nov
)
{
nghttp2_ext_origin
*
origin
;
size_t
payloadlen
=
0
;
size_t
i
;
for
(
i
=
0
;
i
<
nov
;
++
i
)
{
payloadlen
+=
2
+
ov
[
i
].
origin_len
;
}
nghttp2_frame_hd_init
(
&
frame
->
hd
,
payloadlen
,
NGHTTP2_ORIGIN
,
NGHTTP2_FLAG_NONE
,
0
);
origin
=
frame
->
payload
;
origin
->
ov
=
ov
;
origin
->
nov
=
nov
;
}
void
nghttp2_frame_origin_free
(
nghttp2_extension
*
frame
,
nghttp2_mem
*
mem
)
{
nghttp2_ext_origin
*
origin
;
origin
=
frame
->
payload
;
if
(
origin
==
NULL
)
{
return
;
}
/* We use the same buffer for all resources pointed by the field of
origin directly or indirectly. */
nghttp2_mem_free
(
mem
,
origin
->
ov
);
}
size_t
nghttp2_frame_priority_len
(
uint8_t
flags
)
{
if
(
flags
&
NGHTTP2_FLAG_PRIORITY
)
{
return
NGHTTP2_PRIORITY_SPECLEN
;
...
...
@@ -746,6 +776,106 @@ int nghttp2_frame_unpack_altsvc_payload2(nghttp2_extension *frame,
return
0
;
}
int
nghttp2_frame_pack_origin
(
nghttp2_bufs
*
bufs
,
nghttp2_extension
*
frame
)
{
nghttp2_buf
*
buf
;
nghttp2_ext_origin
*
origin
;
nghttp2_origin_entry
*
orig
;
size_t
i
;
origin
=
frame
->
payload
;
buf
=
&
bufs
->
head
->
buf
;
if
(
nghttp2_buf_avail
(
buf
)
<
frame
->
hd
.
length
)
{
return
NGHTTP2_ERR_FRAME_SIZE_ERROR
;
}
buf
->
pos
-=
NGHTTP2_FRAME_HDLEN
;
nghttp2_frame_pack_frame_hd
(
buf
->
pos
,
&
frame
->
hd
);
for
(
i
=
0
;
i
<
origin
->
nov
;
++
i
)
{
orig
=
&
origin
->
ov
[
i
];
nghttp2_put_uint16be
(
buf
->
last
,
(
uint16_t
)
orig
->
origin_len
);
buf
->
last
+=
2
;
buf
->
last
=
nghttp2_cpymem
(
buf
->
last
,
orig
->
origin
,
orig
->
origin_len
);
}
assert
(
nghttp2_buf_len
(
buf
)
==
NGHTTP2_FRAME_HDLEN
+
frame
->
hd
.
length
);
return
0
;
}
int
nghttp2_frame_unpack_origin_payload
(
nghttp2_extension
*
frame
,
const
uint8_t
*
payload
,
size_t
payloadlen
,
nghttp2_mem
*
mem
)
{
nghttp2_ext_origin
*
origin
;
const
uint8_t
*
p
,
*
end
;
uint8_t
*
dst
;
size_t
originlen
;
nghttp2_origin_entry
*
ov
;
size_t
nov
=
0
;
size_t
len
=
0
;
origin
=
frame
->
payload
;
p
=
payload
;
end
=
p
+
payloadlen
;
for
(;
p
!=
end
;)
{
if
(
end
-
p
<
2
)
{
return
NGHTTP2_ERR_FRAME_SIZE_ERROR
;
}
originlen
=
nghttp2_get_uint16
(
p
);
p
+=
2
;
if
(
originlen
==
0
)
{
continue
;
}
if
(
originlen
>
(
size_t
)(
end
-
p
))
{
return
NGHTTP2_ERR_FRAME_SIZE_ERROR
;
}
p
+=
originlen
;
/* 1 for terminal NULL */
len
+=
originlen
+
1
;
++
nov
;
}
if
(
nov
==
0
)
{
origin
->
ov
=
NULL
;
origin
->
nov
=
0
;
return
0
;
}
len
+=
nov
*
sizeof
(
nghttp2_origin_entry
);
ov
=
nghttp2_mem_malloc
(
mem
,
len
);
if
(
ov
==
NULL
)
{
return
NGHTTP2_ERR_NOMEM
;
}
origin
->
ov
=
ov
;
origin
->
nov
=
nov
;
dst
=
(
uint8_t
*
)
ov
+
nov
*
sizeof
(
nghttp2_origin_entry
);
p
=
payload
;
for
(;
p
!=
end
;)
{
originlen
=
nghttp2_get_uint16
(
p
);
p
+=
2
;
if
(
originlen
==
0
)
{
continue
;
}
ov
->
origin
=
dst
;
ov
->
origin_len
=
originlen
;
dst
=
nghttp2_cpymem
(
dst
,
p
,
originlen
);
*
dst
++
=
'\0'
;
p
+=
originlen
;
++
ov
;
}
return
0
;
}
nghttp2_settings_entry
*
nghttp2_frame_iv_copy
(
const
nghttp2_settings_entry
*
iv
,
size_t
niv
,
nghttp2_mem
*
mem
)
{
nghttp2_settings_entry
*
iv_copy
;
...
...
lib/nghttp2_frame.h
View file @
80342215
...
...
@@ -72,6 +72,7 @@
/* Union of extension frame payload */
typedef
union
{
nghttp2_ext_altsvc
altsvc
;
nghttp2_ext_origin
origin
;
}
nghttp2_ext_frame_payload
;
void
nghttp2_frame_pack_frame_hd
(
uint8_t
*
buf
,
const
nghttp2_frame_hd
*
hd
);
...
...
@@ -392,6 +393,36 @@ int nghttp2_frame_unpack_altsvc_payload2(nghttp2_extension *frame,
const
uint8_t
*
payload
,
size_t
payloadlen
,
nghttp2_mem
*
mem
);
/*
* Packs ORIGIN frame |frame| in wire frame format and store it in
* |bufs|.
*
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
* before calling this function.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_FRAME_SIZE_ERROR
* The length of the frame is too large.
*/
int
nghttp2_frame_pack_origin
(
nghttp2_bufs
*
bufs
,
nghttp2_extension
*
ext
);
/*
* Unpacks ORIGIN wire format into |frame|. The |payload| of length
* |payloadlen| contains the frame payload.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory.
* NGHTTP2_ERR_FRAME_SIZE_ERROR
* The payload is too small.
*/
int
nghttp2_frame_unpack_origin_payload
(
nghttp2_extension
*
frame
,
const
uint8_t
*
payload
,
size_t
payloadlen
,
nghttp2_mem
*
mem
);
/*
* Initializes HEADERS frame |frame| with given values. |frame| takes
* ownership of |nva|, so caller must not free it. If |stream_id| is
...
...
@@ -489,6 +520,24 @@ void nghttp2_frame_altsvc_init(nghttp2_extension *frame, int32_t stream_id,
*/
void
nghttp2_frame_altsvc_free
(
nghttp2_extension
*
frame
,
nghttp2_mem
*
mem
);
/*
* Initializes ORIGIN frame |frame| with given values. This function
* assumes that frame->payload points to nghttp2_ext_origin object.
* Also |ov| and the memory pointed by the field of its elements are
* allocated in single buffer, starting with |ov|. On success, this
* function takes ownership of |ov|, so caller must not free it.
*/
void
nghttp2_frame_origin_init
(
nghttp2_extension
*
frame
,
nghttp2_origin_entry
*
ov
,
size_t
nov
);
/*
* Frees up resources under |frame|. This function does not free
* nghttp2_ext_origin object pointed by frame->payload. This function
* only frees nghttp2_ext_origin.ov. Therefore, other fields must be
* allocated in the same buffer with ov.
*/
void
nghttp2_frame_origin_free
(
nghttp2_extension
*
frame
,
nghttp2_mem
*
mem
);
/*
* Returns the number of padding bytes after payload. The total
* padding length is given in the |padlen|. The returned value does
...
...
lib/nghttp2_option.c
View file @
80342215
...
...
@@ -86,6 +86,10 @@ void nghttp2_option_set_builtin_recv_extension_type(nghttp2_option *option,
option
->
opt_set_mask
|=
NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES
;
option
->
builtin_recv_ext_types
|=
NGHTTP2_TYPEMASK_ALTSVC
;
return
;
case
NGHTTP2_ORIGIN
:
option
->
opt_set_mask
|=
NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES
;
option
->
builtin_recv_ext_types
|=
NGHTTP2_TYPEMASK_ORIGIN
;
return
;
default:
return
;
}
...
...
lib/nghttp2_outbound_item.c
View file @
80342215
...
...
@@ -86,6 +86,9 @@ void nghttp2_outbound_item_free(nghttp2_outbound_item *item, nghttp2_mem *mem) {
case
NGHTTP2_ALTSVC
:
nghttp2_frame_altsvc_free
(
&
frame
->
ext
,
mem
);
break
;
case
NGHTTP2_ORIGIN
:
nghttp2_frame_origin_free
(
&
frame
->
ext
,
mem
);
break
;
default:
assert
(
0
);
break
;
...
...
lib/nghttp2_session.c
View file @
80342215
...
...
@@ -348,6 +348,12 @@ static void session_inbound_frame_reset(nghttp2_session *session) {
}
nghttp2_frame_altsvc_free
(
&
iframe
->
frame
.
ext
,
mem
);
break
;
case
NGHTTP2_ORIGIN
:
if
((
session
->
builtin_recv_ext_types
&
NGHTTP2_TYPEMASK_ORIGIN
)
==
0
)
{
break
;
}
nghttp2_frame_origin_free
(
&
iframe
->
frame
.
ext
,
mem
);
break
;
}
}
...
...
@@ -1749,6 +1755,13 @@ static int session_predicate_altsvc_send(nghttp2_session *session,
return
0
;
}
static
int
session_predicate_origin_send
(
nghttp2_session
*
session
)
{
if
(
session_is_closing
(
session
))
{
return
NGHTTP2_ERR_SESSION_CLOSING
;
}
return
0
;
}
/* Take into account settings max frame size and both connection-level
flow control here */
static
ssize_t
...
...
@@ -2280,6 +2293,18 @@ static int session_prep_frame(nghttp2_session *session,
nghttp2_frame_pack_altsvc
(
&
session
->
aob
.
framebufs
,
&
frame
->
ext
);
return
0
;
case
NGHTTP2_ORIGIN
:
rv
=
session_predicate_origin_send
(
session
);
if
(
rv
!=
0
)
{
return
rv
;
}
rv
=
nghttp2_frame_pack_origin
(
&
session
->
aob
.
framebufs
,
&
frame
->
ext
);
if
(
rv
!=
0
)
{
return
rv
;
}
return
0
;
default:
/* Unreachable here */
...
...
@@ -4821,6 +4846,11 @@ int nghttp2_session_on_altsvc_received(nghttp2_session *session,
return
session_call_on_frame_received
(
session
,
frame
);
}
int
nghttp2_session_on_origin_received
(
nghttp2_session
*
session
,
nghttp2_frame
*
frame
)
{
return
session_call_on_frame_received
(
session
,
frame
);
}
static
int
session_process_altsvc_frame
(
nghttp2_session
*
session
)
{
nghttp2_inbound_frame
*
iframe
=
&
session
->
iframe
;
nghttp2_frame
*
frame
=
&
iframe
->
frame
;
...
...
@@ -4836,6 +4866,25 @@ static int session_process_altsvc_frame(nghttp2_session *session) {
return
nghttp2_session_on_altsvc_received
(
session
,
frame
);
}
static
int
session_process_origin_frame
(
nghttp2_session
*
session
)
{
nghttp2_inbound_frame
*
iframe
=
&
session
->
iframe
;
nghttp2_frame
*
frame
=
&
iframe
->
frame
;
nghttp2_mem
*
mem
=
&
session
->
mem
;
int
rv
;
rv
=
nghttp2_frame_unpack_origin_payload
(
&
frame
->
ext
,
iframe
->
lbuf
.
pos
,
nghttp2_buf_len
(
&
iframe
->
lbuf
),
mem
);
if
(
rv
!=
0
)
{
if
(
nghttp2_is_fatal
(
rv
))
{
return
rv
;
}
/* Ignore ORIGIN frame which cannot be parsed. */
return
0
;
}
return
nghttp2_session_on_origin_received
(
session
,
frame
);
}
static
int
session_process_extension_frame
(
nghttp2_session
*
session
)
{
int
rv
;
nghttp2_inbound_frame
*
iframe
=
&
session
->
iframe
;
...
...
@@ -5746,6 +5795,42 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
iframe
->
state
=
NGHTTP2_IB_READ_NBYTE
;
inbound_frame_set_mark
(
iframe
,
2
);
break
;
case
NGHTTP2_ORIGIN
:
if
(
!
(
session
->
builtin_recv_ext_types
&
NGHTTP2_TYPEMASK_ORIGIN
))
{
busy
=
1
;
iframe
->
state
=
NGHTTP2_IB_IGN_PAYLOAD
;
break
;
}
DEBUGF
(
"recv: ORIGIN
\n
"
);
iframe
->
frame
.
ext
.
payload
=
&
iframe
->
ext_frame_payload
.
origin
;
if
(
session
->
server
||
iframe
->
frame
.
hd
.
stream_id
||
(
iframe
->
frame
.
hd
.
flags
&
0xf0
))
{
busy
=
1
;
iframe
->
state
=
NGHTTP2_IB_IGN_PAYLOAD
;
break
;
}
iframe
->
frame
.
hd
.
flags
=
NGHTTP2_FLAG_NONE
;
if
(
iframe
->
payloadleft
)
{
iframe
->
raw_lbuf
=
nghttp2_mem_malloc
(
mem
,
iframe
->
payloadleft
);
if
(
iframe
->
raw_lbuf
==
NULL
)
{
return
NGHTTP2_ERR_NOMEM
;
}
nghttp2_buf_wrap_init
(
&
iframe
->
lbuf
,
iframe
->
raw_lbuf
,
iframe
->
payloadleft
);
}
else
{
busy
=
1
;
}
iframe
->
state
=
NGHTTP2_IB_READ_ORIGIN_PAYLOAD
;
break
;
default:
busy
=
1
;
...
...
@@ -6583,7 +6668,6 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
DEBUGF
(
"recv: [IB_READ_ALTSVC_PAYLOAD]
\n
"
);
readlen
=
inbound_frame_payload_readlen
(
iframe
,
in
,
last
);
if
(
readlen
>
0
)
{
iframe
->
lbuf
.
last
=
nghttp2_cpymem
(
iframe
->
lbuf
.
last
,
in
,
readlen
);
...
...
@@ -6601,11 +6685,44 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
}
rv
=
session_process_altsvc_frame
(
session
);
if
(
nghttp2_is_fatal
(
rv
))
{
return
rv
;
}
session_inbound_frame_reset
(
session
);
break
;
case
NGHTTP2_IB_READ_ORIGIN_PAYLOAD
:
DEBUGF
(
"recv: [IB_READ_ORIGIN_PAYLOAD]
\n
"
);
readlen
=
inbound_frame_payload_readlen
(
iframe
,
in
,
last
);
if
(
readlen
>
0
)
{
iframe
->
lbuf
.
last
=
nghttp2_cpymem
(
iframe
->
lbuf
.
last
,
in
,
readlen
);
iframe
->
payloadleft
-=
readlen
;
in
+=
readlen
;
}
DEBUGF
(
"recv: readlen=%zu, payloadleft=%zu
\n
"
,
readlen
,
iframe
->
payloadleft
);
if
(
iframe
->
payloadleft
)
{
assert
(
nghttp2_buf_avail
(
&
iframe
->
lbuf
)
>
0
);
break
;
}
rv
=
session_process_origin_frame
(
session
);
if
(
nghttp2_is_fatal
(
rv
))
{
return
rv
;
}
if
(
iframe
->
state
==
NGHTTP2_IB_IGN_ALL
)
{
return
(
ssize_t
)
inlen
;
}
session_inbound_frame_reset
(
session
);
break
;
...
...
lib/nghttp2_session.h
View file @
80342215
...
...
@@ -61,7 +61,8 @@ typedef enum {
*/
typedef
enum
{
NGHTTP2_TYPEMASK_NONE
=
0
,
NGHTTP2_TYPEMASK_ALTSVC
=
1
<<
0
NGHTTP2_TYPEMASK_ALTSVC
=
1
<<
0
,
NGHTTP2_TYPEMASK_ORIGIN
=
1
<<
1
}
nghttp2_typemask
;
typedef
enum
{
...
...
@@ -121,6 +122,7 @@ typedef enum {
NGHTTP2_IB_IGN_DATA
,
NGHTTP2_IB_IGN_ALL
,
NGHTTP2_IB_READ_ALTSVC_PAYLOAD
,
NGHTTP2_IB_READ_ORIGIN_PAYLOAD
,
NGHTTP2_IB_READ_EXTENSION_PAYLOAD
}
nghttp2_inbound_state
;
...
...
@@ -749,6 +751,19 @@ int nghttp2_session_on_window_update_received(nghttp2_session *session,
int
nghttp2_session_on_altsvc_received
(
nghttp2_session
*
session
,
nghttp2_frame
*
frame
);
/*
* Called when ORIGIN is received, assuming |frame| is properly
* initialized.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_CALLBACK_FAILURE
* The callback function failed.
*/
int
nghttp2_session_on_origin_received
(
nghttp2_session
*
session
,
nghttp2_frame
*
frame
);
/*
* Called when DATA is received, assuming |frame| is properly
* initialized.
...
...
lib/nghttp2_submit.c
View file @
80342215
...
...
@@ -571,6 +571,89 @@ fail_item_malloc:
return
rv
;
}
int
nghttp2_submit_origin
(
nghttp2_session
*
session
,
uint8_t
flags
,
const
nghttp2_origin_entry
*
ov
,
size_t
nov
)
{
nghttp2_mem
*
mem
;
uint8_t
*
p
;
nghttp2_outbound_item
*
item
;
nghttp2_frame
*
frame
;
nghttp2_ext_origin
*
origin
;
nghttp2_origin_entry
*
ov_copy
;
size_t
len
=
0
;
size_t
i
;
int
rv
;
(
void
)
flags
;
mem
=
&
session
->
mem
;
if
(
!
session
->
server
)
{
return
NGHTTP2_ERR_INVALID_STATE
;
}
if
(
nov
)
{
for
(
i
=
0
;
i
<
nov
;
++
i
)
{
len
+=
ov
[
i
].
origin_len
;
}
if
(
2
*
nov
+
len
>
NGHTTP2_MAX_PAYLOADLEN
)
{
return
NGHTTP2_ERR_INVALID_ARGUMENT
;
}
/* The last nov is added for terminal NULL character. */
ov_copy
=
nghttp2_mem_malloc
(
mem
,
nov
*
sizeof
(
nghttp2_origin_entry
)
+
len
+
nov
);
if
(
ov_copy
==
NULL
)
{
return
NGHTTP2_ERR_NOMEM
;
}
p
=
(
uint8_t
*
)
ov_copy
+
nov
*
sizeof
(
nghttp2_origin_entry
);
for
(
i
=
0
;
i
<
nov
;
++
i
)
{
ov_copy
[
i
].
origin
=
p
;
ov_copy
[
i
].
origin_len
=
ov
[
i
].
origin_len
;
p
=
nghttp2_cpymem
(
p
,
ov
[
i
].
origin
,
ov
[
i
].
origin_len
);
*
p
++
=
'\0'
;
}
assert
((
size_t
)(
p
-
(
uint8_t
*
)
ov_copy
)
==
nov
*
sizeof
(
nghttp2_origin_entry
)
+
len
+
nov
);
}
else
{
ov_copy
=
NULL
;
}
item
=
nghttp2_mem_malloc
(
mem
,
sizeof
(
nghttp2_outbound_item
));
if
(
item
==
NULL
)
{
rv
=
NGHTTP2_ERR_NOMEM
;
goto
fail_item_malloc
;
}
nghttp2_outbound_item_init
(
item
);
item
->
aux_data
.
ext
.
builtin
=
1
;
origin
=
&
item
->
ext_frame_payload
.
origin
;
frame
=
&
item
->
frame
;
frame
->
ext
.
payload
=
origin
;
nghttp2_frame_origin_init
(
&
frame
->
ext
,
ov_copy
,
nov
);
rv
=
nghttp2_session_add_item
(
session
,
item
);
if
(
rv
!=
0
)
{
nghttp2_frame_origin_free
(
&
frame
->
ext
,
mem
);
nghttp2_mem_free
(
mem
,
item
);
return
rv
;
}
return
0
;
fail_item_malloc:
free
(
ov_copy
);
return
rv
;
}
static
uint8_t
set_request_flags
(
const
nghttp2_priority_spec
*
pri_spec
,
const
nghttp2_data_provider
*
data_prd
)
{
uint8_t
flags
=
NGHTTP2_FLAG_NONE
;
...
...
tests/failmalloc_test.c
View file @
80342215
...
...
@@ -224,6 +224,11 @@ static void run_nghttp2_session_send_server(void) {
ssize_t
txdatalen
;
const
uint8_t
origin
[]
=
"nghttp2.org"
;
const
uint8_t
altsvc_field_value
[]
=
"h2=
\"
:443
\"
"
;
static
const
uint8_t
nghttp2
[]
=
"https://nghttp2.org"
;
static
const
nghttp2_origin_entry
ov
=
{
(
uint8_t
*
)
nghttp2
,
sizeof
(
nghttp2
)
-
1
,
};
rv
=
nghttp2_session_callbacks_new
(
&
callbacks
);
if
(
rv
!=
0
)
{
...
...
@@ -246,6 +251,11 @@ static void run_nghttp2_session_send_server(void) {
goto
fail
;
}
rv
=
nghttp2_submit_origin
(
session
,
NGHTTP2_FLAG_NONE
,
&
ov
,
1
);
if
(
rv
!=
0
)
{
goto
fail
;
}
txdatalen
=
nghttp2_session_mem_send
(
session
,
&
txdata
);
if
(
txdatalen
<
0
)
{
...
...
tests/main.c
View file @
80342215
...
...
@@ -107,6 +107,8 @@ int main() {
test_nghttp2_session_recv_extension
)
||
!
CU_add_test
(
pSuite
,
"session_recv_altsvc"
,
test_nghttp2_session_recv_altsvc
)
||
!
CU_add_test
(
pSuite
,
"session_recv_origin"
,
test_nghttp2_session_recv_origin
)
||
!
CU_add_test
(
pSuite
,
"session_continue"
,
test_nghttp2_session_continue
)
||
!
CU_add_test
(
pSuite
,
"session_add_frame"
,
test_nghttp2_session_add_frame
)
||
...
...
@@ -206,6 +208,7 @@ int main() {
test_nghttp2_submit_invalid_nv
)
||
!
CU_add_test
(
pSuite
,
"submit_extension"
,
test_nghttp2_submit_extension
)
||
!
CU_add_test
(
pSuite
,
"submit_altsvc"
,
test_nghttp2_submit_altsvc
)
||
!
CU_add_test
(
pSuite
,
"submit_origin"
,
test_nghttp2_submit_origin
)
||
!
CU_add_test
(
pSuite
,
"session_open_stream"
,
test_nghttp2_session_open_stream
)
||
!
CU_add_test
(
pSuite
,
"session_open_stream_with_idle_stream_dep"
,
...
...
@@ -355,6 +358,8 @@ int main() {
test_nghttp2_frame_pack_window_update
)
||
!
CU_add_test
(
pSuite
,
"frame_pack_altsvc"
,
test_nghttp2_frame_pack_altsvc
)
||
!
CU_add_test
(
pSuite
,
"frame_pack_origin"
,
test_nghttp2_frame_pack_origin
)
||
!
CU_add_test
(
pSuite
,
"nv_array_copy"
,
test_nghttp2_nv_array_copy
)
||
!
CU_add_test
(
pSuite
,
"iv_check"
,
test_nghttp2_iv_check
)
||
!
CU_add_test
(
pSuite
,
"hd_deflate"
,
test_nghttp2_hd_deflate
)
||
...
...
tests/nghttp2_frame_test.c
View file @
80342215
...
...
@@ -508,6 +508,98 @@ void test_nghttp2_frame_pack_altsvc(void) {
nghttp2_bufs_free
(
&
bufs
);
}
void
test_nghttp2_frame_pack_origin
(
void
)
{
nghttp2_extension
frame
,
oframe
;
nghttp2_ext_origin
origin
,
oorigin
;
nghttp2_bufs
bufs
;
nghttp2_buf
*
buf
;
int
rv
;
size_t
payloadlen
;
static
const
uint8_t
example
[]
=
"https://example.com"
;
static
const
uint8_t
nghttp2
[]
=
"https://nghttp2.org"
;
nghttp2_origin_entry
ov
[]
=
{
{
(
uint8_t
*
)
example
,
sizeof
(
example
)
-
1
,
},
{
NULL
,
0
,
},
{
(
uint8_t
*
)
nghttp2
,
sizeof
(
nghttp2
)
-
1
,
},
};
nghttp2_mem
*
mem
;
mem
=
nghttp2_mem_default
();
frame_pack_bufs_init
(
&
bufs
);
frame
.
payload
=
&
origin
;
oframe
.
payload
=
&
oorigin
;
nghttp2_frame_origin_init
(
&
frame
,
ov
,
3
);
payloadlen
=
2
+
sizeof
(
example
)
-
1
+
2
+
2
+
sizeof
(
nghttp2
)
-
1
;
rv
=
nghttp2_frame_pack_origin
(
&
bufs
,
&
frame
);
CU_ASSERT
(
0
==
rv
);
CU_ASSERT
(
NGHTTP2_FRAME_HDLEN
+
payloadlen
==
nghttp2_bufs_len
(
&
bufs
));
rv
=
unpack_framebuf
((
nghttp2_frame
*
)
&
oframe
,
&
bufs
);
CU_ASSERT
(
0
==
rv
);
check_frame_header
(
payloadlen
,
NGHTTP2_ORIGIN
,
NGHTTP2_FLAG_NONE
,
0
,
&
oframe
.
hd
);
CU_ASSERT
(
2
==
oorigin
.
nov
);
CU_ASSERT
(
sizeof
(
example
)
-
1
==
oorigin
.
ov
[
0
].
origin_len
);
CU_ASSERT
(
0
==
memcmp
(
example
,
oorigin
.
ov
[
0
].
origin
,
sizeof
(
example
)
-
1
));
CU_ASSERT
(
sizeof
(
nghttp2
)
-
1
==
oorigin
.
ov
[
1
].
origin_len
);
CU_ASSERT
(
0
==
memcmp
(
nghttp2
,
oorigin
.
ov
[
1
].
origin
,
sizeof
(
nghttp2
)
-
1
));
nghttp2_frame_origin_free
(
&
oframe
,
mem
);
/* Check the case where origin length is too large */
buf
=
&
bufs
.
head
->
buf
;
nghttp2_put_uint16be
(
buf
->
pos
+
NGHTTP2_FRAME_HDLEN
,
(
uint16_t
)(
payloadlen
-
1
));
rv
=
unpack_framebuf
((
nghttp2_frame
*
)
&
oframe
,
&
bufs
);
CU_ASSERT
(
NGHTTP2_ERR_FRAME_SIZE_ERROR
==
rv
);
nghttp2_bufs_reset
(
&
bufs
);
memset
(
&
oframe
,
0
,
sizeof
(
oframe
));
memset
(
&
oorigin
,
0
,
sizeof
(
oorigin
));
oframe
.
payload
=
&
oorigin
;
/* Empty ORIGIN frame */
nghttp2_frame_origin_init
(
&
frame
,
NULL
,
0
);
rv
=
nghttp2_frame_pack_origin
(
&
bufs
,
&
frame
);
CU_ASSERT
(
0
==
rv
);
CU_ASSERT
(
NGHTTP2_FRAME_HDLEN
==
nghttp2_bufs_len
(
&
bufs
));
rv
=
unpack_framebuf
((
nghttp2_frame
*
)
&
oframe
,
&
bufs
);
CU_ASSERT
(
0
==
rv
);
check_frame_header
(
0
,
NGHTTP2_ORIGIN
,
NGHTTP2_FLAG_NONE
,
0
,
&
oframe
.
hd
);
CU_ASSERT
(
0
==
oorigin
.
nov
);
CU_ASSERT
(
NULL
==
oorigin
.
ov
);
nghttp2_frame_origin_free
(
&
oframe
,
mem
);
nghttp2_bufs_free
(
&
bufs
);
}
void
test_nghttp2_nv_array_copy
(
void
)
{
nghttp2_nv
*
nva
;
ssize_t
rv
;
...
...
tests/nghttp2_frame_test.h
View file @
80342215
...
...
@@ -39,6 +39,7 @@ void test_nghttp2_frame_pack_ping(void);
void
test_nghttp2_frame_pack_goaway
(
void
);
void
test_nghttp2_frame_pack_window_update
(
void
);
void
test_nghttp2_frame_pack_altsvc
(
void
);
void
test_nghttp2_frame_pack_origin
(
void
);
void
test_nghttp2_nv_array_copy
(
void
);
void
test_nghttp2_iv_check
(
void
);
...
...
tests/nghttp2_session_test.c
View file @
80342215
...
...
@@ -2436,6 +2436,153 @@ void test_nghttp2_session_recv_altsvc(void) {
nghttp2_option_del
(
option
);
}
void
test_nghttp2_session_recv_origin
(
void
)
{
nghttp2_session
*
session
;
nghttp2_session_callbacks
callbacks
;
my_user_data
ud
;
nghttp2_bufs
bufs
;
ssize_t
rv
;
nghttp2_option
*
option
;
nghttp2_extension
frame
;
nghttp2_ext_origin
origin
;
nghttp2_origin_entry
ov
;
static
const
uint8_t
nghttp2
[]
=
"https://nghttp2.org"
;
frame_pack_bufs_init
(
&
bufs
);
frame
.
payload
=
&
origin
;
ov
.
origin
=
(
uint8_t
*
)
nghttp2
;
ov
.
origin_len
=
sizeof
(
nghttp2
)
-
1
;
memset
(
&
callbacks
,
0
,
sizeof
(
nghttp2_session_callbacks
));
callbacks
.
on_frame_recv_callback
=
on_frame_recv_callback
;
nghttp2_option_new
(
&
option
);
nghttp2_option_set_builtin_recv_extension_type
(
option
,
NGHTTP2_ORIGIN
);
nghttp2_session_client_new2
(
&
session
,
&
callbacks
,
&
ud
,
option
);
nghttp2_frame_origin_init
(
&
frame
,
&
ov
,
1
);
rv
=
nghttp2_frame_pack_origin
(
&
bufs
,
&
frame
);
CU_ASSERT
(
0
==
rv
);
ud
.
frame_recv_cb_called
=
0
;
rv
=
nghttp2_session_mem_recv
(
session
,
bufs
.
head
->
buf
.
pos
,
nghttp2_bufs_len
(
&
bufs
));
CU_ASSERT
((
ssize_t
)
nghttp2_bufs_len
(
&
bufs
)
==
rv
);
CU_ASSERT
(
1
==
ud
.
frame_recv_cb_called
);
CU_ASSERT
(
NGHTTP2_ORIGIN
==
ud
.
recv_frame_hd
.
type
);
CU_ASSERT
(
NGHTTP2_FLAG_NONE
==
ud
.
recv_frame_hd
.
flags
);
CU_ASSERT
(
0
==
ud
.
recv_frame_hd
.
stream_id
);
nghttp2_session_del
(
session
);
nghttp2_bufs_reset
(
&
bufs
);
/* The length of origin is larger than payload length. */
nghttp2_session_client_new2
(
&
session
,
&
callbacks
,
&
ud
,
option
);
nghttp2_frame_origin_init
(
&
frame
,
&
ov
,
1
);
rv
=
nghttp2_frame_pack_origin
(
&
bufs
,
&
frame
);
CU_ASSERT
(
0
==
rv
);
nghttp2_put_uint16be
(
bufs
.
head
->
buf
.
pos
+
NGHTTP2_FRAME_HDLEN
,
(
uint16_t
)
sizeof
(
nghttp2
));
ud
.
frame_recv_cb_called
=
0
;
rv
=
nghttp2_session_mem_recv
(
session
,
bufs
.
head
->
buf
.
pos
,
nghttp2_bufs_len
(
&
bufs
));
CU_ASSERT
((
ssize_t
)
nghttp2_bufs_len
(
&
bufs
)
==
rv
);
CU_ASSERT
(
0
==
ud
.
frame_recv_cb_called
);
nghttp2_session_del
(
session
);
nghttp2_bufs_reset
(
&
bufs
);
/* A frame should be ignored if it is sent to a stream other than
stream 0. */
nghttp2_session_client_new2
(
&
session
,
&
callbacks
,
&
ud
,
option
);
nghttp2_frame_origin_init
(
&
frame
,
&
ov
,
1
);
frame
.
hd
.
stream_id
=
1
;
rv
=
nghttp2_frame_pack_origin
(
&
bufs
,
&
frame
);
CU_ASSERT
(
0
==
rv
);
ud
.
frame_recv_cb_called
=
0
;
rv
=
nghttp2_session_mem_recv
(
session
,
bufs
.
head
->
buf
.
pos
,
nghttp2_bufs_len
(
&
bufs
));
CU_ASSERT
((
ssize_t
)
nghttp2_bufs_len
(
&
bufs
)
==
rv
);
CU_ASSERT
(
0
==
ud
.
frame_recv_cb_called
);
nghttp2_session_del
(
session
);
nghttp2_bufs_reset
(
&
bufs
);
/* A frame should be ignored if the reserved flag is set */
nghttp2_session_client_new2
(
&
session
,
&
callbacks
,
&
ud
,
option
);
nghttp2_frame_origin_init
(
&
frame
,
&
ov
,
1
);
frame
.
hd
.
flags
=
0xf0
;
rv
=
nghttp2_frame_pack_origin
(
&
bufs
,
&
frame
);
CU_ASSERT
(
0
==
rv
);
ud
.
frame_recv_cb_called
=
0
;
rv
=
nghttp2_session_mem_recv
(
session
,
bufs
.
head
->
buf
.
pos
,
nghttp2_bufs_len
(
&
bufs
));
CU_ASSERT
((
ssize_t
)
nghttp2_bufs_len
(
&
bufs
)
==
rv
);
CU_ASSERT
(
0
==
ud
.
frame_recv_cb_called
);
nghttp2_session_del
(
session
);
nghttp2_bufs_reset
(
&
bufs
);
/* A frame should be ignored if it is received by a server. */
nghttp2_session_server_new2
(
&
session
,
&
callbacks
,
&
ud
,
option
);
nghttp2_frame_origin_init
(
&
frame
,
&
ov
,
1
);
rv
=
nghttp2_frame_pack_origin
(
&
bufs
,
&
frame
);
CU_ASSERT
(
0
==
rv
);
ud
.
frame_recv_cb_called
=
0
;
rv
=
nghttp2_session_mem_recv
(
session
,
bufs
.
head
->
buf
.
pos
,
nghttp2_bufs_len
(
&
bufs
));
CU_ASSERT
((
ssize_t
)
nghttp2_bufs_len
(
&
bufs
)
==
rv
);
CU_ASSERT
(
0
==
ud
.
frame_recv_cb_called
);
nghttp2_session_del
(
session
);
nghttp2_bufs_reset
(
&
bufs
);
/* Receiving empty ORIGIN frame */
nghttp2_session_client_new2
(
&
session
,
&
callbacks
,
&
ud
,
option
);
nghttp2_frame_origin_init
(
&
frame
,
NULL
,
0
);
rv
=
nghttp2_frame_pack_origin
(
&
bufs
,
&
frame
);
CU_ASSERT
(
0
==
rv
);
ud
.
frame_recv_cb_called
=
0
;
rv
=
nghttp2_session_mem_recv
(
session
,
bufs
.
head
->
buf
.
pos
,
nghttp2_bufs_len
(
&
bufs
));
CU_ASSERT
((
ssize_t
)
nghttp2_bufs_len
(
&
bufs
)
==
rv
);
CU_ASSERT
(
1
==
ud
.
frame_recv_cb_called
);
CU_ASSERT
(
NGHTTP2_ORIGIN
==
ud
.
recv_frame_hd
.
type
);
nghttp2_session_del
(
session
);
nghttp2_option_del
(
option
);
nghttp2_bufs_free
(
&
bufs
);
}
void
test_nghttp2_session_continue
(
void
)
{
nghttp2_session
*
session
;
nghttp2_session_callbacks
callbacks
;
...
...
@@ -6036,6 +6183,95 @@ void test_nghttp2_submit_altsvc(void) {
nghttp2_session_del
(
session
);
}
void
test_nghttp2_submit_origin
(
void
)
{
nghttp2_session
*
session
;
nghttp2_session_callbacks
callbacks
;
my_user_data
ud
;
int
rv
;
ssize_t
len
;
const
uint8_t
*
data
;
static
const
uint8_t
nghttp2
[]
=
"https://nghttp2.org"
;
static
const
uint8_t
examples
[]
=
"https://examples.com"
;
static
const
nghttp2_origin_entry
ov
[]
=
{
{
(
uint8_t
*
)
nghttp2
,
sizeof
(
nghttp2
)
-
1
,
},
{
(
uint8_t
*
)
examples
,
sizeof
(
examples
)
-
1
,
},
};
nghttp2_frame
frame
;
nghttp2_ext_origin
origin
;
nghttp2_mem
*
mem
;
mem
=
nghttp2_mem_default
();
memset
(
&
callbacks
,
0
,
sizeof
(
nghttp2_session_callbacks
));
callbacks
.
on_frame_send_callback
=
on_frame_send_callback
;
frame
.
ext
.
payload
=
&
origin
;
nghttp2_session_server_new
(
&
session
,
&
callbacks
,
&
ud
);
rv
=
nghttp2_submit_origin
(
session
,
NGHTTP2_FLAG_NONE
,
ov
,
2
);
CU_ASSERT
(
0
==
rv
);
ud
.
frame_send_cb_called
=
0
;
len
=
nghttp2_session_mem_send
(
session
,
&
data
);
CU_ASSERT
(
len
>
0
);
CU_ASSERT
(
1
==
ud
.
frame_send_cb_called
);
nghttp2_frame_unpack_frame_hd
(
&
frame
.
hd
,
data
);
rv
=
nghttp2_frame_unpack_origin_payload
(
&
frame
.
ext
,
data
+
NGHTTP2_FRAME_HDLEN
,
(
size_t
)
len
-
NGHTTP2_FRAME_HDLEN
,
mem
);
CU_ASSERT
(
0
==
rv
);
CU_ASSERT
(
0
==
frame
.
hd
.
stream_id
);
CU_ASSERT
(
NGHTTP2_ORIGIN
==
frame
.
hd
.
type
);
CU_ASSERT
(
2
==
origin
.
nov
);
CU_ASSERT
(
0
==
memcmp
(
nghttp2
,
origin
.
ov
[
0
].
origin
,
sizeof
(
nghttp2
)
-
1
));
CU_ASSERT
(
sizeof
(
nghttp2
)
-
1
==
origin
.
ov
[
0
].
origin_len
);
CU_ASSERT
(
0
==
memcmp
(
examples
,
origin
.
ov
[
1
].
origin
,
sizeof
(
examples
)
-
1
));
CU_ASSERT
(
sizeof
(
examples
)
-
1
==
origin
.
ov
[
1
].
origin_len
);
nghttp2_frame_origin_free
(
&
frame
.
ext
,
mem
);
nghttp2_session_del
(
session
);
/* Submitting ORIGIN frame from client session is error */
nghttp2_session_client_new
(
&
session
,
&
callbacks
,
NULL
);
rv
=
nghttp2_submit_origin
(
session
,
NGHTTP2_FLAG_NONE
,
ov
,
1
);
CU_ASSERT
(
NGHTTP2_ERR_INVALID_STATE
==
rv
);
nghttp2_session_del
(
session
);
/* Submitting empty ORIGIN frame */
nghttp2_session_server_new
(
&
session
,
&
callbacks
,
&
ud
);
rv
=
nghttp2_submit_origin
(
session
,
NGHTTP2_FLAG_NONE
,
NULL
,
0
);
CU_ASSERT
(
0
==
rv
);
ud
.
frame_send_cb_called
=
0
;
len
=
nghttp2_session_mem_send
(
session
,
&
data
);
CU_ASSERT
(
len
==
NGHTTP2_FRAME_HDLEN
);
CU_ASSERT
(
1
==
ud
.
frame_send_cb_called
);
nghttp2_frame_unpack_frame_hd
(
&
frame
.
hd
,
data
);
CU_ASSERT
(
NGHTTP2_ORIGIN
==
frame
.
hd
.
type
);
nghttp2_session_del
(
session
);
}
void
test_nghttp2_session_open_stream
(
void
)
{
nghttp2_session
*
session
;
nghttp2_session_callbacks
callbacks
;
...
...
tests/nghttp2_session_test.h
View file @
80342215
...
...
@@ -47,6 +47,7 @@ void test_nghttp2_session_recv_settings_header_table_size(void);
void
test_nghttp2_session_recv_too_large_frame_length
(
void
);
void
test_nghttp2_session_recv_extension
(
void
);
void
test_nghttp2_session_recv_altsvc
(
void
);
void
test_nghttp2_session_recv_origin
(
void
);
void
test_nghttp2_session_continue
(
void
);
void
test_nghttp2_session_add_frame
(
void
);
void
test_nghttp2_session_on_request_headers_received
(
void
);
...
...
@@ -100,6 +101,7 @@ void test_nghttp2_submit_shutdown_notice(void);
void
test_nghttp2_submit_invalid_nv
(
void
);
void
test_nghttp2_submit_extension
(
void
);
void
test_nghttp2_submit_altsvc
(
void
);
void
test_nghttp2_submit_origin
(
void
);
void
test_nghttp2_session_open_stream
(
void
);
void
test_nghttp2_session_open_stream_with_idle_stream_dep
(
void
);
void
test_nghttp2_session_get_next_ob_item
(
void
);
...
...
tests/nghttp2_test_helper.c
View file @
80342215
...
...
@@ -84,6 +84,10 @@ int unpack_frame(nghttp2_frame *frame, const uint8_t *in, size_t len) {
assert
(
payloadlen
>
2
);
nghttp2_frame_unpack_altsvc_payload2
(
&
frame
->
ext
,
payload
,
payloadlen
,
mem
);
break
;
case
NGHTTP2_ORIGIN
:
rv
=
nghttp2_frame_unpack_origin_payload
(
&
frame
->
ext
,
payload
,
payloadlen
,
mem
);
break
;
default:
/* Must not be reachable */
assert
(
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