Implement HTTP-draft-04/2.0

This commit is contained in:
Tatsuhiro Tsujikawa 2013-07-15 21:45:59 +09:00
parent cdc7fee1e6
commit 48cb017245
32 changed files with 3889 additions and 6931 deletions

View File

@ -20,7 +20,7 @@
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
SUBDIRS = lib src tests examples doc
SUBDIRS = lib src tests doc
ACLOCAL_AMFLAGS = -I m4

View File

@ -33,16 +33,16 @@ lib_LTLIBRARIES = libnghttp2.la
OBJECTS = nghttp2_pq.c nghttp2_map.c nghttp2_queue.c \
nghttp2_buffer.c nghttp2_frame.c nghttp2_zlib.c \
nghttp2_session.c nghttp2_helper.c nghttp2_stream.c nghttp2_npn.c \
nghttp2_submit.c nghttp2_outbound_item.c \
nghttp2_client_cert_vector.c nghttp2_gzip.c
nghttp2_stream.c nghttp2_outbound_item.c \
nghttp2_session.c nghttp2_submit.c \
nghttp2_helper.c \
nghttp2_npn.c nghttp2_gzip.c
HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
nghttp2_buffer.h nghttp2_frame.h nghttp2_zlib.h \
nghttp2_session.h nghttp2_helper.h nghttp2_stream.h nghttp2_int.h \
nghttp2_npn.h nghttp2_gzip.h \
nghttp2_submit.h nghttp2_outbound_item.h \
nghttp2_client_cert_vector.h \
nghttp2_net.h
libnghttp2_la_SOURCES = $(HFILES) $(OBJECTS)

File diff suppressed because it is too large Load Diff

View File

@ -1,156 +0,0 @@
/*
* nghttp2 - HTTP/2.0 C Library
*
* Copyright (c) 2012 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "nghttp2_client_cert_vector.h"
#include <string.h>
#include "nghttp2_helper.h"
int nghttp2_origin_equal(const nghttp2_origin *lhs, const nghttp2_origin *rhs)
{
return strcmp(lhs->scheme, rhs->scheme) == 0 &&
strcmp(lhs->host, rhs->host) == 0 && lhs->port == rhs->port;
}
int nghttp2_origin_set(nghttp2_origin *origin,
const char *scheme, const char *host, uint16_t port)
{
if(strlen(scheme) > NGHTTP2_MAX_SCHEME ||
strlen(host) > NGHTTP2_MAX_HOSTNAME) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
strcpy(origin->scheme, scheme);
strcpy(origin->host, host);
origin->port = port;
return 0;
}
const char* nghttp2_origin_get_scheme(const nghttp2_origin *origin)
{
return origin->scheme;
}
const char* nghttp2_origin_get_host(const nghttp2_origin *origin)
{
return origin->host;
}
uint16_t nghttp2_origin_get_port(const nghttp2_origin *origin)
{
return origin->port;
}
int nghttp2_client_cert_vector_init(nghttp2_client_cert_vector *certvec,
size_t size)
{
certvec->size = certvec->capacity = size;
certvec->last_slot = 0;
if(certvec->capacity) {
size_t vec_size = sizeof(nghttp2_origin*)*certvec->capacity;
certvec->vector = malloc(vec_size);
if(certvec->vector == NULL) {
return NGHTTP2_ERR_NOMEM;
}
memset(certvec->vector, 0, vec_size);
} else {
certvec->vector = NULL;
}
return 0;
}
void nghttp2_client_cert_vector_free(nghttp2_client_cert_vector *certvec)
{
size_t i;
for(i = 0; i < certvec->size; ++i) {
free(certvec->vector[i]);
}
free(certvec->vector);
}
int nghttp2_client_cert_vector_resize(nghttp2_client_cert_vector *certvec,
size_t size)
{
if(certvec->capacity < size) {
nghttp2_origin **vector = realloc(certvec->vector,
sizeof(nghttp2_origin*)*size);
if(vector == NULL) {
return NGHTTP2_ERR_NOMEM;
}
memset(vector + certvec->capacity, 0,
sizeof(nghttp2_origin*)*(size - certvec->capacity));
certvec->vector = vector;
certvec->size = certvec->capacity = size;
} else {
size_t i;
for(i = size; i < certvec->size; ++i) {
free(certvec->vector[i]);
certvec->vector[i] = NULL;
}
certvec->size = nghttp2_min(certvec->size, size);
if(certvec->last_slot > certvec->size) {
certvec->last_slot = certvec->size;
}
}
return 0;
}
size_t nghttp2_client_cert_vector_find(nghttp2_client_cert_vector *certvec,
const nghttp2_origin *origin)
{
size_t i;
for(i = 0; i < certvec->size && certvec->vector[i]; ++i) {
if(nghttp2_origin_equal(origin, certvec->vector[i])) {
return i+1;
}
}
return 0;
}
size_t nghttp2_client_cert_vector_put(nghttp2_client_cert_vector *certvec,
nghttp2_origin *origin)
{
if(certvec->size == 0) {
return 0;
}
if(certvec->last_slot == certvec->size) {
certvec->last_slot = 1;
} else {
++certvec->last_slot;
}
free(certvec->vector[certvec->last_slot-1]);
certvec->vector[certvec->last_slot-1] = origin;
return certvec->last_slot;
}
const nghttp2_origin* nghttp2_client_cert_vector_get_origin
(nghttp2_client_cert_vector *certvec,
size_t slot)
{
if(slot == 0 || slot > certvec->size || !certvec->vector[slot-1]) {
return NULL;
} else {
return certvec->vector[slot-1];
}
}

View File

@ -1,112 +0,0 @@
/*
* nghttp2 - HTTP/2.0 C Library
*
* Copyright (c) 2012 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef NGHTTP2_CLIENT_CERT_VECTOR_H
#define NGHTTP2_CLIENT_CERT_VECTOR_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h>
struct nghttp2_origin {
char scheme[NGHTTP2_MAX_SCHEME+1];
char host[NGHTTP2_MAX_HOSTNAME+1];
uint16_t port;
};
typedef struct {
nghttp2_origin **vector;
/* The size of the vector. */
size_t size;
/* The real capacity of the vector. size <= capacity holds true. */
size_t capacity;
/* The last slot where origin is stored. The default value is 0. */
size_t last_slot;
} nghttp2_client_cert_vector;
/*
* Returns nonzero if |lhs| and |rhs| are equal. The equality is
* defined such that each member is equal respectively.
*/
int nghttp2_origin_equal(const nghttp2_origin *lhs, const nghttp2_origin *rhs);
/*
* Convenient function to set members to the |origin|. The |origin|
* must be allocated prior this call.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_INVALID_ARGUMENT
* The |scheme| is longer than NGHTTP2_MAX_SCHEME; or the |host|
* is longer than NGHTTP2_MAX_HOSTNAME.
*/
int nghttp2_origin_set(nghttp2_origin *origin,
const char *scheme, const char *host, uint16_t port);
/*
* Initializes the client certificate vector with the vector size
* |size|.
*/
int nghttp2_client_cert_vector_init(nghttp2_client_cert_vector *certvec,
size_t size);
void nghttp2_client_cert_vector_free(nghttp2_client_cert_vector *certvec);
/*
* Returns the slot of the |origin| in the client certificate vector.
* If it is not found, returns 0.
*/
size_t nghttp2_client_cert_vector_find(nghttp2_client_cert_vector *certvec,
const nghttp2_origin *origin);
/*
* Puts the |origin| to the |certvec|. This function takes ownership
* of the |origin| on success.
*
* This function returns the positive slot index of the certificate
* vector where the |origin| is stored if it succeeds, or 0.
*/
size_t nghttp2_client_cert_vector_put(nghttp2_client_cert_vector *certvec,
nghttp2_origin *origin);
/*
* Resizes client certificate vector to the size |size|.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
int nghttp2_client_cert_vector_resize(nghttp2_client_cert_vector *certvec,
size_t size);
const nghttp2_origin* nghttp2_client_cert_vector_get_origin
(nghttp2_client_cert_vector *certvec,
size_t slot);
#endif /* NGHTTP2_CLIENT_CERT_VECTOR_H */

File diff suppressed because it is too large Load Diff

View File

@ -32,64 +32,46 @@
#include <nghttp2/nghttp2.h>
#include "nghttp2_zlib.h"
#include "nghttp2_buffer.h"
#include "nghttp2_client_cert_vector.h"
/**
* @macro
* default priority value
*/
#define NGHTTP2_PRI_DEFAULT (1 << 30)
#define NGHTTP2_PRI_LOWEST ((1U << 31) - 1)
#define NGHTTP2_STREAM_ID_MASK 0x7fffffff
/* This is actually the maximum length of a control frame in SPDY/2
and 3. */
#define NGHTTP2_LENGTH_MASK 0xffffff
#define NGHTTP2_VERSION_MASK 0x7fff
#define NGHTTP2_DELTA_WINDOW_SIZE_MASK 0x7fffffff
#define NGHTTP2_PRIORITY_MASK 0x7fffffff
#define NGHTTP2_WINDOW_SIZE_INCREMENT_MASK 0x7fffffff
#define NGHTTP2_SETTINGS_ID_MASK 0xffffff
/* The length of DATA frame payload. */
/* The maximum length of DATA frame payload. */
#define NGHTTP2_DATA_PAYLOAD_LENGTH 4096
/* The number of bytes of frame header. */
#define NGHTTP2_FRAME_HEAD_LENGTH 8
/* The offset to the name/value header block in the frame (including
frame header) */
#define NGHTTP2_SYN_STREAM_NV_OFFSET 18
#define NGHTTP2_SPDY2_SYN_REPLY_NV_OFFSET 14
#define NGHTTP2_SPDY3_SYN_REPLY_NV_OFFSET 12
#define NGHTTP2_SPDY2_HEADERS_NV_OFFSET 14
#define NGHTTP2_SPDY3_HEADERS_NV_OFFSET 12
#define nghttp2_frame_get_nv_len(RED, LEN_SIZE) \
(LEN_SIZE == 2 ? nghttp2_buffer_reader_uint16(RED) : \
nghttp2_buffer_reader_uint32(RED))
#define nghttp2_frame_put_nv_len(OUT, VAL, LEN_SIZE) \
(LEN_SIZE == 2 ? \
nghttp2_put_uint16be(OUT, VAL) : nghttp2_put_uint32be(OUT, VAL))
/* Category of SPDY frames. */
/* Category of frames. */
typedef enum {
/* Control frame */
NGHTTP2_CTRL,
/* non-DATA frame */
NGHTTP2_CAT_CTRL,
/* DATA frame */
NGHTTP2_DATA
NGHTTP2_CAT_DATA
} nghttp2_frame_category;
#define nghttp2_frame_get_nv_len(RED) nghttp2_buffer_reader_uint16(RED)
#define nghttp2_frame_put_nv_len(OUT, VAL) nghttp2_put_uint16be(OUT, VAL)
/**
* @struct
* The DATA frame. It has the following members:
*/
typedef struct {
/**
* The stream ID.
*/
int32_t stream_id;
/**
* The DATA frame flags. See :type:`nghttp2_data_flag`.
*/
uint8_t flags;
nghttp2_frame_hd hd;
/**
* The flag to indicate whether EOF was reached or not. Initially
* |eof| is 0. It becomes 1 after all data were read.
* |eof| is 0. It becomes 1 after all data were read. This is used
* exclusively by nghttp2 library and not in the spec.
*/
uint8_t eof;
/**
@ -98,15 +80,14 @@ typedef struct {
nghttp2_data_provider data_prd;
} nghttp2_data;
/*
* Returns the number of bytes in length of name/value pair for the
* given protocol version |version|. If |version| is not supported,
* returns 0.
*/
size_t nghttp2_frame_get_len_size(uint16_t version);
int nghttp2_frame_is_data_frame(uint8_t *head);
void nghttp2_frame_pack_frame_hd(uint8_t *buf, const nghttp2_frame_hd *hd);
void nghttp2_frame_unpack_frame_hd(nghttp2_frame_hd *hd, const uint8_t* buf);
/*
* Packs SYN_STREAM frame |frame| in wire format and store it in
* Packs HEADERS frame |frame| in wire format and store it in
* |*buf_ptr|. The capacity of |*buf_ptr| is |*buflen_ptr| bytes.
* The |*nvbuf_ptr| is used to store inflated name/value pairs in wire
* format temporarily. Its length is |*nvbuflen_ptr| bytes. This
@ -122,8 +103,6 @@ size_t nghttp2_frame_get_len_size(uint16_t version);
* This function returns the size of packed frame if it succeeds, or
* returns one of the following negative error codes:
*
* NGHTTP2_ERR_UNSUPPORTED_VERSION
* The version is not supported.
* NGHTTP2_ERR_ZLIB
* The deflate operation failed.
* NGHTTP2_ERR_FRAME_TOO_LARGE
@ -131,18 +110,18 @@ size_t nghttp2_frame_get_len_size(uint16_t version);
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
ssize_t nghttp2_frame_pack_syn_stream(uint8_t **buf_ptr,
size_t *buflen_ptr,
uint8_t **nvbuf_ptr,
size_t *nvbuflen_ptr,
nghttp2_syn_stream *frame,
nghttp2_zlib *deflater);
ssize_t nghttp2_frame_pack_headers(uint8_t **buf_ptr,
size_t *buflen_ptr,
uint8_t **nvbuf_ptr,
size_t *nvbuflen_ptr,
nghttp2_headers *frame,
nghttp2_zlib *deflater);
/*
* Unpacks SYN_STREAM frame byte sequence into |frame|. The control
* frame header is given in |head| with |headlen| length. In spdy/3
* spec, headlen is 8 bytes. |payload| is the data after length field
* of the header and just before name/value header block.
* Unpacks HEADERS frame byte sequence into |frame|. The control
* frame header is given in |head| with |headlen| length. In the spec,
* headlen is 8 bytes. |payload| is the data after frame header and
* just before name/value header block.
*
* The |inflatebuf| contains inflated name/value header block in wire
* foramt.
@ -158,107 +137,116 @@ ssize_t nghttp2_frame_pack_syn_stream(uint8_t **buf_ptr,
* Unpacking succeeds but the header block is invalid.
* NGHTTP2_ERR_INVALID_FRAME
* The input data are invalid.
* NGHTTP2_ERR_UNSUPPORTED_VERSION
* The version is not supported.
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
int nghttp2_frame_unpack_syn_stream(nghttp2_syn_stream *frame,
int nghttp2_frame_unpack_headers(nghttp2_headers *frame,
const uint8_t *head, size_t headlen,
const uint8_t *payload, size_t payloadlen,
nghttp2_buffer *inflatebuf);
/*
* Unpacks HEADERS frame byte sequence into |frame|. This function
* only unapcks bytes that come before name/value header block.
*
* This function returns 0 if it succeeds or one of the following
* negative error codes:
*
* NGHTTP2_ERR_INVALID_FRAME
* The input data are invalid.
*/
int nghttp2_frame_unpack_headers_without_nv(nghttp2_headers *frame,
const uint8_t *head,
size_t headlen,
const uint8_t *payload,
size_t payloadlen);
/*
* Packs PRIORITY frame |frame| in wire format and store it in
* |*buf_ptr|. The capacity of |*buf_ptr| is |*buflen_ptr|
* length. This function expands |*buf_ptr| as necessary to store
* given |frame|.
*
* This function returns 0 if it succeeds or one of the following
* negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
ssize_t nghttp2_frame_pack_priority(uint8_t **buf_ptr, size_t *buflen_ptr,
nghttp2_priority *frame);
/*
* Unpacks PRIORITY wire format into |frame|.
*
* This function returns 0 if it succeeds or one of the following
* negative error codes:
*
* NGHTTP2_ERR_INVALID_FRAME
* The input data are invalid.
*/
int nghttp2_frame_unpack_priority(nghttp2_priority *frame,
const uint8_t *head, size_t headlen,
const uint8_t *payload, size_t payloadlen);
/*
* Packs RST_STREAM frame |frame| in wire frame format and store it in
* |*buf_ptr|. The capacity of |*buf_ptr| is |*buflen_ptr|
* length. This function expands |*buf_ptr| as necessary to store
* given |frame|. In spdy/2 spec, RST_STREAM wire format is always 16
* bytes long.
*
* This function returns the size of packed frame if it succeeds, or
* returns one of the following negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
ssize_t nghttp2_frame_pack_rst_stream(uint8_t **buf_ptr, size_t *buflen_ptr,
nghttp2_rst_stream *frame);
/*
* Unpacks RST_STREAM frame byte sequence into |frame|.
*
* This function returns 0 if it succeeds or one of the following
* negative error codes:
*
* NGHTTP2_ERR_INVALID_FRAME
* The input data are invalid.
*/
int nghttp2_frame_unpack_rst_stream(nghttp2_rst_stream *frame,
const uint8_t *head, size_t headlen,
const uint8_t *payload, size_t payloadlen,
nghttp2_buffer *inflatebuf);
const uint8_t *payload, size_t payloadlen);
/*
* Unpacks SYN_STREAM frame byte sequence into |frame|. This function
* only unapcks bytes that come before name/value header block.
*
* This function returns 0 if it succeeds or one of the following
* negative error codes:
*
* NGHTTP2_ERR_INVALID_FRAME
* The input data are invalid.
*/
int nghttp2_frame_unpack_syn_stream_without_nv(nghttp2_syn_stream *frame,
const uint8_t *head,
size_t headlen,
const uint8_t *payload,
size_t payloadlen);
/*
* Packs SYN_REPLY frame |frame| in wire frame format and store it in
* |*buf_ptr|. The capacity of |*buf_ptr| is |*buflen_ptr| bytes.
* The |*nvbuf_ptr| is used to store inflated name/value pairs in wire
* format temporarily. Its length is |*nvbuflen_ptr| bytes. This
* function expands |*buf_ptr| and |*nvbuf_ptr| as necessary to store
* frame and name/value pairs. When expansion occurred, memory
* previously pointed by |*buf_ptr| and |*nvbuf_ptr| is freed.
* |*buf_ptr|, |*buflen_ptr|, |*nvbuf_ptr| and |*nvbuflen_ptr| are
* updated accordingly.
*
* frame->hd.length is assigned after length is determined during
* packing process.
* Packs SETTINGS frame |frame| in wire format and store it in
* |*buf_ptr|. The capacity of |*buf_ptr| is |*buflen_ptr|
* length. This function expands |*buf_ptr| as necessary to store
* given |frame|.
*
* This function returns the size of packed frame if it succeeds, or
* returns one of the following negative error codes:
*
* NGHTTP2_ERR_UNSUPPORTED_VERSION
* The version is not supported.
* NGHTTP2_ERR_ZLIB
* The deflate operation failed.
* NGHTTP2_ERR_FRAME_TOO_LARGE
* The length of the frame is too large.
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
ssize_t nghttp2_frame_pack_syn_reply(uint8_t **buf_ptr,
size_t *buflen_ptr,
uint8_t **nvbuf_ptr,
size_t *nvbuflen_ptr,
nghttp2_syn_reply *frame,
nghttp2_zlib *deflater);
ssize_t nghttp2_frame_pack_settings(uint8_t **buf_ptr, size_t *buflen_ptr,
nghttp2_settings *frame);
/*
* Unpacks SYN_REPLY frame byte sequence into |frame|.
*
* The |inflatebuf| contains inflated name/value header block in wire
* foramt.
*
* This function also validates the name/value pairs. If unpacking
* succeeds but validation fails, it is indicated by returning
* NGHTTP2_ERR_INVALID_HEADER_BLOCK.
*
* This function returns 0 if it succeeds or one of the following
* negative error codes:
*
* NGHTTP2_ERR_INVALID_HEADER_BLOCK
* Unpacking succeeds but the header block is invalid.
* NGHTTP2_ERR_UNSUPPORTED_VERSION
* The version is not supported.
* NGHTTP2_ERR_INVALID_FRAME
* The input data are invalid.
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
int nghttp2_frame_unpack_syn_reply(nghttp2_syn_reply *frame,
const uint8_t *head, size_t headlen,
const uint8_t *payload, size_t payloadlen,
nghttp2_buffer *inflatebuf);
/*
* Unpacks SYN_REPLY frame byte sequence into |frame|. This function
* only unapcks bytes that come before name/value header block.
* Unpacks SETTINGS wire format into |frame|.
*
* This function returns 0 if it succeeds or one of the following
* negative error codes:
*
* NGHTTP2_ERR_INVALID_FRAME
* The input data are invalid.
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
int nghttp2_frame_unpack_syn_reply_without_nv(nghttp2_syn_reply *frame,
const uint8_t *head,
size_t headlen,
const uint8_t *payload,
size_t payloadlen);
int nghttp2_frame_unpack_settings(nghttp2_settings *frame,
const uint8_t *head, size_t headlen,
const uint8_t *payload, size_t payloadlen);
/*
* Packs PING frame |frame| in wire format and store it in
@ -297,8 +285,6 @@ int nghttp2_frame_unpack_ping(nghttp2_ping *frame,
* This function returns 0 if it succeeds or one of the following
* negative error codes:
*
* NGHTTP2_ERR_UNSUPPORTED_VERSION
* The version is not supported.
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
@ -311,119 +297,15 @@ ssize_t nghttp2_frame_pack_goaway(uint8_t **buf_ptr, size_t *buflen_ptr,
* This function returns 0 if it succeeds or one of the following
* negative error codes:
*
* NGHTTP2_ERR_UNSUPPORTED_VERSION
* The version is not supported.
* NGHTTP2_ERR_INVALID_FRAME
* The input data are invalid.
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
int nghttp2_frame_unpack_goaway(nghttp2_goaway *frame,
const uint8_t *head, size_t headlen,
const uint8_t *payload, size_t payloadlen);
/*
* Packs HEADERS frame |frame| in wire format and store it in
* |*buf_ptr|. The capacity of |*buf_ptr| is |*buflen_ptr| bytes.
* The |*nvbuf_ptr| is used to store inflated name/value pairs in wire
* format temporarily. Its length is |*nvbuflen_ptr| bytes. This
* function expands |*buf_ptr| and |*nvbuf_ptr| as necessary to store
* frame and name/value pairs. When expansion occurred, memory
* previously pointed by |*buf_ptr| and |*nvbuf_ptr| is freed.
* |*buf_ptr|, |*buflen_ptr|, |*nvbuf_ptr| and |*nvbuflen_ptr| are
* updated accordingly.
*
* frame->hd.length is assigned after length is determined during
* packing process.
*
* This function returns the size of packed frame if it succeeds, or
* returns one of the following negative error codes:
*
* NGHTTP2_ERR_UNSUPPORTED_VERSION
* The version is not supported.
* NGHTTP2_ERR_ZLIB
* The deflate operation failed.
* NGHTTP2_ERR_FRAME_TOO_LARGE
* The length of the frame is too large.
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
ssize_t nghttp2_frame_pack_headers(uint8_t **buf_ptr, size_t *buflen_ptr,
uint8_t **nvbuf_ptr, size_t *nvbuflen_ptr,
nghttp2_headers *frame,
nghttp2_zlib *deflater);
/*
* Unpacks HEADERS wire format into |frame|.
*
* The |inflatebuf| contains inflated name/value header block in wire
* foramt.
*
* This function also validates the name/value pairs. If unpacking
* succeeds but validation fails, it is indicated by returning
* NGHTTP2_ERR_INVALID_HEADER_BLOCK.
*
* This function returns 0 if it succeeds or one of the following
* negative error codes:
*
* NGHTTP2_ERR_INVALID_HEADER_BLOCK
* Unpacking succeeds but the header block is invalid.
* NGHTTP2_ERR_UNSUPPORTED_VERSION
* The version is not supported.
* NGHTTP2_ERR_INVALID_FRAME
* The input data are invalid.
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
int nghttp2_frame_unpack_headers(nghttp2_headers *frame,
const uint8_t *head, size_t headlen,
const uint8_t *payload, size_t payloadlen,
nghttp2_buffer *inflatebuf);
/*
* Unpacks HEADERS frame byte sequence into |frame|. This function
* only unapcks bytes that come before name/value header block.
*
* This function returns 0 if it succeeds or one of the following
* negative error codes:
*
* NGHTTP2_ERR_INVALID_FRAME
* The input data are invalid.
*/
int nghttp2_frame_unpack_headers_without_nv(nghttp2_headers *frame,
const uint8_t *head,
size_t headlen,
const uint8_t *payload,
size_t payloadlen);
/*
* Packs RST_STREAM frame |frame| in wire frame format and store it in
* |*buf_ptr|. The capacity of |*buf_ptr| is |*buflen_ptr|
* length. This function expands |*buf_ptr| as necessary to store
* given |frame|. In spdy/2 spec, RST_STREAM wire format is always 16
* bytes long.
*
* This function returns the size of packed frame if it succeeds, or
* returns one of the following negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
ssize_t nghttp2_frame_pack_rst_stream(uint8_t **buf_ptr, size_t *buflen_ptr,
nghttp2_rst_stream *frame);
/*
* Unpacks RST_STREAM frame byte sequence into |frame|.
*
* This function returns 0 if it succeeds or one of the following
* negative error codes:
*
* NGHTTP2_ERR_INVALID_FRAME
* The input data are invalid.
*/
int nghttp2_frame_unpack_rst_stream(nghttp2_rst_stream *frame,
const uint8_t *head, size_t headlen,
const uint8_t *payload, size_t payloadlen);
/*
* Packs WINDOW_UPDATE frame |frame| in wire frame format and store it
* in |*buf_ptr|. The capacity of |*buf_ptr| is |*buflen_ptr|
@ -454,69 +336,6 @@ int nghttp2_frame_unpack_window_update(nghttp2_window_update *frame,
const uint8_t *payload,
size_t payloadlen);
/*
* Packs SETTINGS frame |frame| in wire format and store it in
* |*buf_ptr|. The capacity of |*buf_ptr| is |*buflen_ptr|
* length. This function expands |*buf_ptr| as necessary to store
* given |frame|.
*
* This function returns the size of packed frame if it succeeds, or
* returns one of the following negative error codes:
*
* NGHTTP2_ERR_UNSUPPORTED_VERSION
* The version is not supported.
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
ssize_t nghttp2_frame_pack_settings(uint8_t **buf_ptr, size_t *buflen_ptr,
nghttp2_settings *frame);
/*
* Unpacks SETTINGS wire format into |frame|.
*
* This function returns 0 if it succeeds or one of the following
* negative error codes:
*
* NGHTTP2_ERR_UNSUPPORTED_VERSION
* The version is not supported.
* NGHTTP2_ERR_INVALID_FRAME
* The input data are invalid.
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
int nghttp2_frame_unpack_settings(nghttp2_settings *frame,
const uint8_t *head, size_t headlen,
const uint8_t *payload, size_t payloadlen);
/*
* Packs CREDENTIAL frame |frame| in wire format and store it in
* |*buf_ptr|. The capacity of |*buf_ptr| is |*buflen_ptr|
* length. This function expands |*buf_ptr| as necessary to store
* given |frame|.
*
* This function returns the size of packed frame if it succeeds, or
* returns one of the following negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
ssize_t nghttp2_frame_pack_credential(uint8_t **buf_ptr, size_t *buflen_ptr,
nghttp2_credential *frame);
/*
* Unpacks CREDENTIAL wire format into |frame|.
*
* This function returns 0 if it succeeds or one of the following
* negative error codes:
*
* NGHTTP2_ERR_INVALID_FRAME
* The input data are invalid.
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
int nghttp2_frame_unpack_credential(nghttp2_credential *frame,
const uint8_t *head, size_t headlen,
const uint8_t *payload, size_t payloadlen);
/*
* Returns number of bytes to pack name/value pairs |nv|. This
* function expects |nv| is sorted in ascending order of key.
@ -622,93 +441,73 @@ int nghttp2_frame_unpack_nv(char ***nv_ptr, nghttp2_buffer *in,
size_t len_size);
/*
* Initializes SYN_STREAM frame |frame| with given values. |frame|
* takes ownership of |nv|, so caller must not free it. If stream_id
* is not assigned yet, it must be 0.
* Initializes HEADERS frame |frame| with given values. |frame|
* takes ownership of |nv|, so caller must not free it. If |stream_id|
* is not assigned yet, it must be -1.
*/
void nghttp2_frame_syn_stream_init(nghttp2_syn_stream *frame,
uint16_t version, uint8_t flags,
int32_t stream_id, int32_t assoc_stream_id,
uint8_t pri, char **nv);
void nghttp2_frame_syn_stream_free(nghttp2_syn_stream *frame);
void nghttp2_frame_syn_reply_init(nghttp2_syn_reply *frame,
uint16_t version, uint8_t flags,
int32_t stream_id, char **nv);
void nghttp2_frame_syn_reply_free(nghttp2_syn_reply *frame);
void nghttp2_frame_ping_init(nghttp2_ping *frame, uint16_t version,
uint32_t unique_id);
void nghttp2_frame_ping_free(nghttp2_ping *frame);
/*
* Initializes GOAWAY frame |frame| with given values. The
* |status_code| is ignored if |version| == NGHTTP2_PROTO_SPDY2.
*/
void nghttp2_frame_goaway_init(nghttp2_goaway *frame, uint16_t version,
int32_t last_good_stream_id,
uint32_t status_code);
void nghttp2_frame_goaway_free(nghttp2_goaway *frame);
void nghttp2_frame_headers_init(nghttp2_headers *frame, uint16_t version,
uint8_t flags,
int32_t stream_id, char **nv);
void nghttp2_frame_headers_init(nghttp2_headers *frame,
uint8_t flags, int32_t stream_id, int32_t pri,
char **nv);
void nghttp2_frame_headers_free(nghttp2_headers *frame);
void nghttp2_frame_priority_init(nghttp2_priority *frame, int32_t stream_id,
int32_t pri);
void nghttp2_frame_priority_free(nghttp2_priority *frame);
void nghttp2_frame_rst_stream_init(nghttp2_rst_stream *frame,
uint16_t version,
int32_t stream_id, uint32_t status_code);
int32_t stream_id,
nghttp2_error_code error_code);
void nghttp2_frame_rst_stream_free(nghttp2_rst_stream *frame);
void nghttp2_frame_window_update_init(nghttp2_window_update *frame,
uint16_t version,
int32_t stream_id,
int32_t delta_window_size);
void nghttp2_frame_window_update_free(nghttp2_window_update *frame);
/*
* Initializes SETTINGS frame |frame| with given values. |frame| takes
* ownership of |iv|, so caller must not free it. The |flags| are
* bitwise-OR of one or more of nghttp2_settings_flag.
*/
void nghttp2_frame_settings_init(nghttp2_settings *frame,
uint16_t version, uint8_t flags,
nghttp2_settings_entry *iv, size_t niv);
void nghttp2_frame_settings_free(nghttp2_settings *frame);
/*
* Initializes CREDENTIAL frame |frame| with given values. This
* function takes ownership of |proof->data| and |certs| on success.
* Note that the ownership of |proof| is not taken.
* Initializes PING frame |frame| with given values. If the
* |opqeue_data| is not NULL, it must point to 8 bytes memory region
* of data. The data pointed by |opaque_data| is copied. It can be
* NULL. In this case, 8 bytes NULL is used.
*/
void nghttp2_frame_credential_init(nghttp2_credential *frame,
uint16_t version, uint16_t slot,
nghttp2_mem_chunk *proof,
nghttp2_mem_chunk *certs,
size_t ncerts);
void nghttp2_frame_ping_init(nghttp2_ping *frame, uint8_t flags,
const uint8_t *opque_data);
void nghttp2_frame_credential_free(nghttp2_credential *frame);
void nghttp2_frame_ping_free(nghttp2_ping *frame);
void nghttp2_frame_data_init(nghttp2_data *frame, int32_t stream_id,
uint8_t flags,
/*
* Initializes GOAWAY frame |frame| with given values. On success,
* this function takes ownership of |opaque_data|, so caller must not
* free it. If the |opaque_data_len| is 0, opaque_data could be NULL.
*/
void nghttp2_frame_goaway_init(nghttp2_goaway *frame, int32_t last_stream_id,
nghttp2_error_code error_code,
uint8_t *opaque_data, size_t opaque_data_len);
void nghttp2_frame_goaway_free(nghttp2_goaway *frame);
void nghttp2_frame_window_update_init(nghttp2_window_update *frame,
uint8_t flags,
int32_t stream_id,
int32_t window_size_increment);
void nghttp2_frame_window_update_free(nghttp2_window_update *frame);
void nghttp2_frame_data_init(nghttp2_data *frame, uint8_t flags,
int32_t stream_id,
const nghttp2_data_provider *data_prd);
void nghttp2_frame_data_free(nghttp2_data *frame);
/*
* Returns 1 if the first byte of this frame indicates it is a control
* frame.
*/
int nghttp2_frame_is_ctrl_frame(uint8_t first_byte);
/*
* Deallocates memory of name/value pair |nv|.
*/
@ -742,34 +541,6 @@ void nghttp2_frame_nv_downcase(char **nv);
*/
char** nghttp2_frame_nv_norm_copy(const char **nv);
/*
* Translates the |nv| in SPDY/3 header names into SPDY/2.
*/
void nghttp2_frame_nv_3to2(char **nv);
/*
* Translates the |nv| in SPDY/2 header names into SPDY/3.
*/
void nghttp2_frame_nv_2to3(char **nv);
/*
* Assigns the members of the |origin| using ":scheme" and ":host"
* values in |nv|.
*
* If ":host" value contains ':', this function parses the chracters
* after ':' as integer and uses it as port number.
*
* If ':' is missing in :host value, the default port number is used.
* The only defined default port number is 443.
*
* This function returns 0 if it succeeds, or one of the following
* negative error code:
*
* NGHTTP2_ERR_INVALID_ARGUMENT
* The |nv| lacks either :scheme or :host, or both.
*/
int nghttp2_frame_nv_set_origin(char **nv, nghttp2_origin *origin);
/*
* Makes copy of |iv| and return the copy. The |niv| is the number of
* entries in |iv|. This function returns the pointer to the copy if
@ -787,11 +558,10 @@ void nghttp2_frame_iv_sort(nghttp2_settings_entry *iv, size_t niv);
/*
* Returns the offset of the name/header block in the frame, including
* frame header. If |type| is neither NGHTTP2_SYN_STREAM,
* NGHTTP2_SYN_REPLY nor NGHTTP2_HEADERS, this function returns -1.
* If |version| is unknown, this function returns -1.
* frame header. The |head| is frame header. If the indicated frame
* type does not have header block, this function returns -1.
*/
ssize_t nghttp2_frame_nv_offset(nghttp2_frame_type type, uint16_t version);
ssize_t nghttp2_frame_nv_offset(const uint8_t *head);
/*
* Checks names are not empty string and do not contain control

View File

@ -107,7 +107,7 @@ const char* nghttp2_strerror(int error_code)
return "Invalid stream state";
case NGHTTP2_ERR_DEFERRED_DATA_EXIST:
return "Another DATA frame has already been deferred";
case NGHTTP2_ERR_SYN_STREAM_NOT_ALLOWED:
case NGHTTP2_ERR_START_STREAM_NOT_ALLOWED:
return "SYN_STREAM is not allowed";
case NGHTTP2_ERR_GOAWAY_ALREADY_SENT:
return "GOAWAY has already been sent";

View File

@ -26,37 +26,22 @@
#include <string.h>
static const nghttp2_npn_proto proto_list[] = {
{ (const unsigned char*)"spdy/3", 6, NGHTTP2_PROTO_SPDY3 },
{ (const unsigned char*)"spdy/2", 6, NGHTTP2_PROTO_SPDY2 }
};
const nghttp2_npn_proto* nghttp2_npn_get_proto_list(size_t *len_ptr)
{
*len_ptr = sizeof(proto_list)/sizeof(nghttp2_npn_proto);
return proto_list;
}
int nghttp2_select_next_protocol(unsigned char **out, unsigned char *outlen,
const unsigned char *in, unsigned int inlen)
{
int http_selected = 0;
unsigned int i = 0;
for(; i < inlen; i += in[i]+1) {
unsigned int j;
for(j = 0; j < sizeof(proto_list)/sizeof(nghttp2_npn_proto); ++j) {
if(in[i] == proto_list[j].len &&
memcmp(&in[i+1], proto_list[j].proto, in[i]) == 0) {
*out = (unsigned char*)&in[i+1];
*outlen = in[i];
return proto_list[j].version;
}
if(in[i] == 17 && memcmp(&in[i+1], "HTTP-draft-04/2.0", in[i]) == 0) {
*out = (unsigned char*)&in[i+1];
*outlen = in[i];
return 1;
}
if(in[i] == 8 && memcmp(&in[i+1], "http/1.1", in[i]) == 0) {
http_selected = 1;
*out = (unsigned char*)&in[i+1];
*outlen = in[i];
/* Go through to the next iteration, because "spdy/X" may be
/* Go through to the next iteration, because "HTTP/2.0" may be
there */
}
}
@ -66,19 +51,3 @@ int nghttp2_select_next_protocol(unsigned char **out, unsigned char *outlen,
return -1;
}
}
uint16_t nghttp2_npn_get_version(const unsigned char *proto, size_t protolen)
{
if(proto == NULL) {
return 0;
} else {
if(protolen == 6) {
if(memcmp("spdy/2", proto, 6) == 0) {
return NGHTTP2_PROTO_SPDY2;
} else if(memcmp("spdy/3", proto, 6) == 0) {
return NGHTTP2_PROTO_SPDY3;
}
}
return 0;
}
}

View File

@ -31,18 +31,18 @@ void nghttp2_outbound_item_free(nghttp2_outbound_item *item)
if(item == NULL) {
return;
}
if(item->frame_cat == NGHTTP2_CTRL) {
nghttp2_frame_type frame_type;
if(item->frame_cat == NGHTTP2_CAT_CTRL) {
nghttp2_frame *frame;
frame_type = nghttp2_outbound_item_get_ctrl_frame_type(item);
frame = nghttp2_outbound_item_get_ctrl_frame(item);
switch(frame_type) {
case NGHTTP2_SYN_STREAM:
nghttp2_frame_syn_stream_free(&frame->syn_stream);
free(((nghttp2_syn_stream_aux_data*)item->aux_data)->data_prd);
switch(frame->hd.type) {
case NGHTTP2_HEADERS:
nghttp2_frame_headers_free(&frame->headers);
if(item->aux_data) {
free(((nghttp2_headers_aux_data*)item->aux_data)->data_prd);
}
break;
case NGHTTP2_SYN_REPLY:
nghttp2_frame_syn_reply_free(&frame->syn_reply);
case NGHTTP2_PRIORITY:
nghttp2_frame_priority_free(&frame->priority);
break;
case NGHTTP2_RST_STREAM:
nghttp2_frame_rst_stream_free(&frame->rst_stream);
@ -50,27 +50,17 @@ void nghttp2_outbound_item_free(nghttp2_outbound_item *item)
case NGHTTP2_SETTINGS:
nghttp2_frame_settings_free(&frame->settings);
break;
case NGHTTP2_NOOP:
/* We don't have any public API to add NOOP, so here is
unreachable. */
assert(0);
case NGHTTP2_PING:
nghttp2_frame_ping_free(&frame->ping);
break;
case NGHTTP2_GOAWAY:
nghttp2_frame_goaway_free(&frame->goaway);
break;
case NGHTTP2_HEADERS:
nghttp2_frame_headers_free(&frame->headers);
break;
case NGHTTP2_WINDOW_UPDATE:
nghttp2_frame_window_update_free(&frame->window_update);
break;
case NGHTTP2_CREDENTIAL:
nghttp2_frame_credential_free(&frame->credential);
break;
}
} else if(item->frame_cat == NGHTTP2_DATA) {
} else if(item->frame_cat == NGHTTP2_CAT_DATA) {
nghttp2_data *data_frame;
data_frame = nghttp2_outbound_item_get_data_frame(item);
nghttp2_frame_data_free(data_frame);

View File

@ -42,7 +42,7 @@
typedef struct {
nghttp2_data_provider *data_prd;
void *stream_user_data;
} nghttp2_syn_stream_aux_data;
} nghttp2_headers_aux_data;
typedef struct {
/* Type of |frame|. NGHTTP2_CTRL: nghttp2_frame*, NGHTTP2_DATA:
@ -74,7 +74,7 @@ void nghttp2_outbound_item_free(nghttp2_outbound_item *item);
/* Macros to cast nghttp2_outbound_item.frame to the proper type. */
#define nghttp2_outbound_item_get_ctrl_frame(ITEM) ((nghttp2_frame*)ITEM->frame)
#define nghttp2_outbound_item_get_ctrl_frame_type(ITEM) \
(((nghttp2_frame*)ITEM->frame)->ctrl.hd.type)
(((nghttp2_frame*)ITEM->frame)->hd.type)
#define nghttp2_outbound_item_get_data_frame(ITEM) ((nghttp2_data*)ITEM->frame)
#endif /* NGHTTP2_OUTBOUND_ITEM_H */

File diff suppressed because it is too large Load Diff

View File

@ -37,18 +37,6 @@
#include "nghttp2_stream.h"
#include "nghttp2_buffer.h"
#include "nghttp2_outbound_item.h"
#include "nghttp2_client_cert_vector.h"
/**
* @macro
* Lowest priority value in SPDY/2, which is 3.
*/
#define NGHTTP2_PRI_LOWEST_SPDY2 3
/**
* @macro
* Lowest priority value in SPDY/3, which is 7.
*/
#define NGHTTP2_PRI_LOWEST_SPDY3 7
/*
* Option flags.
@ -81,11 +69,7 @@ typedef struct {
#define NGHTTP2_INITIAL_NV_BUFFER_LENGTH 4096
#define NGHTTP2_INITIAL_WINDOW_SIZE 65536
/* Initial size of client certificate vector */
#define NGHTTP2_INITIAL_CLIENT_CERT_VECTOR_LENGTH 8
/* Maxmum size of client certificate vector */
#define NGHTTP2_MAX_CLIENT_CERT_VECTOR_LENGTH 255
#define NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE 65536
/* Internal state when receiving incoming frame */
typedef enum {
@ -96,22 +80,16 @@ typedef enum {
/* Receiving frame payload, but the received bytes are discarded. */
NGHTTP2_RECV_PAYLOAD_IGN,
/* Receiving frame payload that comes before name/value header
block. Applied only for SYN_STREAM, SYN_REPLY and HEADERS. */
block. Applied only for HEADERS and PUSH_PROMISE. */
NGHTTP2_RECV_PAYLOAD_PRE_NV,
/* Receiving name/value header block in frame payload. Applied only
for SYN_STREAM, SYN_REPLY and HEADERS. */
for HEADERS and PUSH_PROMISE. */
NGHTTP2_RECV_PAYLOAD_NV
} nghttp2_inbound_state;
#define NGHTTP2_HEAD_LEN 8
/* Maximum unique ID in use for PING. If unique ID exeeds this number,
it wraps to 1 (client) or 2 (server) */
#define NGHTTP2_MAX_UNIQUE_ID ((1u << 31)-1)
typedef struct {
nghttp2_inbound_state state;
uint8_t headbuf[NGHTTP2_HEAD_LEN];
uint8_t headbuf[NGHTTP2_FRAME_HEAD_LENGTH];
/* How many bytes are filled in headbuf */
size_t headbufoff;
/* Payload for control frames. It is not used for DATA frames */
@ -170,9 +148,9 @@ struct nghttp2_session {
local_settings[NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS]. */
size_t num_incoming_streams;
/* Queue for outbound frames other than SYN_STREAM */
/* Queue for outbound frames other than stream-creating HEADERS */
nghttp2_pq /* <nghttp2_outbound_item*> */ ob_pq;
/* Queue for outbound SYN_STREAM frame */
/* Queue for outbound stream-creating HEADERS frame */
nghttp2_pq /* <nghttp2_outbound_item*> */ ob_ss_pq;
nghttp2_active_outbound_item aob;
@ -188,18 +166,26 @@ struct nghttp2_session {
nghttp2_zlib hd_deflater;
nghttp2_zlib hd_inflater;
/* The last unique ID sent to the peer. */
uint32_t last_ping_unique_id;
/* Flags indicating GOAWAY is sent and/or recieved. The flags are
composed by bitwise OR-ing nghttp2_goaway_flag. */
uint8_t goaway_flags;
/* This is the value in GOAWAY frame sent by remote endpoint. */
int32_t last_good_stream_id;
int32_t last_stream_id;
/* Flag to indicate whether this session enforces flow
control. Nonzero for flow control enabled. */
uint8_t flow_control;
/* Non-zero indicates connection-level flow control on remote side
is in effect. This will be disabled when WINDOW_UPDATE with
END_FLOW_CONTROL bit set is received. */
uint8_t remote_flow_control;
/* Non-zero indicates connection-level flow control on local side is
in effect. This will be disabled when WINDOW_UPDATE with
END_FLOW_CONTROL bit set is sent. */
uint8_t local_flow_control;
/* Current sender window size. This value is computed against the
current initial window size of remote endpoint. */
int32_t window_size;
/* Keep track of the number of bytes received without
WINDOW_UPDATE. */
int32_t recv_window_size;
/* Settings value received from the remote endpoint. We just use ID
as index. The index = 0 is unused. */
@ -212,9 +198,6 @@ struct nghttp2_session {
/* Maxmum size of buffer to use when receving control frame. */
uint32_t max_recv_ctrl_frame_buf;
/* Client certificate vector */
nghttp2_client_cert_vector cli_certvec;
nghttp2_session_callbacks callbacks;
void *user_data;
};
@ -256,8 +239,8 @@ int nghttp2_session_add_frame(nghttp2_session *session,
void *abs_frame, void *aux_data);
/*
* Adds RST_STREAM frame for the stream |stream_id| with status code
* |status_code|. This is a convenient function built on top of
* Adds RST_STREAM frame for the stream |stream_id| with the error
* code |error_code|. This is a convenient function built on top of
* nghttp2_session_add_frame() to add RST_STREAM easily.
*
* This function returns 0 if it succeeds, or one of the following
@ -267,12 +250,16 @@ int nghttp2_session_add_frame(nghttp2_session *session,
* Out of memory.
*/
int nghttp2_session_add_rst_stream(nghttp2_session *session,
int32_t stream_id, uint32_t status_code);
int32_t stream_id,
nghttp2_error_code error_code);
/*
* Adds PING frame with unique ID |unique_id|. This is a convenient
* functin built on top of nghttp2_session_add_frame() to add PING
* easily.
* Adds PING frame. This is a convenient functin built on top of
* nghttp2_session_add_frame() to add PING easily.
*
* If the |opaque_data| is not NULL, it must point to 8 bytes memory
* region of data. The data pointed by |opaque_data| is copied. It can
* be NULL. In this case, 8 bytes NULL is used.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
@ -280,14 +267,13 @@ int nghttp2_session_add_rst_stream(nghttp2_session *session,
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
int nghttp2_session_add_ping(nghttp2_session *session, uint32_t unique_id);
int nghttp2_session_add_ping(nghttp2_session *session, uint8_t flags,
uint8_t *opaque_data);
/*
* Adds GOAWAY frame with last-good-stream-ID |last_good_stream_id|
* and the status code |status_code|. The |status_code| is ignored if
* the protocol version is NGHTTP2_PROTO_SPDY2. This is a convenient
* function built on top of nghttp2_session_add_frame() to add GOAWAY
* easily.
* Adds GOAWAY frame with the last-stream-ID |last_stream_id| and the
* error code |error_code|. This is a convenient function built on top
* of nghttp2_session_add_frame() to add GOAWAY easily.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
@ -296,12 +282,13 @@ int nghttp2_session_add_ping(nghttp2_session *session, uint32_t unique_id);
* Out of memory.
*/
int nghttp2_session_add_goaway(nghttp2_session *session,
int32_t last_good_stream_id,
uint32_t status_code);
int32_t last_stream_id,
nghttp2_error_code error_code,
uint8_t *opaque_data, size_t opaque_data_len);
/*
* Adds WINDOW_UPDATE frame with stream ID |stream_id| and
* delta-window-size |delta_window_size|. This is a convenient
* window-size-increment |window_size_increment|. This is a convenient
* function built on top of nghttp2_session_add_frame() to add
* WINDOW_UPDATE easily.
*
@ -311,34 +298,32 @@ int nghttp2_session_add_goaway(nghttp2_session *session,
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
int nghttp2_session_add_window_update(nghttp2_session *session,
int nghttp2_session_add_window_update(nghttp2_session *session, uint8_t flags,
int32_t stream_id,
int32_t delta_window_size);
int32_t window_size_increment);
/*
* Creates new stream in |session| with stream ID |stream_id|,
* priority |pri| and flags |flags|. NGHTTP2_CTRL_FLAG_UNIDIRECTIONAL
* flag is set in |flags|, this stream is
* unidirectional. NGHTTP2_CTRL_FLAG_FIN flag is set in |flags|, the
* sender of SYN_STREAM will not send any further data in this
* stream. Since this function is called when SYN_STREAM is sent or
* received, these flags are taken from SYN_STREAM. The state of
* stream is set to |initial_state|. |stream_user_data| is a pointer
* to the arbitrary user supplied data to be associated to this
* stream.
* priority |pri| and flags |flags|. NGHTTP2_FLAG_END_STREAM flag is
* set in |flags|, the sender of HEADERS will not send any further
* data in this stream. Since this function is called when initial
* HEADERS is sent or received, these flags are taken from it. The
* state of stream is set to |initial_state|. The |stream_user_data|
* is a pointer to the arbitrary user supplied data to be associated
* to this stream.
*
* This function returns a pointer to created new stream object, or
* NULL.
*/
nghttp2_stream* nghttp2_session_open_stream(nghttp2_session *session,
int32_t stream_id,
uint8_t flags, uint8_t pri,
uint8_t flags, int32_t pri,
nghttp2_stream_state initial_state,
void *stream_user_data);
/*
* Closes stream whose stream ID is |stream_id|. The reason of closure
* is indicated by |status_code|. When closing the stream,
* is indicated by the |error_code|. When closing the stream,
* on_stream_close_callback will be called.
*
* This function returns 0 if it succeeds, or one the following
@ -348,19 +333,11 @@ nghttp2_stream* nghttp2_session_open_stream(nghttp2_session *session,
* The specified stream does not exist.
*/
int nghttp2_session_close_stream(nghttp2_session *session, int32_t stream_id,
nghttp2_status_code status_code);
/*
* Closes all pushed streams which associate them to stream
* |stream_id| with the status code |status_code|.
*/
void nghttp2_session_close_pushed_streams(nghttp2_session *session,
int32_t stream_id,
nghttp2_status_code status_code);
nghttp2_error_code error_code);
/*
* If further receptions and transmissions over the stream |stream_id|
* are disallowed, close the stream with status code |status_code|.
* are disallowed, close the stream with error code NGHTTP2_NO_ERROR.
*
* This function returns 0 if it
* succeeds, or one of the following negative error codes:
@ -371,24 +348,18 @@ void nghttp2_session_close_pushed_streams(nghttp2_session *session,
int nghttp2_session_close_stream_if_shut_rdwr(nghttp2_session *session,
nghttp2_stream *stream);
/*
* Called when SYN_STREAM is received, assuming |frame.syn_stream| is
* properly initialized. This function does first validate received
* frame and then open stream and call callback functions. This
* function does not return error if frame is not valid.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
int nghttp2_session_on_syn_stream_received(nghttp2_session *session,
nghttp2_frame *frame);
int nghttp2_session_on_syn_reply_received(nghttp2_session *session,
nghttp2_frame *frame,
nghttp2_stream *stream);
/*
* Called when SYN_REPLY is received, assuming |frame.syn_reply| is
* properly initialized.
* Called when HEADERS is received, assuming |frame| is properly
* initialized. This function does first validate received frame and
* then open stream and call callback functions.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
@ -396,13 +367,13 @@ int nghttp2_session_on_syn_stream_received(nghttp2_session *session,
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
int nghttp2_session_on_syn_reply_received(nghttp2_session *session,
nghttp2_frame *frame);
int nghttp2_session_on_headers_received(nghttp2_session *session,
nghttp2_frame *frame,
nghttp2_stream *stream);
/*
* Called when RST_STREAM is received, assuming |frame.rst_stream| is
* properly initialized.
* Called when RST_STREAM is received, assuming |frame| is properly
* initialized.
*
* This function returns 0 and never fail.
*/
@ -410,8 +381,8 @@ int nghttp2_session_on_rst_stream_received(nghttp2_session *session,
nghttp2_frame *frame);
/*
* Called when SETTINGS is received, assuming |frame.settings| is
* properly initialized.
* Called when SETTINGS is received, assuming |frame| is properly
* initialized.
*
* This function returns 0 and never fail.
*/
@ -419,7 +390,7 @@ int nghttp2_session_on_settings_received(nghttp2_session *session,
nghttp2_frame *frame);
/*
* Called when PING is received, assuming |frame.ping| is properly
* Called when PING is received, assuming |frame| is properly
* initialized.
*
* This function returns 0 if it succeeds, or one of the following
@ -432,7 +403,7 @@ int nghttp2_session_on_ping_received(nghttp2_session *session,
nghttp2_frame *frame);
/*
* Called when GOAWAY is received, assuming |frame.goaway| is properly
* Called when GOAWAY is received, assuming |frame| is properly
* initialized.
*
* This function returns 0 and never fail.
@ -441,21 +412,8 @@ int nghttp2_session_on_goaway_received(nghttp2_session *session,
nghttp2_frame *frame);
/*
* Called when HEADERS is recieved, assuming |frame.headers| is
* properly initialized.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
int nghttp2_session_on_headers_received(nghttp2_session *session,
nghttp2_frame *frame);
/*
* Called when WINDOW_UPDATE is recieved, assuming
* |frame.window_update| is properly initialized.
* Called when WINDOW_UPDATE is recieved, assuming |frame| is properly
* initialized.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
@ -466,15 +424,6 @@ int nghttp2_session_on_headers_received(nghttp2_session *session,
int nghttp2_session_on_window_update_received(nghttp2_session *session,
nghttp2_frame *frame);
/*
* Called when CREDENTIAL is received, assuming |frame.credential| is
* properly initialized.
*
* Currently, this function always succeeds and returns 0.
*/
int nghttp2_session_on_credential_received(nghttp2_session *session,
nghttp2_frame *frame);
/*
* Called when DATA is received.
*
@ -485,7 +434,7 @@ int nghttp2_session_on_credential_received(nghttp2_session *session,
* Out of memory.
*/
int nghttp2_session_on_data_received(nghttp2_session *session,
uint8_t flags, int32_t length,
uint16_t length, uint8_t flags,
int32_t stream_id);
/*
@ -520,11 +469,6 @@ ssize_t nghttp2_session_pack_data(nghttp2_session *session,
size_t datamax,
nghttp2_data *frame);
/*
* Returns next unique ID which can be used with PING.
*/
uint32_t nghttp2_session_get_next_unique_id(nghttp2_session *session);
/*
* Returns top of outbound frame queue. This function returns NULL if
* queue is empty.
@ -561,21 +505,4 @@ void nghttp2_session_update_local_settings(nghttp2_session *session,
nghttp2_settings_entry *iv,
size_t niv);
/*
* Returns the index in the client certificate vector for the
* |syn_stream|. The origin is computed from |syn_stream->nv|. If no
* client certificate is required, return 0. If CREDENTIAL frame needs
* to be sent before the |syn_stream|, this function returns
* :macro:`NGHTTP2_ERR_CREDENTIAL_PENDING`. In this case, CREDENTIAL
* frame has been already queued. This function returns one of the
* following negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory.
* NGHTTP2_ERR_CREDENTIAL_PENDING
* The CREDENTIAL frame must be sent before the |syn_stream|.
*/
int nghttp2_session_prep_credential(nghttp2_session *session,
nghttp2_syn_stream *syn_stream);
#endif /* NGHTTP2_SESSION_H */

View File

@ -27,8 +27,10 @@
#include <assert.h>
void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
uint8_t flags, uint8_t pri,
uint8_t flags, int32_t pri,
nghttp2_stream_state initial_state,
uint8_t remote_flow_control,
uint8_t local_flow_control,
int32_t initial_window_size,
void *stream_user_data)
{
@ -44,6 +46,8 @@ void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
stream->stream_user_data = stream_user_data;
stream->deferred_data = NULL;
stream->deferred_flags = NGHTTP2_DEFERRED_NONE;
stream->remote_flow_control = remote_flow_control;
stream->local_flow_control = local_flow_control;
stream->window_size = initial_window_size;
stream->recv_window_size = 0;
}

View File

@ -84,8 +84,8 @@ typedef struct {
nghttp2_stream_state state;
/* Use same value in SYN_STREAM frame */
uint8_t flags;
/* Use same scheme in SYN_STREAM frame */
uint8_t pri;
/* Use same value in SYN_STREAM frame */
int32_t pri;
/* Bitwise OR of zero or more nghttp2_shut_flag values */
uint8_t shut_flags;
/* The array of server-pushed stream IDs which associate them to
@ -103,6 +103,18 @@ typedef struct {
/* The flags for defered DATA. Bitwise OR of zero or more
nghttp2_deferred_flag values */
uint8_t deferred_flags;
/* Flag to indicate whether the remote side has flow control
enabled. If it is enabled, we have to enforces flow control to
send data to the other side. This could be disabled when
receiving SETTINGS with flow control options off or receiving
WINDOW_UPDATE with END_FLOW_CONTROL bit set. */
uint8_t remote_flow_control;
/* Flag to indicate whether the local side has flow control
enabled. If it is enabled, the received data are subject to the
flow control. This could be disabled by sending SETTINGS with
flow control options off or sending WINDOW_UPDATE with
END_FLOW_CONTROL bit set. */
uint8_t local_flow_control;
/* Current sender window size. This value is computed against the
current initial window size of remote endpoint. */
int32_t window_size;
@ -112,8 +124,10 @@ typedef struct {
} nghttp2_stream;
void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
uint8_t flags, uint8_t pri,
uint8_t flags, int32_t pri,
nghttp2_stream_state initial_state,
uint8_t remote_flow_control,
uint8_t local_flow_control,
int32_t initial_window_size,
void *stream_user_data);

View File

@ -30,11 +30,11 @@
#include "nghttp2_frame.h"
#include "nghttp2_helper.h"
static int nghttp2_submit_syn_stream_shared
static int nghttp2_submit_headers_shared
(nghttp2_session *session,
uint8_t flags,
int32_t assoc_stream_id,
uint8_t pri,
int32_t stream_id,
int32_t pri,
const char **nv,
const nghttp2_data_provider *data_prd,
void *stream_user_data)
@ -44,13 +44,10 @@ static int nghttp2_submit_syn_stream_shared
char **nv_copy;
uint8_t flags_copy;
nghttp2_data_provider *data_prd_copy = NULL;
nghttp2_syn_stream_aux_data *aux_data;
if(pri > nghttp2_session_get_pri_lowest(session)) {
nghttp2_headers_aux_data *aux_data = NULL;
if(pri < 0) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
if(assoc_stream_id != 0 && session->server == 0) {
assoc_stream_id = 0;
}
if(!nghttp2_frame_nv_check_null(nv)) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
@ -61,14 +58,15 @@ static int nghttp2_submit_syn_stream_shared
}
*data_prd_copy = *data_prd;
}
aux_data = malloc(sizeof(nghttp2_syn_stream_aux_data));
if(aux_data == NULL) {
free(data_prd_copy);
return NGHTTP2_ERR_NOMEM;
if(data_prd || stream_user_data) {
aux_data = malloc(sizeof(nghttp2_headers_aux_data));
if(aux_data == NULL) {
free(data_prd_copy);
return NGHTTP2_ERR_NOMEM;
}
aux_data->data_prd = data_prd_copy;
aux_data->stream_user_data = stream_user_data;
}
aux_data->data_prd = data_prd_copy;
aux_data->stream_user_data = stream_user_data;
frame = malloc(sizeof(nghttp2_frame));
if(frame == NULL) {
free(aux_data);
@ -82,20 +80,16 @@ static int nghttp2_submit_syn_stream_shared
free(data_prd_copy);
return NGHTTP2_ERR_NOMEM;
}
flags_copy = 0;
if(flags & NGHTTP2_CTRL_FLAG_FIN) {
flags_copy |= NGHTTP2_CTRL_FLAG_FIN;
}
if(flags & NGHTTP2_CTRL_FLAG_UNIDIRECTIONAL) {
flags_copy |= NGHTTP2_CTRL_FLAG_UNIDIRECTIONAL;
}
nghttp2_frame_syn_stream_init(&frame->syn_stream,
session->version, flags_copy,
0, assoc_stream_id, pri, nv_copy);
r = nghttp2_session_add_frame(session, NGHTTP2_CTRL, frame,
/* TODO Implement header continuation */
flags_copy = (flags & (NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_PRIORITY)) |
NGHTTP2_FLAG_END_HEADERS;
nghttp2_frame_headers_init(&frame->headers, flags_copy, stream_id, pri,
nv_copy);
r = nghttp2_session_add_frame(session, NGHTTP2_CAT_CTRL, frame,
aux_data);
if(r != 0) {
nghttp2_frame_syn_stream_free(&frame->syn_stream);
nghttp2_frame_headers_free(&frame->headers);
free(frame);
free(aux_data);
free(data_prd_copy);
@ -103,99 +97,35 @@ static int nghttp2_submit_syn_stream_shared
return r;
}
int nghttp2_submit_syn_stream(nghttp2_session *session, uint8_t flags,
int32_t assoc_stream_id, uint8_t pri,
const char **nv, void *stream_user_data)
{
return nghttp2_submit_syn_stream_shared(session, flags, assoc_stream_id,
pri, nv, NULL, stream_user_data);
}
int nghttp2_submit_syn_reply(nghttp2_session *session, uint8_t flags,
int32_t stream_id, const char **nv)
{
int r;
nghttp2_frame *frame;
char **nv_copy;
uint8_t flags_copy;
if(!nghttp2_frame_nv_check_null(nv)) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
frame = malloc(sizeof(nghttp2_frame));
if(frame == NULL) {
return NGHTTP2_ERR_NOMEM;
}
nv_copy = nghttp2_frame_nv_norm_copy(nv);
if(nv_copy == NULL) {
free(frame);
return NGHTTP2_ERR_NOMEM;
}
flags_copy = 0;
if(flags & NGHTTP2_CTRL_FLAG_FIN) {
flags_copy |= NGHTTP2_CTRL_FLAG_FIN;
}
nghttp2_frame_syn_reply_init(&frame->syn_reply, session->version, flags_copy,
stream_id, nv_copy);
r = nghttp2_session_add_frame(session, NGHTTP2_CTRL, frame, NULL);
if(r != 0) {
nghttp2_frame_syn_reply_free(&frame->syn_reply);
free(frame);
}
return r;
}
int nghttp2_submit_headers(nghttp2_session *session, uint8_t flags,
int32_t stream_id, const char **nv)
int32_t stream_id, int32_t pri,
const char **nv, void *stream_user_data)
{
int r;
nghttp2_frame *frame;
char **nv_copy;
uint8_t flags_copy;
if(!nghttp2_frame_nv_check_null(nv)) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
frame = malloc(sizeof(nghttp2_frame));
if(frame == NULL) {
return NGHTTP2_ERR_NOMEM;
}
nv_copy = nghttp2_frame_nv_norm_copy(nv);
if(nv_copy == NULL) {
free(frame);
return NGHTTP2_ERR_NOMEM;
}
flags_copy = 0;
if(flags & NGHTTP2_CTRL_FLAG_FIN) {
flags_copy |= NGHTTP2_CTRL_FLAG_FIN;
}
nghttp2_frame_headers_init(&frame->headers, session->version, flags_copy,
stream_id, nv_copy);
r = nghttp2_session_add_frame(session, NGHTTP2_CTRL, frame, NULL);
if(r != 0) {
nghttp2_frame_headers_free(&frame->headers);
free(frame);
}
return r;
return nghttp2_submit_headers_shared(session, flags, stream_id,
pri, nv, NULL, stream_user_data);
}
int nghttp2_submit_ping(nghttp2_session *session)
int nghttp2_submit_ping(nghttp2_session *session, uint8_t *opaque_data)
{
return nghttp2_session_add_ping(session,
nghttp2_session_get_next_unique_id(session));
return nghttp2_session_add_ping(session, NGHTTP2_FLAG_NONE, opaque_data);
}
int nghttp2_submit_rst_stream(nghttp2_session *session, int32_t stream_id,
uint32_t status_code)
nghttp2_error_code error_code)
{
return nghttp2_session_add_rst_stream(session, stream_id, status_code);
return nghttp2_session_add_rst_stream(session, stream_id, error_code);
}
int nghttp2_submit_goaway(nghttp2_session *session, uint32_t status_code)
int nghttp2_submit_goaway(nghttp2_session *session,
nghttp2_error_code error_code,
uint8_t *opaque_data, size_t opaque_data_len)
{
return nghttp2_session_add_goaway(session, session->last_recv_stream_id,
status_code);
error_code, opaque_data, opaque_data_len);
}
int nghttp2_submit_settings(nghttp2_session *session, uint8_t flags,
int nghttp2_submit_settings(nghttp2_session *session,
const nghttp2_settings_entry *iv, size_t niv)
{
nghttp2_frame *frame;
@ -222,9 +152,8 @@ int nghttp2_submit_settings(nghttp2_session *session, uint8_t flags,
return NGHTTP2_ERR_NOMEM;
}
nghttp2_frame_iv_sort(iv_copy, niv);
nghttp2_frame_settings_init(&frame->settings, session->version,
flags, iv_copy, niv);
r = nghttp2_session_add_frame(session, NGHTTP2_CTRL, frame, NULL);
nghttp2_frame_settings_init(&frame->settings, iv_copy, niv);
r = nghttp2_session_add_frame(session, NGHTTP2_CAT_CTRL, frame, NULL);
if(r == 0) {
nghttp2_session_update_local_settings(session, iv_copy, niv);
} else {
@ -234,85 +163,61 @@ int nghttp2_submit_settings(nghttp2_session *session, uint8_t flags,
return r;
}
int nghttp2_submit_window_update(nghttp2_session *session, int32_t stream_id,
int32_t delta_window_size)
int nghttp2_submit_window_update(nghttp2_session *session, uint8_t flags,
int32_t stream_id,
int32_t window_size_increment)
{
nghttp2_stream *stream;
if(delta_window_size <= 0) {
if(window_size_increment <= 0) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
stream = nghttp2_session_get_stream(session, stream_id);
if(stream) {
stream->recv_window_size -= nghttp2_min(delta_window_size,
stream->recv_window_size);
return nghttp2_session_add_window_update(session, stream_id,
delta_window_size);
if(stream_id == 0) {
return nghttp2_session_add_window_update(session, flags, stream_id,
window_size_increment);
} else {
return NGHTTP2_ERR_STREAM_CLOSED;
stream = nghttp2_session_get_stream(session, stream_id);
if(stream) {
stream->recv_window_size -= nghttp2_min(window_size_increment,
stream->recv_window_size);
return nghttp2_session_add_window_update(session, flags, stream_id,
window_size_increment);
} else {
return NGHTTP2_ERR_STREAM_CLOSED;
}
}
}
int nghttp2_submit_request(nghttp2_session *session, uint8_t pri,
int nghttp2_submit_request(nghttp2_session *session, int32_t pri,
const char **nv,
const nghttp2_data_provider *data_prd,
void *stream_user_data)
{
int flags;
flags = 0;
uint8_t flags = NGHTTP2_FLAG_NONE;
if(data_prd == NULL || data_prd->read_callback == NULL) {
flags |= NGHTTP2_CTRL_FLAG_FIN;
flags |= NGHTTP2_FLAG_END_STREAM;
}
return nghttp2_submit_syn_stream_shared(session, flags, 0, pri, nv, data_prd,
stream_user_data);
if(pri != NGHTTP2_PRI_DEFAULT) {
flags |= NGHTTP2_FLAG_PRIORITY;
}
return nghttp2_submit_headers_shared(session, flags, -1, pri, nv,
data_prd, stream_user_data);
}
int nghttp2_submit_response(nghttp2_session *session,
int32_t stream_id, const char **nv,
const nghttp2_data_provider *data_prd)
{
int r;
nghttp2_frame *frame;
char **nv_copy;
uint8_t flags = 0;
nghttp2_data_provider *data_prd_copy = NULL;
if(!nghttp2_frame_nv_check_null(nv)) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
uint8_t flags = NGHTTP2_FLAG_NONE;
if(data_prd == NULL || data_prd->read_callback == NULL) {
flags |= NGHTTP2_FLAG_END_STREAM;
}
if(data_prd != NULL && data_prd->read_callback != NULL) {
data_prd_copy = malloc(sizeof(nghttp2_data_provider));
if(data_prd_copy == NULL) {
return NGHTTP2_ERR_NOMEM;
}
*data_prd_copy = *data_prd;
}
frame = malloc(sizeof(nghttp2_frame));
if(frame == NULL) {
free(data_prd_copy);
return NGHTTP2_ERR_NOMEM;
}
nv_copy = nghttp2_frame_nv_norm_copy(nv);
if(nv_copy == NULL) {
free(frame);
free(data_prd_copy);
return NGHTTP2_ERR_NOMEM;
}
if(data_prd_copy == NULL) {
flags |= NGHTTP2_CTRL_FLAG_FIN;
}
nghttp2_frame_syn_reply_init(&frame->syn_reply, session->version, flags,
stream_id, nv_copy);
r = nghttp2_session_add_frame(session, NGHTTP2_CTRL, frame,
data_prd_copy);
if(r != 0) {
nghttp2_frame_syn_reply_free(&frame->syn_reply);
free(frame);
free(data_prd_copy);
}
return r;
return nghttp2_submit_headers_shared(session, flags, stream_id,
NGHTTP2_PRI_DEFAULT, nv, data_prd,
NULL);
}
int nghttp2_submit_data(nghttp2_session *session, int32_t stream_id,
uint8_t flags,
int nghttp2_submit_data(nghttp2_session *session, uint8_t flags,
int32_t stream_id,
const nghttp2_data_provider *data_prd)
{
int r;
@ -322,11 +227,11 @@ int nghttp2_submit_data(nghttp2_session *session, int32_t stream_id,
if(data_frame == NULL) {
return NGHTTP2_ERR_NOMEM;
}
if(flags & NGHTTP2_DATA_FLAG_FIN) {
nflags |= NGHTTP2_DATA_FLAG_FIN;
if(flags & NGHTTP2_FLAG_END_STREAM) {
nflags |= NGHTTP2_FLAG_END_STREAM;
}
nghttp2_frame_data_init(data_frame, stream_id, nflags, data_prd);
r = nghttp2_session_add_frame(session, NGHTTP2_DATA, data_frame, NULL);
nghttp2_frame_data_init(data_frame, nflags, stream_id, data_prd);
r = nghttp2_session_add_frame(session, NGHTTP2_CAT_DATA, data_frame, NULL);
if(r != 0) {
nghttp2_frame_data_free(data_frame);
free(data_frame);

View File

@ -230,13 +230,8 @@ static const uint8_t* nghttp2_select_hd_dict(size_t *len_ptr, uint16_t version)
{
const uint8_t *hd_dict;
hd_dict = NULL;
if(version == NGHTTP2_PROTO_SPDY2) {
hd_dict = (const uint8_t*)spdy2_hd_dict;
*len_ptr = sizeof(spdy2_hd_dict);
} else if(version == NGHTTP2_PROTO_SPDY3) {
hd_dict = spdy3_hd_dict;
*len_ptr = sizeof(spdy3_hd_dict);
}
hd_dict = (const uint8_t*)spdy2_hd_dict;
*len_ptr = sizeof(spdy2_hd_dict);
return hd_dict;
}

View File

@ -24,35 +24,39 @@ SUBDIRS = testdata
if HAVE_CUNIT
check_PROGRAMS = main failmalloc
check_PROGRAMS = main
# failmalloc
OBJECTS = main.c nghttp2_pq_test.c nghttp2_map_test.c nghttp2_queue_test.c \
nghttp2_buffer_test.c nghttp2_zlib_test.c nghttp2_session_test.c \
nghttp2_frame_test.c nghttp2_stream_test.c nghttp2_npn_test.c \
nghttp2_client_cert_vector_test.c nghttp2_gzip_test.c \
nghttp2_test_helper.c
nghttp2_buffer_test.c nghttp2_zlib_test.c \
nghttp2_test_helper.c \
nghttp2_frame_test.c \
nghttp2_stream_test.c \
nghttp2_session_test.c \
nghttp2_npn_test.c \
nghttp2_gzip_test.c
HFILES = nghttp2_pq_test.h nghttp2_map_test.h nghttp2_queue_test.h \
nghttp2_buffer_test.h nghttp2_zlib_test.h nghttp2_session_test.h \
nghttp2_frame_test.h nghttp2_stream_test.h nghttp2_npn_test.h \
nghttp2_client_cert_vector_test.h nghttp2_gzip_test.h \
nghttp2_test_helper.h
nghttp2_gzip_test.h nghttp2_test_helper.h
main_SOURCES = $(HFILES) $(OBJECTS)
main_LDADD = ${top_builddir}/lib/libnghttp2.la
main_LDFLAGS = -static @CUNIT_LIBS@ @TESTS_LIBS@
failmalloc_SOURCES = failmalloc.c failmalloc_test.c failmalloc_test.h \
malloc_wrapper.c malloc_wrapper.h \
nghttp2_test_helper.c nghttp2_test_helper.h
failmalloc_LDADD = $(main_LDADD)
failmalloc_LDFLAGS = $(main_LDFLAGS)
# failmalloc_SOURCES = failmalloc.c failmalloc_test.c failmalloc_test.h \
# malloc_wrapper.c malloc_wrapper.h \
# nghttp2_test_helper.c nghttp2_test_helper.h
# failmalloc_LDADD = $(main_LDADD)
# failmalloc_LDFLAGS = $(main_LDFLAGS)
AM_CFLAGS = -Wall -I${top_srcdir}/lib -I${top_srcdir}/lib/includes -I${top_builddir}/lib/includes \
@CUNIT_CFLAGS@ @DEFS@
TESTS = main failmalloc
TESTS = main
# failmalloc
if ENABLE_SRC

View File

@ -35,7 +35,6 @@
#include "nghttp2_frame_test.h"
#include "nghttp2_stream_test.h"
#include "nghttp2_npn_test.h"
#include "nghttp2_client_cert_vector_test.h"
#include "nghttp2_gzip_test.h"
static int init_suite1(void)
@ -73,170 +72,133 @@ int main(int argc, char* argv[])
!CU_add_test(pSuite, "queue", test_nghttp2_queue) ||
!CU_add_test(pSuite, "buffer", test_nghttp2_buffer) ||
!CU_add_test(pSuite, "buffer_reader", test_nghttp2_buffer_reader) ||
!CU_add_test(pSuite, "zlib_spdy2", test_nghttp2_zlib_spdy2) ||
!CU_add_test(pSuite, "zlib_spdy3", test_nghttp2_zlib_spdy3) ||
!CU_add_test(pSuite, "zlib", test_nghttp2_zlib) ||
!CU_add_test(pSuite, "npn", test_nghttp2_npn) ||
!CU_add_test(pSuite, "npn_get_proto_list",
test_nghttp2_npn_get_proto_list) ||
!CU_add_test(pSuite, "session_recv", test_nghttp2_session_recv) ||
!CU_add_test(pSuite, "session_recv_invalid_stream_id",
test_nghttp2_session_recv_invalid_stream_id) ||
!CU_add_test(pSuite, "session_add_frame",
test_nghttp2_session_add_frame) ||
!CU_add_test(pSuite, "session_on_syn_stream_received",
test_nghttp2_session_on_syn_stream_received) ||
!CU_add_test(pSuite, "session_on_syn_stream_received_with_push",
test_nghttp2_session_on_syn_stream_received_with_push) ||
!CU_add_test(pSuite, "session_on_syn_reply_received",
test_nghttp2_session_on_syn_reply_received) ||
!CU_add_test(pSuite, "session_send_syn_stream",
test_nghttp2_session_send_syn_stream) ||
!CU_add_test(pSuite, "session_send_syn_reply",
test_nghttp2_session_send_syn_reply) ||
!CU_add_test(pSuite, "submit_response", test_nghttp2_submit_response) ||
!CU_add_test(pSuite, "submit_response_without_data",
test_nghttp2_submit_response_with_null_data_read_callback) ||
!CU_add_test(pSuite, "submit_request_with_data",
test_nghttp2_submit_request_with_data) ||
!CU_add_test(pSuite, "submit_request_without_data",
test_nghttp2_submit_request_with_null_data_read_callback) ||
!CU_add_test(pSuite, "submit_syn_stream",
test_nghttp2_submit_syn_stream) ||
!CU_add_test(pSuite, "submit_syn_reply", test_nghttp2_submit_syn_reply) ||
!CU_add_test(pSuite, "submit_headers", test_nghttp2_submit_headers) ||
!CU_add_test(pSuite, "submit_invalid_nv",
test_nghttp2_submit_invalid_nv) ||
!CU_add_test(pSuite, "session_reply_fail",
test_nghttp2_session_reply_fail) ||
!CU_add_test(pSuite, "session_on_headers_received",
test_nghttp2_session_on_headers_received) ||
!CU_add_test(pSuite, "session_on_window_update_received",
test_nghttp2_session_on_window_update_received) ||
!CU_add_test(pSuite, "session_on_ping_received",
test_nghttp2_session_on_ping_received) ||
!CU_add_test(pSuite, "session_on_goaway_received",
test_nghttp2_session_on_goaway_received) ||
!CU_add_test(pSuite, "session_on_data_received",
test_nghttp2_session_on_data_received) ||
!CU_add_test(pSuite, "session_on_rst_stream_received",
test_nghttp2_session_on_rst_received) ||
!CU_add_test(pSuite, "session_is_my_stream_id",
test_nghttp2_session_is_my_stream_id) ||
!CU_add_test(pSuite, "session_send_rst_stream",
test_nghttp2_session_send_rst_stream) ||
!CU_add_test(pSuite, "session_get_next_ob_item",
test_nghttp2_session_get_next_ob_item) ||
!CU_add_test(pSuite, "session_pop_next_ob_item",
test_nghttp2_session_pop_next_ob_item) ||
!CU_add_test(pSuite, "session_on_request_recv_callback",
test_nghttp2_session_on_request_recv_callback) ||
!CU_add_test(pSuite, "session_on_stream_close",
test_nghttp2_session_on_stream_close) ||
!CU_add_test(pSuite, "session_max_concurrent_streams",
test_nghttp2_session_max_concurrent_streams) ||
!CU_add_test(pSuite, "session_data_backoff_by_high_pri_frame",
test_nghttp2_session_data_backoff_by_high_pri_frame) ||
!CU_add_test(pSuite, "session_stop_data_with_rst_stream",
test_nghttp2_session_stop_data_with_rst_stream) ||
!CU_add_test(pSuite, "session_stream_close_on_syn_stream",
test_nghttp2_session_stream_close_on_syn_stream) ||
!CU_add_test(pSuite, "session_recv_invalid_frame",
test_nghttp2_session_recv_invalid_frame) ||
!CU_add_test(pSuite, "session_defer_data",
test_nghttp2_session_defer_data) ||
!CU_add_test(pSuite, "session_flow_control",
test_nghttp2_session_flow_control) ||
!CU_add_test(pSuite, "session_on_ctrl_not_send",
test_nghttp2_session_on_ctrl_not_send) ||
!CU_add_test(pSuite, "session_on_settings_received",
test_nghttp2_session_on_settings_received) ||
!CU_add_test(pSuite, "session_submit_settings",
test_nghttp2_submit_settings) ||
!CU_add_test(pSuite, "session_get_outbound_queue_size",
test_nghttp2_session_get_outbound_queue_size) ||
!CU_add_test(pSuite, "session_prep_credential",
test_nghttp2_session_prep_credential) ||
!CU_add_test(pSuite, "session_submit_syn_stream_with_credential",
test_nghttp2_submit_syn_stream_with_credential) ||
!CU_add_test(pSuite, "session_set_initial_client_cert_origin",
test_nghttp2_session_set_initial_client_cert_origin) ||
!CU_add_test(pSuite, "session_set_option",
test_nghttp2_session_set_option) ||
!CU_add_test(pSuite, "submit_window_update",
test_nghttp2_submit_window_update) ||
!CU_add_test(pSuite, "session_data_read_temporal_failure",
test_nghttp2_session_data_read_temporal_failure) ||
!CU_add_test(pSuite, "session_recv_eof",
test_nghttp2_session_recv_eof) ||
!CU_add_test(pSuite, "session_recv_data",
test_nghttp2_session_recv_data) ||
!CU_add_test(pSuite, "frame_unpack_nv_spdy2",
test_nghttp2_frame_unpack_nv_spdy2) ||
!CU_add_test(pSuite, "frame_unpack_nv_spdy3",
test_nghttp2_frame_unpack_nv_spdy3) ||
!CU_add_test(pSuite, "session_add_frame",
test_nghttp2_session_add_frame) ||
!CU_add_test(pSuite, "session_on_syn_stream_received",
test_nghttp2_session_on_syn_stream_received) ||
!CU_add_test(pSuite, "session_on_syn_reply_received",
test_nghttp2_session_on_syn_reply_received) ||
!CU_add_test(pSuite, "session_on_headers_received",
test_nghttp2_session_on_headers_received) ||
!CU_add_test(pSuite, "session_on_rst_stream_received",
test_nghttp2_session_on_rst_stream_received) ||
!CU_add_test(pSuite, "session_on_settings_received",
test_nghttp2_session_on_settings_received) ||
!CU_add_test(pSuite, "session_on_ping_received",
test_nghttp2_session_on_ping_received) ||
!CU_add_test(pSuite, "session_on_goaway_received",
test_nghttp2_session_on_goaway_received) ||
!CU_add_test(pSuite, "session_on_window_update_received",
test_nghttp2_session_on_window_update_received) ||
!CU_add_test(pSuite, "session_on_data_received",
test_nghttp2_session_on_data_received) ||
!CU_add_test(pSuite, "session_send_headers_start_stream",
test_nghttp2_session_send_headers_start_stream) ||
!CU_add_test(pSuite, "session_send_headers_reply",
test_nghttp2_session_send_headers_reply) ||
!CU_add_test(pSuite, "session_send_rst_stream",
test_nghttp2_session_send_rst_stream) ||
!CU_add_test(pSuite, "session_is_my_stream_id",
test_nghttp2_session_is_my_stream_id) ||
!CU_add_test(pSuite, "submit_response", test_nghttp2_submit_response) ||
!CU_add_test(pSuite, "submit_response_without_data",
test_nghttp2_submit_response_without_data) ||
!CU_add_test(pSuite, "submit_request_with_data",
test_nghttp2_submit_request_with_data) ||
!CU_add_test(pSuite, "submit_request_without_data",
test_nghttp2_submit_request_without_data) ||
!CU_add_test(pSuite, "submit_headers_start_stream",
test_nghttp2_submit_headers_start_stream) ||
!CU_add_test(pSuite, "submit_headers_reply",
test_nghttp2_submit_headers_reply) ||
!CU_add_test(pSuite, "submit_headers", test_nghttp2_submit_headers) ||
!CU_add_test(pSuite, "session_submit_settings",
test_nghttp2_submit_settings) ||
!CU_add_test(pSuite, "submit_window_update",
test_nghttp2_submit_window_update) ||
!CU_add_test(pSuite, "submit_invalid_nv",
test_nghttp2_submit_invalid_nv) ||
!CU_add_test(pSuite, "session_get_next_ob_item",
test_nghttp2_session_get_next_ob_item) ||
!CU_add_test(pSuite, "session_pop_next_ob_item",
test_nghttp2_session_pop_next_ob_item) ||
!CU_add_test(pSuite, "session_reply_fail",
test_nghttp2_session_reply_fail) ||
!CU_add_test(pSuite, "session_max_concurrent_streams",
test_nghttp2_session_max_concurrent_streams) ||
!CU_add_test(pSuite, "session_stream_close_on_headers_push",
test_nghttp2_session_stream_close_on_headers_push) ||
!CU_add_test(pSuite, "session_stop_data_with_rst_stream",
test_nghttp2_session_stop_data_with_rst_stream) ||
!CU_add_test(pSuite, "session_defer_data",
test_nghttp2_session_defer_data) ||
!CU_add_test(pSuite, "session_flow_control",
test_nghttp2_session_flow_control) ||
!CU_add_test(pSuite, "session_data_read_temporal_failure",
test_nghttp2_session_data_read_temporal_failure) ||
!CU_add_test(pSuite, "session_on_request_recv_callback",
test_nghttp2_session_on_request_recv_callback) ||
!CU_add_test(pSuite, "session_on_stream_close",
test_nghttp2_session_on_stream_close) ||
!CU_add_test(pSuite, "session_on_ctrl_not_send",
test_nghttp2_session_on_ctrl_not_send) ||
!CU_add_test(pSuite, "session_get_outbound_queue_size",
test_nghttp2_session_get_outbound_queue_size) ||
!CU_add_test(pSuite, "session_set_option",
test_nghttp2_session_set_option) ||
!CU_add_test(pSuite, "session_data_backoff_by_high_pri_frame",
test_nghttp2_session_data_backoff_by_high_pri_frame) ||
!CU_add_test(pSuite, "frame_unpack_nv",
test_nghttp2_frame_unpack_nv) ||
!CU_add_test(pSuite, "frame_unpack_nv_check_name",
test_nghttp2_frame_unpack_nv_check_name) ||
!CU_add_test(pSuite, "frame_unpack_nv_last_empty_value",
test_nghttp2_frame_unpack_nv_last_empty_value) ||
!CU_add_test(pSuite, "frame_pack_nv_duplicate_keys",
test_nghttp2_frame_pack_nv_duplicate_keys) ||
!CU_add_test(pSuite, "frame_count_nv_space",
test_nghttp2_frame_count_nv_space) ||
!CU_add_test(pSuite, "frame_pack_nv_empty_value",
test_nghttp2_frame_pack_nv_empty_value) ||
!CU_add_test(pSuite, "frame_count_unpack_nv_space",
test_nghttp2_frame_count_unpack_nv_space) ||
!CU_add_test(pSuite, "frame_pack_ping", test_nghttp2_frame_pack_ping) ||
!CU_add_test(pSuite, "frame_pack_goaway_spdy2",
test_nghttp2_frame_pack_goaway_spdy2) ||
!CU_add_test(pSuite, "frame_pack_goaway_spdy3",
test_nghttp2_frame_pack_goaway_spdy3) ||
!CU_add_test(pSuite, "frame_pack_syn_stream_spdy2",
test_nghttp2_frame_pack_syn_stream_spdy2) ||
!CU_add_test(pSuite, "frame_pack_syn_stream_spdy3",
test_nghttp2_frame_pack_syn_stream_spdy3) ||
!CU_add_test(pSuite, "frame_pack_syn_stream_frame_too_large",
test_nghttp2_frame_pack_syn_stream_frame_too_large) ||
!CU_add_test(pSuite, "frame_pack_syn_reply_spdy2",
test_nghttp2_frame_pack_syn_reply_spdy2) ||
!CU_add_test(pSuite, "frame_pack_syn_reply_spdy3",
test_nghttp2_frame_pack_syn_reply_spdy3) ||
!CU_add_test(pSuite, "frame_pack_headers_spdy2",
test_nghttp2_frame_pack_headers_spdy2) ||
!CU_add_test(pSuite, "frame_pack_headers_spdy3",
test_nghttp2_frame_pack_headers_spdy3) ||
!CU_add_test(pSuite, "frame_pack_window_update",
test_nghttp2_frame_pack_window_update) ||
!CU_add_test(pSuite, "frame_pack_settings_spdy2",
test_nghttp2_frame_pack_settings_spdy2) ||
!CU_add_test(pSuite, "frame_pack_settings_spdy3",
test_nghttp2_frame_pack_settings_spdy3) ||
!CU_add_test(pSuite, "frame_pack_credential",
test_nghttp2_frame_pack_credential) ||
!CU_add_test(pSuite, "frame_nv_sort", test_nghttp2_frame_nv_sort) ||
!CU_add_test(pSuite, "frame_nv_downcase",
test_nghttp2_frame_nv_downcase) ||
!CU_add_test(pSuite, "frame_pack_nv_duplicate_keys",
test_nghttp2_frame_pack_nv_duplicate_keys) ||
!CU_add_test(pSuite, "frame_pack_nv_empty_value_spdy2",
test_nghttp2_frame_pack_nv_empty_value_spdy2) ||
!CU_add_test(pSuite, "frame_pack_nv_empty_value_spdy3",
test_nghttp2_frame_pack_nv_empty_value_spdy3) ||
!CU_add_test(pSuite, "frame_nv_2to3", test_nghttp2_frame_nv_2to3) ||
!CU_add_test(pSuite, "frame_nv_3to2", test_nghttp2_frame_nv_3to2) ||
!CU_add_test(pSuite, "frame_unpack_nv_check_name_spdy2",
test_nghttp2_frame_unpack_nv_check_name_spdy2) ||
!CU_add_test(pSuite, "frame_unpack_nv_check_name_spdy3",
test_nghttp2_frame_unpack_nv_check_name_spdy3) ||
!CU_add_test(pSuite, "frame_unpack_nv_last_empty_value_spdy2",
test_nghttp2_frame_unpack_nv_last_empty_value_spdy2) ||
!CU_add_test(pSuite, "frame_unpack_nv_last_empty_value_spdy3",
test_nghttp2_frame_unpack_nv_last_empty_value_spdy3) ||
!CU_add_test(pSuite, "frame_nv_set_origin",
test_nghttp2_frame_nv_set_origin) ||
!CU_add_test(pSuite, "frame_nv_check_null",
test_nghttp2_frame_nv_check_null) ||
!CU_add_test(pSuite, "stream_add_pushed_stream",
test_nghttp2_stream_add_pushed_stream) ||
!CU_add_test(pSuite, "client_cert_vector_find",
test_nghttp2_client_cert_vector_find) ||
!CU_add_test(pSuite, "client_cert_vector_resize",
test_nghttp2_client_cert_vector_resize) ||
!CU_add_test(pSuite, "client_cert_vector_get_origin",
test_nghttp2_client_cert_vector_get_origin) ||
!CU_add_test(pSuite, "gzip_inflate", test_nghttp2_gzip_inflate)) {
!CU_add_test(pSuite, "frame_pack_headers",
test_nghttp2_frame_pack_headers) ||
!CU_add_test(pSuite, "frame_pack_headers_frame_too_large",
test_nghttp2_frame_pack_headers_frame_too_large) ||
!CU_add_test(pSuite, "frame_pack_priority",
test_nghttp2_frame_pack_priority) ||
!CU_add_test(pSuite, "frame_pack_rst_stream",
test_nghttp2_frame_pack_rst_stream) ||
!CU_add_test(pSuite, "frame_pack_settings",
test_nghttp2_frame_pack_settings) ||
!CU_add_test(pSuite, "frame_pack_ping", test_nghttp2_frame_pack_ping) ||
!CU_add_test(pSuite, "frame_pack_goaway",
test_nghttp2_frame_pack_goaway) ||
!CU_add_test(pSuite, "frame_pack_window_update",
test_nghttp2_frame_pack_window_update) ||
/* !CU_add_test(pSuite, "stream_add_pushed_stream", */
/* test_nghttp2_stream_add_pushed_stream) || */
!CU_add_test(pSuite, "gzip_inflate", test_nghttp2_gzip_inflate)
) {
CU_cleanup_registry();
return CU_get_error();
}

View File

@ -1,124 +0,0 @@
/*
* nghttp2 - HTTP/2.0 C Library
*
* Copyright (c) 2012 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "nghttp2_client_cert_vector_test.h"
#include <CUnit/CUnit.h>
#include "nghttp2_client_cert_vector.h"
static nghttp2_origin* create_origin(const char *scheme, const char *host,
uint16_t port)
{
nghttp2_origin *origin = malloc(sizeof(nghttp2_origin));
nghttp2_origin_set(origin, scheme, host, port);
return origin;
}
void test_nghttp2_client_cert_vector_find(void)
{
nghttp2_client_cert_vector certvec;
nghttp2_origin *origin;
const nghttp2_origin *origin_get;
size_t slot;
nghttp2_client_cert_vector_init(&certvec, 3);
origin = create_origin("https", "example.org", 443);
CU_ASSERT(0 == nghttp2_client_cert_vector_find(&certvec, origin));
CU_ASSERT(1 == nghttp2_client_cert_vector_put(&certvec, origin));
slot = nghttp2_client_cert_vector_find(&certvec, origin);
CU_ASSERT(1 == slot);
origin_get = nghttp2_client_cert_vector_get_origin(&certvec, slot);
CU_ASSERT(strcmp(origin->scheme, origin_get->scheme) == 0);
CU_ASSERT(strcmp(origin->host, origin_get->host) == 0);
CU_ASSERT(origin->port == origin_get->port);
origin = create_origin("https", "example.org", 8443);
CU_ASSERT(0 == nghttp2_client_cert_vector_find(&certvec, origin));
CU_ASSERT(2 == nghttp2_client_cert_vector_put(&certvec, origin));
slot = nghttp2_client_cert_vector_find(&certvec, origin);
CU_ASSERT(2 == slot);
origin = create_origin("https", "example.com", 443);
CU_ASSERT(0 == nghttp2_client_cert_vector_find(&certvec, origin));
CU_ASSERT(3 == nghttp2_client_cert_vector_put(&certvec, origin));
slot = nghttp2_client_cert_vector_find(&certvec, origin);
CU_ASSERT(3 == slot);
origin = create_origin("https", "example.com", 8443);
CU_ASSERT(0 == nghttp2_client_cert_vector_find(&certvec, origin));
CU_ASSERT(1 == nghttp2_client_cert_vector_put(&certvec, origin));
slot = nghttp2_client_cert_vector_find(&certvec, origin);
CU_ASSERT(1 == slot);
origin = create_origin("https", "example.org", 443);
CU_ASSERT(0 == nghttp2_client_cert_vector_find(&certvec, origin));
free(origin);
nghttp2_client_cert_vector_free(&certvec);
}
void test_nghttp2_client_cert_vector_resize(void)
{
nghttp2_client_cert_vector certvec;
nghttp2_origin *origin;
size_t i;
nghttp2_client_cert_vector_init(&certvec, 3);
origin = create_origin("https", "example.org", 443);
nghttp2_client_cert_vector_put(&certvec, origin);
origin = create_origin("https", "example.com", 443);
nghttp2_client_cert_vector_put(&certvec, origin);
CU_ASSERT(0 == nghttp2_client_cert_vector_resize(&certvec, 1));
CU_ASSERT(NULL != nghttp2_client_cert_vector_get_origin(&certvec, 1));
CU_ASSERT(1 == certvec.last_slot);
CU_ASSERT(0 == nghttp2_client_cert_vector_resize(&certvec, 8));
CU_ASSERT(NULL != nghttp2_client_cert_vector_get_origin(&certvec, 1));
CU_ASSERT(1 == certvec.last_slot);
for(i = 2; i <= 8; ++i) {
CU_ASSERT(NULL == nghttp2_client_cert_vector_get_origin(&certvec, i));
}
nghttp2_client_cert_vector_free(&certvec);
}
void test_nghttp2_client_cert_vector_get_origin(void)
{
nghttp2_client_cert_vector certvec;
nghttp2_origin *origin;
nghttp2_client_cert_vector_init(&certvec, 3);
origin = create_origin("https", "example.org", 443);
CU_ASSERT(1 == nghttp2_client_cert_vector_put(&certvec, origin));
CU_ASSERT(NULL == nghttp2_client_cert_vector_get_origin(&certvec, 0));
CU_ASSERT(NULL != nghttp2_client_cert_vector_get_origin(&certvec, 1));
CU_ASSERT(NULL == nghttp2_client_cert_vector_get_origin(&certvec, 2));
CU_ASSERT(NULL == nghttp2_client_cert_vector_get_origin(&certvec, 3));
CU_ASSERT(NULL == nghttp2_client_cert_vector_get_origin(&certvec, 4));
nghttp2_client_cert_vector_free(&certvec);
}

View File

@ -1,32 +0,0 @@
/*
* nghttp2 - HTTP/2.0 C Library
*
* Copyright (c) 2012 Tatsuhiro Tsujikawa
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef NGHTTP2_CLIENT_CERT_VECTOR_TEST_H
#define NGHTTP2_CLIENT_CERT_VECTOR_TEST_H
void test_nghttp2_client_cert_vector_find(void);
void test_nghttp2_client_cert_vector_resize(void);
void test_nghttp2_client_cert_vector_get_origin(void);
#endif /* NGHTTP2_CLIENT_CERT_VECTOR_TEST_H */

File diff suppressed because it is too large Load Diff

View File

@ -25,36 +25,23 @@
#ifndef NGHTTP2_FRAME_TEST_H
#define NGHTTP2_FRAME_TEST_H
void test_nghttp2_frame_unpack_nv_spdy2(void);
void test_nghttp2_frame_unpack_nv_spdy3(void);
void test_nghttp2_frame_unpack_nv(void);
void test_nghttp2_frame_unpack_nv_check_name(void);
void test_nghttp2_frame_unpack_nv_last_empty_value(void);
void test_nghttp2_frame_pack_nv_duplicate_keys(void);
void test_nghttp2_frame_pack_nv_empty_value_spdy2(void);
void test_nghttp2_frame_pack_nv_empty_value_spdy3(void);
void test_nghttp2_frame_count_nv_space(void);
void test_nghttp2_frame_pack_nv_empty_value(void);
void test_nghttp2_frame_count_unpack_nv_space(void);
void test_nghttp2_frame_pack_ping(void);
void test_nghttp2_frame_pack_goaway_spdy2(void);
void test_nghttp2_frame_pack_goaway_spdy3(void);
void test_nghttp2_frame_pack_syn_stream_spdy2(void);
void test_nghttp2_frame_pack_syn_stream_spdy3(void);
void test_nghttp2_frame_pack_syn_stream_frame_too_large(void);
void test_nghttp2_frame_pack_syn_reply_spdy2(void);
void test_nghttp2_frame_pack_syn_reply_spdy3(void);
void test_nghttp2_frame_pack_headers_spdy2(void);
void test_nghttp2_frame_pack_headers_spdy3(void);
void test_nghttp2_frame_pack_window_update(void);
void test_nghttp2_frame_pack_settings_spdy2(void);
void test_nghttp2_frame_pack_settings_spdy3(void);
void test_nghttp2_frame_pack_credential(void);
void test_nghttp2_frame_nv_sort(void);
void test_nghttp2_frame_nv_downcase(void);
void test_nghttp2_frame_nv_2to3(void);
void test_nghttp2_frame_nv_3to2(void);
void test_nghttp2_frame_unpack_nv_check_name_spdy2(void);
void test_nghttp2_frame_unpack_nv_check_name_spdy3(void);
void test_nghttp2_frame_unpack_nv_last_empty_value_spdy2(void);
void test_nghttp2_frame_unpack_nv_last_empty_value_spdy3(void);
void test_nghttp2_frame_nv_set_origin(void);
void test_nghttp2_frame_nv_check_null(void);
void test_nghttp2_frame_pack_headers(void);
void test_nghttp2_frame_pack_headers_frame_too_large(void);
void test_nghttp2_frame_pack_priority(void);
void test_nghttp2_frame_pack_rst_stream(void);
void test_nghttp2_frame_pack_settings(void);
void test_nghttp2_frame_pack_ping(void);
void test_nghttp2_frame_pack_goaway(void);
void test_nghttp2_frame_pack_window_update(void);
#endif /* NGHTTP2_FRAME_TEST_H */

View File

@ -28,19 +28,19 @@
#include <nghttp2/nghttp2.h>
#include <string.h>
static void spdy2(void)
static void http2(void)
{
const unsigned char spdy[] = {
const unsigned char p[] = {
8, 'h', 't', 't', 'p', '/', '1', '.', '1',
6, 's', 'p', 'd', 'y', '/', '2',
17, 'H', 'T', 'T', 'P', '-', 'd', 'r', 'a', 'f', 't', '-', '0', '4', '/',
'2', '.', '0',
6, 's', 'p', 'd', 'y', '/', '3'
};
unsigned char outlen;
unsigned char* out;
CU_ASSERT(NGHTTP2_PROTO_SPDY2 ==
nghttp2_select_next_protocol(&out, &outlen, spdy, sizeof(spdy)));
CU_ASSERT(6 == outlen);
CU_ASSERT(memcmp("spdy/2", out, outlen) == 0);
CU_ASSERT(1 == nghttp2_select_next_protocol(&out, &outlen, p, sizeof(p)));
CU_ASSERT(17 == outlen);
CU_ASSERT(memcmp("HTTP-draft-04/2.0", out, outlen) == 0);
}
static void http11(void)
@ -75,21 +75,7 @@ static void no_overlap(void)
void test_nghttp2_npn(void)
{
spdy2();
http2();
http11();
no_overlap();
}
void test_nghttp2_npn_get_proto_list(void)
{
size_t len;
const nghttp2_npn_proto *list = nghttp2_npn_get_proto_list(&len);
CU_ASSERT_EQUAL(2, len);
CU_ASSERT_STRING_EQUAL("spdy/3", list[0].proto);
CU_ASSERT_EQUAL(6, list[0].len);
CU_ASSERT_EQUAL(NGHTTP2_PROTO_SPDY3, list[0].version);
CU_ASSERT_STRING_EQUAL("spdy/2", list[1].proto);
CU_ASSERT_EQUAL(6, list[1].len);
CU_ASSERT_EQUAL(NGHTTP2_PROTO_SPDY2, list[1].version);
}

View File

@ -26,6 +26,5 @@
#define NGHTTP2_NPN_TEST_H
void test_nghttp2_npn(void);
void test_nghttp2_npn_get_proto_list(void);
#endif /* NGHTTP2_NPN_TEST_H */

File diff suppressed because it is too large Load Diff

View File

@ -27,51 +27,47 @@
void test_nghttp2_session_recv(void);
void test_nghttp2_session_recv_invalid_stream_id(void);
void test_nghttp2_session_add_frame(void);
void test_nghttp2_session_on_syn_stream_received(void);
void test_nghttp2_session_on_syn_stream_received_with_push(void);
void test_nghttp2_session_on_syn_reply_received(void);
void test_nghttp2_session_on_window_update_received(void);
void test_nghttp2_session_send_syn_stream(void);
void test_nghttp2_session_send_syn_reply(void);
void test_nghttp2_submit_response(void);
void test_nghttp2_submit_response_with_null_data_read_callback(void);
void test_nghttp2_submit_request_with_data(void);
void test_nghttp2_submit_request_with_null_data_read_callback(void);
void test_nghttp2_submit_syn_stream(void);
void test_nghttp2_submit_syn_reply(void);
void test_nghttp2_submit_headers(void);
void test_nghttp2_submit_invalid_nv(void);
void test_nghttp2_session_reply_fail(void);
void test_nghttp2_session_on_headers_received(void);
void test_nghttp2_session_on_ping_received(void);
void test_nghttp2_session_on_goaway_received(void);
void test_nghttp2_session_on_data_received(void);
void test_nghttp2_session_on_rst_received(void);
void test_nghttp2_session_is_my_stream_id(void);
void test_nghttp2_session_send_rst_stream(void);
void test_nghttp2_session_get_next_ob_item(void);
void test_nghttp2_session_pop_next_ob_item(void);
void test_nghttp2_session_on_request_recv_callback(void);
void test_nghttp2_session_on_stream_close(void);
void test_nghttp2_session_max_concurrent_streams(void);
void test_nghttp2_session_data_backoff_by_high_pri_frame(void);
void test_nghttp2_session_stop_data_with_rst_stream(void);
void test_nghttp2_session_stream_close_on_syn_stream(void);
void test_nghttp2_session_recv_invalid_frame(void);
void test_nghttp2_session_defer_data(void);
void test_nghttp2_session_flow_control(void);
void test_nghttp2_session_on_ctrl_not_send(void);
void test_nghttp2_session_on_settings_received(void);
void test_nghttp2_submit_settings(void);
void test_nghttp2_session_get_outbound_queue_size(void);
void test_nghttp2_session_prep_credential(void);
void test_nghttp2_submit_syn_stream_with_credential(void);
void test_nghttp2_session_set_initial_client_cert_origin(void);
void test_nghttp2_session_set_option(void);
void test_nghttp2_submit_window_update(void);
void test_nghttp2_session_data_read_temporal_failure(void);
void test_nghttp2_session_recv_eof(void);
void test_nghttp2_session_recv_data(void);
void test_nghttp2_session_add_frame(void);
void test_nghttp2_session_on_syn_stream_received(void);
void test_nghttp2_session_on_syn_reply_received(void);
void test_nghttp2_session_on_headers_received(void);
void test_nghttp2_session_on_rst_stream_received(void);
void test_nghttp2_session_on_settings_received(void);
void test_nghttp2_session_on_ping_received(void);
void test_nghttp2_session_on_goaway_received(void);
void test_nghttp2_session_on_window_update_received(void);
void test_nghttp2_session_on_data_received(void);
void test_nghttp2_session_send_headers_start_stream(void);
void test_nghttp2_session_send_headers_reply(void);
void test_nghttp2_session_send_rst_stream(void);
void test_nghttp2_session_is_my_stream_id(void);
void test_nghttp2_submit_response(void);
void test_nghttp2_submit_response_without_data(void);
void test_nghttp2_submit_request_with_data(void);
void test_nghttp2_submit_request_without_data(void);
void test_nghttp2_submit_headers_start_stream(void);
void test_nghttp2_submit_headers_reply(void);
void test_nghttp2_submit_headers(void);
void test_nghttp2_submit_settings(void);
void test_nghttp2_submit_window_update(void);
void test_nghttp2_submit_invalid_nv(void);
void test_nghttp2_session_get_next_ob_item(void);
void test_nghttp2_session_pop_next_ob_item(void);
void test_nghttp2_session_reply_fail(void);
void test_nghttp2_session_max_concurrent_streams(void);
void test_nghttp2_session_stream_close_on_headers_push(void);
void test_nghttp2_session_stop_data_with_rst_stream(void);
void test_nghttp2_session_defer_data(void);
void test_nghttp2_session_flow_control(void);
void test_nghttp2_session_data_read_temporal_failure(void);
void test_nghttp2_session_on_request_recv_callback(void);
void test_nghttp2_session_on_stream_close(void);
void test_nghttp2_session_on_ctrl_not_send(void);
void test_nghttp2_session_get_outbound_queue_size(void);
void test_nghttp2_session_set_option(void);
void test_nghttp2_session_data_backoff_by_high_pri_frame(void);
#endif /* NGHTTP2_SESSION_TEST_H */

View File

@ -32,8 +32,8 @@ void test_nghttp2_stream_add_pushed_stream(void)
{
nghttp2_stream stream;
int i, n;
nghttp2_stream_init(&stream, 1, NGHTTP2_CTRL_FLAG_NONE, 3, 65536,
NGHTTP2_STREAM_OPENING, NULL);
nghttp2_stream_init(&stream, 1, NGHTTP2_FLAG_NONE, 1 << 30,
NGHTTP2_STREAM_OPENING, 1, 1, 65536, NULL);
n = 26;
for(i = 2; i < n; i += 2) {
CU_ASSERT(0 == nghttp2_stream_add_pushed_stream(&stream, i));
@ -42,5 +42,6 @@ void test_nghttp2_stream_add_pushed_stream(void)
for(i = 2; i < n; i += 2) {
CU_ASSERT(i == stream.pushed_streams[i/2-1]);
}
CU_ASSERT(1 << 30 == stream.pri);
nghttp2_stream_free(&stream);
}

View File

@ -28,44 +28,30 @@
#include <CUnit/CUnit.h>
#include "nghttp2_session.h"
/* #include "nghttp2_session.h" */
ssize_t unpack_frame_with_nv_block(nghttp2_frame_type type,
uint16_t version,
nghttp2_frame *frame,
ssize_t unpack_frame_with_nv_block(nghttp2_frame *frame,
nghttp2_frame_type type,
nghttp2_zlib *inflater,
const uint8_t *in, size_t len)
{
nghttp2_buffer buffer;
ssize_t rv;
ssize_t pnvlen;
pnvlen = nghttp2_frame_nv_offset(type, version) - NGHTTP2_HEAD_LEN;
pnvlen = nghttp2_frame_nv_offset(in);
assert(pnvlen > 0);
nghttp2_buffer_init(&buffer, 4096);
rv = nghttp2_zlib_inflate_hd(inflater, &buffer,
&in[NGHTTP2_HEAD_LEN + pnvlen],
len - NGHTTP2_HEAD_LEN - pnvlen);
rv = nghttp2_zlib_inflate_hd(inflater, &buffer, &in[pnvlen], len - pnvlen);
if(rv < 0) {
return rv;
}
switch(type) {
case NGHTTP2_SYN_STREAM:
rv = nghttp2_frame_unpack_syn_stream(&frame->syn_stream,
&in[0], NGHTTP2_HEAD_LEN,
&in[NGHTTP2_HEAD_LEN], pnvlen,
&buffer);
break;
case NGHTTP2_SYN_REPLY:
rv = nghttp2_frame_unpack_syn_reply(&frame->syn_reply,
&in[0], NGHTTP2_HEAD_LEN,
&in[NGHTTP2_HEAD_LEN], pnvlen,
&buffer);
break;
case NGHTTP2_HEADERS:
rv = nghttp2_frame_unpack_headers(&frame->headers,
&in[0], NGHTTP2_HEAD_LEN,
&in[NGHTTP2_HEAD_LEN], pnvlen,
rv = nghttp2_frame_unpack_headers((nghttp2_headers*)frame,
&in[0], NGHTTP2_FRAME_HEAD_LENGTH,
&in[NGHTTP2_FRAME_HEAD_LENGTH],
pnvlen - NGHTTP2_FRAME_HEAD_LENGTH,
&buffer);
break;
default:
@ -75,3 +61,12 @@ ssize_t unpack_frame_with_nv_block(nghttp2_frame_type type,
nghttp2_buffer_free(&buffer);
return rv;
}
char* strcopy(const char* s)
{
size_t len = strlen(s);
char *dest = malloc(len+1);
memcpy(dest, s, len);
dest[len] = '\0';
return dest;
}

View File

@ -32,10 +32,11 @@
#include "nghttp2_frame.h"
#include "nghttp2_zlib.h"
ssize_t unpack_frame_with_nv_block(nghttp2_frame_type type,
uint16_t version,
nghttp2_frame *frame,
ssize_t unpack_frame_with_nv_block(nghttp2_frame *frame,
nghttp2_frame_type type,
nghttp2_zlib *inflater,
const uint8_t *in, size_t len);
char* strcopy(const char* s);
#endif /* NGHTTP2_TEST_HELPER_H */

View File

@ -30,7 +30,7 @@
#include "nghttp2_zlib.h"
static void test_nghttp2_zlib_with(uint16_t version)
void test_nghttp2_zlib(void)
{
nghttp2_zlib deflater, inflater;
const char msg[] =
@ -50,9 +50,8 @@ static void test_nghttp2_zlib_with(uint16_t version)
ssize_t deflatebuf_len;
nghttp2_buffer_init(&buf, 4096);
CU_ASSERT(0 == nghttp2_zlib_deflate_hd_init(&deflater, 1,
version));
CU_ASSERT(0 == nghttp2_zlib_inflate_hd_init(&inflater, version));
CU_ASSERT(0 == nghttp2_zlib_deflate_hd_init(&deflater, 1, 0));
CU_ASSERT(0 == nghttp2_zlib_inflate_hd_init(&inflater, 0));
deflatebuf_max = nghttp2_zlib_deflate_hd_bound(&deflater, sizeof(msg));
deflatebuf = malloc(deflatebuf_max);
@ -70,13 +69,3 @@ static void test_nghttp2_zlib_with(uint16_t version)
nghttp2_buffer_free(&buf);
}
void test_nghttp2_zlib_spdy2(void)
{
test_nghttp2_zlib_with(NGHTTP2_PROTO_SPDY2);
}
void test_nghttp2_zlib_spdy3(void)
{
test_nghttp2_zlib_with(NGHTTP2_PROTO_SPDY3);
}

View File

@ -25,7 +25,6 @@
#ifndef NGHTTP2_ZLIB_TEST_H
#define NGHTTP2_ZLIB_TEST_H
void test_nghttp2_zlib_spdy2(void);
void test_nghttp2_zlib_spdy3(void);
void test_nghttp2_zlib(void);
#endif /* NGHTTP2_ZLIB_TEST_H */