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
ecabef2d
Commit
ecabef2d
authored
Mar 29, 2016
by
Tatsuhiro Tsujikawa
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
altsvc: Add ALTSVC frame support
parent
4a6fc6ce
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
254 additions
and
10 deletions
+254
-10
lib/includes/nghttp2/nghttp2.h
lib/includes/nghttp2/nghttp2.h
+31
-1
lib/nghttp2_frame.c
lib/nghttp2_frame.c
+55
-0
lib/nghttp2_frame.h
lib/nghttp2_frame.h
+17
-0
lib/nghttp2_outbound_item.c
lib/nghttp2_outbound_item.c
+19
-3
lib/nghttp2_outbound_item.h
lib/nghttp2_outbound_item.h
+8
-0
lib/nghttp2_session.c
lib/nghttp2_session.c
+52
-6
lib/nghttp2_submit.c
lib/nghttp2_submit.c
+72
-0
No files found.
lib/includes/nghttp2/nghttp2.h
View file @
ecabef2d
...
...
@@ -591,7 +591,11 @@ typedef enum {
* callbacks because the library processes this frame type and its
* preceding HEADERS/PUSH_PROMISE as a single frame.
*/
NGHTTP2_CONTINUATION
=
0x09
NGHTTP2_CONTINUATION
=
0x09
,
/**
* The ALTSVC frame.
*/
NGHTTP2_ALTSVC
=
0x0a
}
nghttp2_frame_type
;
/**
...
...
@@ -4113,6 +4117,32 @@ NGHTTP2_EXTERN int nghttp2_submit_extension(nghttp2_session *session,
uint8_t
type
,
uint8_t
flags
,
int32_t
stream_id
,
void
*
payload
);
/**
* @struct
*
* The payload of ALTSVC frame. ALTSVC frame is one of extension
* frame. If this frame is received, and
* `nghttp2_option_set_user_recv_extension_type()` is not set, and
* `nghttp2_option_set_recv_extension_type()` is set for
* :enum:`NGHTTP2_ALTSVC`, ``nghttp2_extension.payload`` will point to
* this struct.
*
* It has the following members:
*/
typedef
struct
{
uint8_t
*
origin
;
size_t
origin_len
;
uint8_t
*
field_value
;
size_t
field_value_len
;
}
nghttp2_ext_altsvc
;
NGHTTP2_EXTERN
int
nghttp2_submit_altsvc
(
nghttp2_session
*
session
,
uint8_t
flags
,
int32_t
stream_id
,
const
uint8_t
*
origin
,
size_t
origin_len
,
const
uint8_t
*
field_value
,
size_t
field_value_len
);
/**
* @function
*
...
...
lib/nghttp2_frame.c
View file @
ecabef2d
...
...
@@ -193,6 +193,31 @@ void nghttp2_frame_extension_init(nghttp2_extension *frame, uint8_t type,
void
nghttp2_frame_extension_free
(
nghttp2_extension
*
frame
_U_
)
{}
void
nghttp2_frame_altsvc_init
(
nghttp2_extension
*
frame
,
int32_t
stream_id
,
uint8_t
*
origin
,
size_t
origin_len
,
uint8_t
*
field_value
,
size_t
field_value_len
)
{
nghttp2_ext_altsvc
*
altsvc
;
nghttp2_frame_hd_init
(
&
frame
->
hd
,
2
+
origin_len
+
field_value_len
,
NGHTTP2_ALTSVC
,
NGHTTP2_FLAG_NONE
,
stream_id
);
altsvc
=
frame
->
payload
;
altsvc
->
origin
=
origin
;
altsvc
->
origin_len
=
origin_len
;
altsvc
->
field_value
=
field_value
;
altsvc
->
field_value_len
=
field_value_len
;
}
void
nghttp2_frame_altsvc_free
(
nghttp2_extension
*
frame
,
nghttp2_mem
*
mem
)
{
nghttp2_ext_altsvc
*
altsvc
;
altsvc
=
frame
->
payload
;
/* We use the same buffer for altsvc->origin and
altsvc->field_value. */
nghttp2_mem_free
(
mem
,
altsvc
->
origin
);
nghttp2_mem_free
(
mem
,
altsvc
);
}
size_t
nghttp2_frame_priority_len
(
uint8_t
flags
)
{
if
(
flags
&
NGHTTP2_FLAG_PRIORITY
)
{
return
NGHTTP2_PRIORITY_SPECLEN
;
...
...
@@ -668,6 +693,36 @@ void nghttp2_frame_unpack_window_update_payload(nghttp2_window_update *frame,
nghttp2_get_uint32
(
payload
)
&
NGHTTP2_WINDOW_SIZE_INCREMENT_MASK
;
}
int
nghttp2_frame_pack_altsvc
(
nghttp2_bufs
*
bufs
,
nghttp2_extension
*
frame
)
{
int
rv
;
nghttp2_buf
*
buf
;
nghttp2_ext_altsvc
*
altsvc
;
altsvc
=
frame
->
payload
;
buf
=
&
bufs
->
head
->
buf
;
assert
(
nghttp2_buf_avail
(
buf
)
>=
2
+
altsvc
->
origin_len
+
altsvc
->
field_value_len
);
buf
->
pos
-=
NGHTTP2_FRAME_HDLEN
;
nghttp2_frame_pack_frame_hd
(
buf
->
pos
,
&
frame
->
hd
);
nghttp2_put_uint16be
(
buf
->
last
,
(
uint16_t
)
altsvc
->
origin_len
);
buf
->
last
+=
2
;
rv
=
nghttp2_bufs_add
(
bufs
,
altsvc
->
origin
,
altsvc
->
origin_len
);
assert
(
rv
==
0
);
rv
=
nghttp2_bufs_add
(
bufs
,
altsvc
->
field_value
,
altsvc
->
field_value_len
);
assert
(
rv
==
0
);
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 @
ecabef2d
...
...
@@ -367,6 +367,17 @@ void nghttp2_frame_unpack_window_update_payload(nghttp2_window_update *frame,
const
uint8_t
*
payload
,
size_t
payloadlen
);
/*
* Packs ALTSVC 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 always succeeds and returns 0.
*/
int
nghttp2_frame_pack_altsvc
(
nghttp2_bufs
*
bufs
,
nghttp2_extension
*
ext
);
/*
* Initializes HEADERS frame |frame| with given values. |frame| takes
* ownership of |nva|, so caller must not free it. If |stream_id| is
...
...
@@ -445,6 +456,12 @@ void nghttp2_frame_extension_init(nghttp2_extension *frame, uint8_t type,
void
nghttp2_frame_extension_free
(
nghttp2_extension
*
frame
);
void
nghttp2_frame_altsvc_init
(
nghttp2_extension
*
frame
,
int32_t
stream_id
,
uint8_t
*
origin
,
size_t
origin_len
,
uint8_t
*
field_value
,
size_t
field_value_len
);
void
nghttp2_frame_altsvc_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_outbound_item.c
View file @
ecabef2d
...
...
@@ -72,9 +72,25 @@ void nghttp2_outbound_item_free(nghttp2_outbound_item *item, nghttp2_mem *mem) {
case
NGHTTP2_WINDOW_UPDATE
:
nghttp2_frame_window_update_free
(
&
frame
->
window_update
);
break
;
default:
nghttp2_frame_extension_free
(
&
frame
->
ext
);
break
;
default:
{
nghttp2_ext_aux_data
*
aux_data
;
aux_data
=
&
item
->
aux_data
.
ext
;
if
(
aux_data
->
builtin
==
0
)
{
nghttp2_frame_extension_free
(
&
frame
->
ext
);
break
;
}
switch
(
frame
->
hd
.
type
)
{
case
NGHTTP2_ALTSVC
:
nghttp2_frame_altsvc_free
(
&
frame
->
ext
,
mem
);
break
;
default:
assert
(
0
);
break
;
}
}
}
}
...
...
lib/nghttp2_outbound_item.h
View file @
ecabef2d
...
...
@@ -87,11 +87,19 @@ typedef struct {
uint8_t
flags
;
}
nghttp2_goaway_aux_data
;
/* struct used for extension frame */
typedef
struct
{
/* nonzero if this extension frame is serialized by library
function, instead of user-defined callbacks. */
uint8_t
builtin
;
}
nghttp2_ext_aux_data
;
/* Additional data which cannot be stored in nghttp2_frame struct */
typedef
union
{
nghttp2_data_aux_data
data
;
nghttp2_headers_aux_data
headers
;
nghttp2_goaway_aux_data
goaway
;
nghttp2_ext_aux_data
ext
;
}
nghttp2_aux_data
;
struct
nghttp2_outbound_item
;
...
...
lib/nghttp2_session.c
View file @
ecabef2d
...
...
@@ -1664,6 +1664,26 @@ static int session_predicate_window_update_send(nghttp2_session *session,
return
0
;
}
static
int
session_predicate_altsvc_send
(
nghttp2_session
*
session
,
int32_t
stream_id
)
{
nghttp2_stream
*
stream
;
if
(
session_is_closing
(
session
))
{
return
NGHTTP2_ERR_SESSION_CLOSING
;
}
if
(
stream_id
==
0
)
{
return
0
;
}
stream
=
nghttp2_session_get_stream
(
session
,
stream_id
);
if
(
stream
==
NULL
)
{
return
NGHTTP2_ERR_STREAM_CLOSED
;
}
return
0
;
}
/* Take into account settings max frame size and both connection-level
flow control here */
static
ssize_t
...
...
@@ -2103,19 +2123,45 @@ static int session_prep_frame(nghttp2_session *session,
/* We never handle CONTINUATION here. */
assert
(
0
);
break
;
default:
default:
{
nghttp2_ext_aux_data
*
aux_data
;
/* extension frame */
if
(
session_is_closing
(
session
))
{
return
NGHTTP2_ERR_SESSION_CLOSING
;
aux_data
=
&
item
->
aux_data
.
ext
;
if
(
aux_data
->
builtin
==
0
)
{
if
(
session_is_closing
(
session
))
{
return
NGHTTP2_ERR_SESSION_CLOSING
;
}
rv
=
session_pack_extension
(
session
,
&
session
->
aob
.
framebufs
,
frame
);
if
(
rv
!=
0
)
{
return
rv
;
}
break
;
}
rv
=
session_pack_extension
(
session
,
&
session
->
aob
.
framebufs
,
frame
);
if
(
rv
!=
0
)
{
return
rv
;
switch
(
frame
->
hd
.
type
)
{
case
NGHTTP2_ALTSVC
:
rv
=
session_predicate_altsvc_send
(
session
,
frame
->
hd
.
stream_id
);
if
(
rv
!=
0
)
{
return
rv
;
}
nghttp2_frame_pack_altsvc
(
&
session
->
aob
.
framebufs
,
&
frame
->
ext
);
break
;
default:
/* Unreachable here */
assert
(
0
);
break
;
}
break
;
}
}
return
0
;
}
else
{
size_t
next_readmax
;
...
...
lib/nghttp2_submit.c
View file @
ecabef2d
...
...
@@ -410,6 +410,78 @@ int nghttp2_submit_window_update(nghttp2_session *session, uint8_t flags,
return
0
;
}
int
nghttp2_submit_altsvc
(
nghttp2_session
*
session
,
uint8_t
flags
_U_
,
int32_t
stream_id
,
const
uint8_t
*
origin
,
size_t
origin_len
,
const
uint8_t
*
field_value
,
size_t
field_value_len
)
{
nghttp2_mem
*
mem
;
uint8_t
*
buf
,
*
p
;
uint8_t
*
origin_copy
;
uint8_t
*
field_value_copy
;
nghttp2_outbound_item
*
item
;
nghttp2_frame
*
frame
;
nghttp2_ext_altsvc
*
altsvc
;
int
rv
;
mem
=
&
session
->
mem
;
if
(
2
+
origin_len
+
field_value_len
>
NGHTTP2_MAX_PAYLOADLEN
)
{
return
NGHTTP2_ERR_INVALID_ARGUMENT
;
}
buf
=
nghttp2_mem_malloc
(
mem
,
origin_len
+
field_value_len
+
2
);
if
(
buf
==
NULL
)
{
return
NGHTTP2_ERR_NOMEM
;
}
p
=
buf
;
origin_copy
=
p
;
p
=
nghttp2_cpymem
(
p
,
origin
,
origin_len
);
*
p
++
=
'\0'
;
field_value_copy
=
p
;
p
=
nghttp2_cpymem
(
p
,
field_value
,
field_value_len
);
*
p
++
=
'\0'
;
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
;
altsvc
=
nghttp2_mem_malloc
(
mem
,
sizeof
(
nghttp2_outbound_item
));
if
(
item
==
NULL
)
{
rv
=
NGHTTP2_ERR_NOMEM
;
goto
fail_altsvc_malloc
;
}
frame
=
&
item
->
frame
;
frame
->
ext
.
payload
=
altsvc
;
nghttp2_frame_altsvc_init
(
&
frame
->
ext
,
stream_id
,
origin_copy
,
origin_len
,
field_value_copy
,
field_value_len
);
rv
=
nghttp2_session_add_item
(
session
,
item
);
if
(
rv
!=
0
)
{
nghttp2_frame_altsvc_free
(
&
frame
->
ext
,
mem
);
nghttp2_mem_free
(
mem
,
item
);
}
return
0
;
fail_altsvc_malloc:
free
(
item
);
fail_item_malloc:
free
(
buf
);
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
;
...
...
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