aboutsummaryrefslogtreecommitdiff
path: root/src/http
diff options
context:
space:
mode:
Diffstat (limited to 'src/http')
-rw-r--r--src/http/modules/ngx_http_fastcgi_module.c2
-rw-r--r--src/http/modules/ngx_http_mp4_module.c261
-rw-r--r--src/http/modules/ngx_http_proxy_module.c3
-rw-r--r--src/http/modules/ngx_http_scgi_module.c2
-rw-r--r--src/http/modules/ngx_http_ssl_module.c65
-rw-r--r--src/http/modules/ngx_http_uwsgi_module.c2
-rw-r--r--src/http/ngx_http.c5
-rw-r--r--src/http/ngx_http_core_module.c2
-rw-r--r--src/http/ngx_http_core_module.h4
-rw-r--r--src/http/ngx_http_request.c16
-rw-r--r--src/http/ngx_http_request_body.c2
-rw-r--r--src/http/ngx_http_upstream.c17
-rw-r--r--src/http/ngx_http_variables.c4
-rw-r--r--src/http/ngx_http_write_filter_module.c9
-rw-r--r--src/http/v2/ngx_http_v2.h3
15 files changed, 266 insertions, 131 deletions
diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c
index 69ac0f72c..4a8dc338e 100644
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -2021,7 +2021,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
/* rc == NGX_HTTP_PARSE_INVALID_HEADER */
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"upstream sent invalid header: \"%*s\\x%02xd...\"",
r->header_end - r->header_name_start,
r->header_name_start, *r->header_end);
diff --git a/src/http/modules/ngx_http_mp4_module.c b/src/http/modules/ngx_http_mp4_module.c
index 0e93fbd09..9c3f627fe 100644
--- a/src/http/modules/ngx_http_mp4_module.c
+++ b/src/http/modules/ngx_http_mp4_module.c
@@ -11,31 +11,33 @@
#define NGX_HTTP_MP4_TRAK_ATOM 0
#define NGX_HTTP_MP4_TKHD_ATOM 1
-#define NGX_HTTP_MP4_MDIA_ATOM 2
-#define NGX_HTTP_MP4_MDHD_ATOM 3
-#define NGX_HTTP_MP4_HDLR_ATOM 4
-#define NGX_HTTP_MP4_MINF_ATOM 5
-#define NGX_HTTP_MP4_VMHD_ATOM 6
-#define NGX_HTTP_MP4_SMHD_ATOM 7
-#define NGX_HTTP_MP4_DINF_ATOM 8
-#define NGX_HTTP_MP4_STBL_ATOM 9
-#define NGX_HTTP_MP4_STSD_ATOM 10
-#define NGX_HTTP_MP4_STTS_ATOM 11
-#define NGX_HTTP_MP4_STTS_DATA 12
-#define NGX_HTTP_MP4_STSS_ATOM 13
-#define NGX_HTTP_MP4_STSS_DATA 14
-#define NGX_HTTP_MP4_CTTS_ATOM 15
-#define NGX_HTTP_MP4_CTTS_DATA 16
-#define NGX_HTTP_MP4_STSC_ATOM 17
-#define NGX_HTTP_MP4_STSC_START 18
-#define NGX_HTTP_MP4_STSC_DATA 19
-#define NGX_HTTP_MP4_STSC_END 20
-#define NGX_HTTP_MP4_STSZ_ATOM 21
-#define NGX_HTTP_MP4_STSZ_DATA 22
-#define NGX_HTTP_MP4_STCO_ATOM 23
-#define NGX_HTTP_MP4_STCO_DATA 24
-#define NGX_HTTP_MP4_CO64_ATOM 25
-#define NGX_HTTP_MP4_CO64_DATA 26
+#define NGX_HTTP_MP4_EDTS_ATOM 2
+#define NGX_HTTP_MP4_ELST_ATOM 3
+#define NGX_HTTP_MP4_MDIA_ATOM 4
+#define NGX_HTTP_MP4_MDHD_ATOM 5
+#define NGX_HTTP_MP4_HDLR_ATOM 6
+#define NGX_HTTP_MP4_MINF_ATOM 7
+#define NGX_HTTP_MP4_VMHD_ATOM 8
+#define NGX_HTTP_MP4_SMHD_ATOM 9
+#define NGX_HTTP_MP4_DINF_ATOM 10
+#define NGX_HTTP_MP4_STBL_ATOM 11
+#define NGX_HTTP_MP4_STSD_ATOM 12
+#define NGX_HTTP_MP4_STTS_ATOM 13
+#define NGX_HTTP_MP4_STTS_DATA 14
+#define NGX_HTTP_MP4_STSS_ATOM 15
+#define NGX_HTTP_MP4_STSS_DATA 16
+#define NGX_HTTP_MP4_CTTS_ATOM 17
+#define NGX_HTTP_MP4_CTTS_DATA 18
+#define NGX_HTTP_MP4_STSC_ATOM 19
+#define NGX_HTTP_MP4_STSC_START 20
+#define NGX_HTTP_MP4_STSC_DATA 21
+#define NGX_HTTP_MP4_STSC_END 22
+#define NGX_HTTP_MP4_STSZ_ATOM 23
+#define NGX_HTTP_MP4_STSZ_DATA 24
+#define NGX_HTTP_MP4_STCO_ATOM 25
+#define NGX_HTTP_MP4_STCO_DATA 26
+#define NGX_HTTP_MP4_CO64_ATOM 27
+#define NGX_HTTP_MP4_CO64_DATA 28
#define NGX_HTTP_MP4_LAST_ATOM NGX_HTTP_MP4_CO64_DATA
@@ -43,6 +45,7 @@
typedef struct {
size_t buffer_size;
size_t max_buffer_size;
+ ngx_flag_t start_key_frame;
} ngx_http_mp4_conf_t;
@@ -54,6 +57,25 @@ typedef struct {
typedef struct {
+ u_char size[4];
+ u_char name[4];
+} ngx_mp4_edts_atom_t;
+
+
+typedef struct {
+ u_char size[4];
+ u_char name[4];
+ u_char version[1];
+ u_char flags[3];
+ u_char entries[4];
+ u_char duration[8];
+ u_char media_time[8];
+ u_char media_rate[2];
+ u_char reserved[2];
+} ngx_mp4_elst_atom_t;
+
+
+typedef struct {
uint32_t timescale;
uint32_t time_to_sample_entries;
uint32_t sample_to_chunk_entries;
@@ -70,6 +92,9 @@ typedef struct {
ngx_uint_t end_chunk_samples;
uint64_t start_chunk_samples_size;
uint64_t end_chunk_samples_size;
+ uint64_t duration;
+ uint64_t prefix;
+ uint64_t movie_duration;
off_t start_offset;
off_t end_offset;
@@ -85,6 +110,8 @@ typedef struct {
ngx_buf_t trak_atom_buf;
ngx_buf_t tkhd_atom_buf;
+ ngx_buf_t edts_atom_buf;
+ ngx_buf_t elst_atom_buf;
ngx_buf_t mdia_atom_buf;
ngx_buf_t mdhd_atom_buf;
ngx_buf_t hdlr_atom_buf;
@@ -111,6 +138,8 @@ typedef struct {
ngx_buf_t co64_atom_buf;
ngx_buf_t co64_data_buf;
+ ngx_mp4_edts_atom_t edts_atom;
+ ngx_mp4_elst_atom_t elst_atom;
ngx_mp4_stsc_entry_t stsc_start_chunk_entry;
ngx_mp4_stsc_entry_t stsc_end_chunk_entry;
} ngx_http_mp4_trak_t;
@@ -186,6 +215,14 @@ typedef struct {
((u_char *) (p))[6] = n3; \
((u_char *) (p))[7] = n4
+#define ngx_mp4_get_16value(p) \
+ ( ((uint16_t) ((u_char *) (p))[0] << 8) \
+ + ( ((u_char *) (p))[1]) )
+
+#define ngx_mp4_set_16value(p, n) \
+ ((u_char *) (p))[0] = (u_char) ((n) >> 8); \
+ ((u_char *) (p))[1] = (u_char) (n)
+
#define ngx_mp4_get_32value(p) \
( ((uint32_t) ((u_char *) (p))[0] << 24) \
+ ( ((u_char *) (p))[1] << 16) \
@@ -253,6 +290,8 @@ static void ngx_http_mp4_update_mdia_atom(ngx_http_mp4_file_t *mp4,
ngx_http_mp4_trak_t *trak);
static ngx_int_t ngx_http_mp4_read_mdhd_atom(ngx_http_mp4_file_t *mp4,
uint64_t atom_data_size);
+static void ngx_http_mp4_update_mdhd_atom(ngx_http_mp4_file_t *mp4,
+ ngx_http_mp4_trak_t *trak);
static ngx_int_t ngx_http_mp4_read_hdlr_atom(ngx_http_mp4_file_t *mp4,
uint64_t atom_data_size);
static ngx_int_t ngx_http_mp4_read_minf_atom(ngx_http_mp4_file_t *mp4,
@@ -267,6 +306,8 @@ static ngx_int_t ngx_http_mp4_read_smhd_atom(ngx_http_mp4_file_t *mp4,
uint64_t atom_data_size);
static ngx_int_t ngx_http_mp4_read_stbl_atom(ngx_http_mp4_file_t *mp4,
uint64_t atom_data_size);
+static void ngx_http_mp4_update_edts_atom(ngx_http_mp4_file_t *mp4,
+ ngx_http_mp4_trak_t *trak);
static void ngx_http_mp4_update_stbl_atom(ngx_http_mp4_file_t *mp4,
ngx_http_mp4_trak_t *trak);
static ngx_int_t ngx_http_mp4_read_stsd_atom(ngx_http_mp4_file_t *mp4,
@@ -277,6 +318,8 @@ static ngx_int_t ngx_http_mp4_update_stts_atom(ngx_http_mp4_file_t *mp4,
ngx_http_mp4_trak_t *trak);
static ngx_int_t ngx_http_mp4_crop_stts_data(ngx_http_mp4_file_t *mp4,
ngx_http_mp4_trak_t *trak, ngx_uint_t start);
+static uint32_t ngx_http_mp4_seek_key_frame(ngx_http_mp4_file_t *mp4,
+ ngx_http_mp4_trak_t *trak, uint32_t start_sample);
static ngx_int_t ngx_http_mp4_read_stss_atom(ngx_http_mp4_file_t *mp4,
uint64_t atom_data_size);
static ngx_int_t ngx_http_mp4_update_stss_atom(ngx_http_mp4_file_t *mp4,
@@ -340,6 +383,13 @@ static ngx_command_t ngx_http_mp4_commands[] = {
offsetof(ngx_http_mp4_conf_t, max_buffer_size),
NULL },
+ { ngx_string("mp4_start_key_frame"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+ ngx_conf_set_flag_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_mp4_conf_t, start_key_frame),
+ NULL },
+
ngx_null_command
};
@@ -822,10 +872,11 @@ ngx_http_mp4_process(ngx_http_mp4_file_t *mp4)
ngx_http_mp4_update_stbl_atom(mp4, &trak[i]);
ngx_http_mp4_update_minf_atom(mp4, &trak[i]);
- trak[i].size += trak[i].mdhd_size;
+ ngx_http_mp4_update_mdhd_atom(mp4, &trak[i]);
trak[i].size += trak[i].hdlr_size;
ngx_http_mp4_update_mdia_atom(mp4, &trak[i]);
trak[i].size += trak[i].tkhd_size;
+ ngx_http_mp4_update_edts_atom(mp4, &trak[i]);
ngx_http_mp4_update_trak_atom(mp4, &trak[i]);
mp4->moov_size += trak[i].size;
@@ -1587,6 +1638,7 @@ ngx_http_mp4_read_tkhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
trak = ngx_mp4_last_trak(mp4);
trak->tkhd_size = atom_size;
+ trak->movie_duration = duration;
ngx_mp4_set_32value(tkhd_atom->size, atom_size);
@@ -1749,16 +1801,10 @@ ngx_http_mp4_read_mdhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
trak = ngx_mp4_last_trak(mp4);
trak->mdhd_size = atom_size;
trak->timescale = timescale;
+ trak->duration = duration;
ngx_mp4_set_32value(mdhd_atom->size, atom_size);
- if (mdhd_atom->version[0] == 0) {
- ngx_mp4_set_32value(mdhd_atom->duration, duration);
-
- } else {
- ngx_mp4_set_64value(mdhd64_atom->duration, duration);
- }
-
atom = &trak->mdhd_atom_buf;
atom->temporary = 1;
atom->pos = atom_header;
@@ -1772,6 +1818,33 @@ ngx_http_mp4_read_mdhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
}
+static void
+ngx_http_mp4_update_mdhd_atom(ngx_http_mp4_file_t *mp4,
+ ngx_http_mp4_trak_t *trak)
+{
+ ngx_buf_t *atom;
+ ngx_mp4_mdhd_atom_t *mdhd_atom;
+ ngx_mp4_mdhd64_atom_t *mdhd64_atom;
+
+ atom = trak->out[NGX_HTTP_MP4_MDHD_ATOM].buf;
+ if (atom == NULL) {
+ return;
+ }
+
+ mdhd_atom = (ngx_mp4_mdhd_atom_t *) atom->pos;
+ mdhd64_atom = (ngx_mp4_mdhd64_atom_t *) atom->pos;
+
+ if (mdhd_atom->version[0] == 0) {
+ ngx_mp4_set_32value(mdhd_atom->duration, trak->duration);
+
+ } else {
+ ngx_mp4_set_64value(mdhd64_atom->duration, trak->duration);
+ }
+
+ trak->size += trak->mdhd_size;
+}
+
+
static ngx_int_t
ngx_http_mp4_read_hdlr_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
{
@@ -1962,6 +2035,59 @@ ngx_http_mp4_read_stbl_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
static void
+ngx_http_mp4_update_edts_atom(ngx_http_mp4_file_t *mp4,
+ ngx_http_mp4_trak_t *trak)
+{
+ ngx_buf_t *atom;
+ ngx_mp4_elst_atom_t *elst_atom;
+ ngx_mp4_edts_atom_t *edts_atom;
+
+ if (trak->prefix == 0) {
+ return;
+ }
+
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
+ "mp4 edts atom update prefix:%uL", trak->prefix);
+
+ edts_atom = &trak->edts_atom;
+ ngx_mp4_set_32value(edts_atom->size, sizeof(ngx_mp4_edts_atom_t)
+ + sizeof(ngx_mp4_elst_atom_t));
+ ngx_mp4_set_atom_name(edts_atom, 'e', 'd', 't', 's');
+
+ atom = &trak->edts_atom_buf;
+ atom->temporary = 1;
+ atom->pos = (u_char *) edts_atom;
+ atom->last = (u_char *) edts_atom + sizeof(ngx_mp4_edts_atom_t);
+
+ trak->out[NGX_HTTP_MP4_EDTS_ATOM].buf = atom;
+
+ elst_atom = &trak->elst_atom;
+ ngx_mp4_set_32value(elst_atom->size, sizeof(ngx_mp4_elst_atom_t));
+ ngx_mp4_set_atom_name(elst_atom, 'e', 'l', 's', 't');
+
+ elst_atom->version[0] = 1;
+ elst_atom->flags[0] = 0;
+ elst_atom->flags[1] = 0;
+ elst_atom->flags[2] = 0;
+
+ ngx_mp4_set_32value(elst_atom->entries, 1);
+ ngx_mp4_set_64value(elst_atom->duration, trak->movie_duration);
+ ngx_mp4_set_64value(elst_atom->media_time, trak->prefix);
+ ngx_mp4_set_16value(elst_atom->media_rate, 1);
+ ngx_mp4_set_16value(elst_atom->reserved, 0);
+
+ atom = &trak->elst_atom_buf;
+ atom->temporary = 1;
+ atom->pos = (u_char *) elst_atom;
+ atom->last = (u_char *) elst_atom + sizeof(ngx_mp4_elst_atom_t);
+
+ trak->out[NGX_HTTP_MP4_ELST_ATOM].buf = atom;
+
+ trak->size += sizeof(ngx_mp4_edts_atom_t) + sizeof(ngx_mp4_elst_atom_t);
+}
+
+
+static void
ngx_http_mp4_update_stbl_atom(ngx_http_mp4_file_t *mp4,
ngx_http_mp4_trak_t *trak)
{
@@ -2159,7 +2285,7 @@ static ngx_int_t
ngx_http_mp4_crop_stts_data(ngx_http_mp4_file_t *mp4,
ngx_http_mp4_trak_t *trak, ngx_uint_t start)
{
- uint32_t count, duration, rest;
+ uint32_t count, duration, rest, key_prefix;
uint64_t start_time;
ngx_buf_t *data;
ngx_uint_t start_sample, entries, start_sec;
@@ -2183,7 +2309,7 @@ ngx_http_mp4_crop_stts_data(ngx_http_mp4_file_t *mp4,
data = trak->out[NGX_HTTP_MP4_STTS_DATA].buf;
- start_time = (uint64_t) start_sec * trak->timescale / 1000;
+ start_time = (uint64_t) start_sec * trak->timescale / 1000 + trak->prefix;
entries = trak->time_to_sample_entries;
start_sample = 0;
@@ -2229,6 +2355,26 @@ ngx_http_mp4_crop_stts_data(ngx_http_mp4_file_t *mp4,
found:
if (start) {
+ key_prefix = ngx_http_mp4_seek_key_frame(mp4, trak, start_sample);
+
+ start_sample -= key_prefix;
+
+ while (rest < key_prefix) {
+ trak->prefix += rest * duration;
+ key_prefix -= rest;
+
+ entry--;
+ entries++;
+
+ count = ngx_mp4_get_32value(entry->count);
+ duration = ngx_mp4_get_32value(entry->duration);
+ rest = count;
+ }
+
+ trak->prefix += key_prefix * duration;
+ trak->duration += trak->prefix;
+ rest -= key_prefix;
+
ngx_mp4_set_32value(entry->count, count - rest);
data->pos = (u_char *) entry;
trak->time_to_sample_entries = entries;
@@ -2253,6 +2399,49 @@ found:
}
+static uint32_t
+ngx_http_mp4_seek_key_frame(ngx_http_mp4_file_t *mp4, ngx_http_mp4_trak_t *trak,
+ uint32_t start_sample)
+{
+ uint32_t key_prefix, sample, *entry, *end;
+ ngx_buf_t *data;
+ ngx_http_mp4_conf_t *conf;
+
+ conf = ngx_http_get_module_loc_conf(mp4->request, ngx_http_mp4_module);
+ if (!conf->start_key_frame) {
+ return 0;
+ }
+
+ data = trak->out[NGX_HTTP_MP4_STSS_DATA].buf;
+ if (data == NULL) {
+ return 0;
+ }
+
+ entry = (uint32_t *) data->pos;
+ end = (uint32_t *) data->last;
+
+ /* sync samples starts from 1 */
+ start_sample++;
+
+ key_prefix = 0;
+
+ while (entry < end) {
+ sample = ngx_mp4_get_32value(entry);
+ if (sample > start_sample) {
+ break;
+ }
+
+ key_prefix = start_sample - sample;
+ entry++;
+ }
+
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
+ "mp4 key frame prefix:%uD", key_prefix);
+
+ return key_prefix;
+}
+
+
typedef struct {
u_char size[4];
u_char name[4];
@@ -3590,6 +3779,7 @@ ngx_http_mp4_create_conf(ngx_conf_t *cf)
conf->buffer_size = NGX_CONF_UNSET_SIZE;
conf->max_buffer_size = NGX_CONF_UNSET_SIZE;
+ conf->start_key_frame = NGX_CONF_UNSET;
return conf;
}
@@ -3604,6 +3794,7 @@ ngx_http_mp4_merge_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size, 512 * 1024);
ngx_conf_merge_size_value(conf->max_buffer_size, prev->max_buffer_size,
10 * 1024 * 1024);
+ ngx_conf_merge_value(conf->start_key_frame, prev->start_key_frame, 0);
return NGX_CONF_OK;
}
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index 084462746..7c4061c02 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -2021,7 +2021,7 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
/* rc == NGX_HTTP_PARSE_INVALID_HEADER */
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"upstream sent invalid header: \"%*s\\x%02xd...\"",
r->header_end - r->header_name_start,
r->header_name_start, *r->header_end);
@@ -2337,6 +2337,7 @@ ngx_http_proxy_non_buffered_copy_filter(void *data, ssize_t bytes)
ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
"upstream sent more data than specified in "
"\"Content-Length\" header");
+ u->keepalive = 0;
return NGX_OK;
}
diff --git a/src/http/modules/ngx_http_scgi_module.c b/src/http/modules/ngx_http_scgi_module.c
index 570713df9..e5d31ae91 100644
--- a/src/http/modules/ngx_http_scgi_module.c
+++ b/src/http/modules/ngx_http_scgi_module.c
@@ -1142,7 +1142,7 @@ ngx_http_scgi_process_header(ngx_http_request_t *r)
/* rc == NGX_HTTP_PARSE_INVALID_HEADER */
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"upstream sent invalid header: \"%*s\\x%02xd...\"",
r->header_end - r->header_name_start,
r->header_name_start, *r->header_end);
diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c
index dbb5905df..f2a85f12e 100644
--- a/src/http/modules/ngx_http_ssl_module.c
+++ b/src/http/modules/ngx_http_ssl_module.c
@@ -17,7 +17,7 @@ typedef ngx_int_t (*ngx_ssl_variable_handler_pt)(ngx_connection_t *c,
#define NGX_DEFAULT_CIPHERS "HIGH:!aNULL:!MD5"
#define NGX_DEFAULT_ECDH_CURVE "auto"
-#define NGX_HTTP_NPN_ADVERTISE "\x08http/1.1"
+#define NGX_HTTP_ALPN_PROTOS "\x08http/1.1\x08http/1.0\x08http/0.9"
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
@@ -26,11 +26,6 @@ static int ngx_http_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn,
const unsigned char *in, unsigned int inlen, void *arg);
#endif
-#ifdef TLSEXT_TYPE_next_proto_neg
-static int ngx_http_ssl_npn_advertised(ngx_ssl_conn_t *ssl_conn,
- const unsigned char **out, unsigned int *outlen, void *arg);
-#endif
-
static ngx_int_t ngx_http_ssl_static_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_ssl_variable(ngx_http_request_t *r,
@@ -363,6 +358,9 @@ static ngx_http_variable_t ngx_http_ssl_vars[] = {
{ ngx_string("ssl_server_name"), NULL, ngx_http_ssl_variable,
(uintptr_t) ngx_ssl_get_server_name, NGX_HTTP_VAR_CHANGEABLE, 0 },
+ { ngx_string("ssl_alpn_protocol"), NULL, ngx_http_ssl_variable,
+ (uintptr_t) ngx_ssl_get_alpn_protocol, NGX_HTTP_VAR_CHANGEABLE, 0 },
+
{ ngx_string("ssl_client_cert"), NULL, ngx_http_ssl_variable,
(uintptr_t) ngx_ssl_get_certificate, NGX_HTTP_VAR_CHANGEABLE, 0 },
@@ -449,10 +447,8 @@ ngx_http_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn, const unsigned char **out,
#if (NGX_HTTP_V2)
if (hc->addr_conf->http2) {
- srv =
- (unsigned char *) NGX_HTTP_V2_ALPN_ADVERTISE NGX_HTTP_NPN_ADVERTISE;
- srvlen = sizeof(NGX_HTTP_V2_ALPN_ADVERTISE NGX_HTTP_NPN_ADVERTISE) - 1;
-
+ srv = (unsigned char *) NGX_HTTP_V2_ALPN_PROTO NGX_HTTP_ALPN_PROTOS;
+ srvlen = sizeof(NGX_HTTP_V2_ALPN_PROTO NGX_HTTP_ALPN_PROTOS) - 1;
} else
#endif
#if (NGX_HTTP_QUIC)
@@ -484,15 +480,15 @@ ngx_http_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn, const unsigned char **out,
} else
#endif
{
- srv = (unsigned char *) NGX_HTTP_NPN_ADVERTISE;
- srvlen = sizeof(NGX_HTTP_NPN_ADVERTISE) - 1;
+ srv = (unsigned char *) NGX_HTTP_ALPN_PROTOS;
+ srvlen = sizeof(NGX_HTTP_ALPN_PROTOS) - 1;
}
if (SSL_select_next_proto((unsigned char **) out, outlen, srv, srvlen,
in, inlen)
!= OPENSSL_NPN_NEGOTIATED)
{
- return SSL_TLSEXT_ERR_NOACK;
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
}
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
@@ -504,44 +500,6 @@ ngx_http_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn, const unsigned char **out,
#endif
-#ifdef TLSEXT_TYPE_next_proto_neg
-
-static int
-ngx_http_ssl_npn_advertised(ngx_ssl_conn_t *ssl_conn,
- const unsigned char **out, unsigned int *outlen, void *arg)
-{
-#if (NGX_HTTP_V2 || NGX_DEBUG)
- ngx_connection_t *c;
-
- c = ngx_ssl_get_connection(ssl_conn);
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "SSL NPN advertised");
-#endif
-
-#if (NGX_HTTP_V2)
- {
- ngx_http_connection_t *hc;
-
- hc = c->data;
-
- if (hc->addr_conf->http2) {
- *out =
- (unsigned char *) NGX_HTTP_V2_NPN_ADVERTISE NGX_HTTP_NPN_ADVERTISE;
- *outlen = sizeof(NGX_HTTP_V2_NPN_ADVERTISE NGX_HTTP_NPN_ADVERTISE) - 1;
-
- return SSL_TLSEXT_ERR_OK;
- }
- }
-#endif
-
- *out = (unsigned char *) NGX_HTTP_NPN_ADVERTISE;
- *outlen = sizeof(NGX_HTTP_NPN_ADVERTISE) - 1;
-
- return SSL_TLSEXT_ERR_OK;
-}
-
-#endif
-
-
static ngx_int_t
ngx_http_ssl_static_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
@@ -825,11 +783,6 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
SSL_CTX_set_alpn_select_cb(conf->ssl.ctx, ngx_http_ssl_alpn_select, NULL);
#endif
-#ifdef TLSEXT_TYPE_next_proto_neg
- SSL_CTX_set_next_protos_advertised_cb(conf->ssl.ctx,
- ngx_http_ssl_npn_advertised, NULL);
-#endif
-
if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers,
conf->prefer_server_ciphers)
!= NGX_OK)
diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c
index 4f9c349c2..d46741a00 100644
--- a/src/http/modules/ngx_http_uwsgi_module.c
+++ b/src/http/modules/ngx_http_uwsgi_module.c
@@ -1363,7 +1363,7 @@ ngx_http_uwsgi_process_header(ngx_http_request_t *r)
/* rc == NGX_HTTP_PARSE_INVALID_HEADER */
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"upstream sent invalid header: \"%*s\\x%02xd...\"",
r->header_end - r->header_name_start,
r->header_name_start, *r->header_end);
diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c
index c9aa3761b..908e88103 100644
--- a/src/http/ngx_http.c
+++ b/src/http/ngx_http.c
@@ -1360,13 +1360,12 @@ ngx_http_add_address(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
}
#if (NGX_HTTP_V2 && NGX_HTTP_SSL \
- && !defined TLSEXT_TYPE_application_layer_protocol_negotiation \
- && !defined TLSEXT_TYPE_next_proto_neg)
+ && !defined TLSEXT_TYPE_application_layer_protocol_negotiation)
if (lsopt->http2 && lsopt->ssl) {
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
"nginx was built with OpenSSL that lacks ALPN "
- "and NPN support, HTTP/2 is not enabled for %V",
+ "support, HTTP/2 is not enabled for %V",
&lsopt->addr_text);
}
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index c19020dfd..19bc75136 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -3720,7 +3720,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_value(conf->internal, prev->internal, 0);
ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0);
ngx_conf_merge_size_value(conf->sendfile_max_chunk,
- prev->sendfile_max_chunk, 0);
+ prev->sendfile_max_chunk, 2 * 1024 * 1024);
ngx_conf_merge_size_value(conf->subrequest_output_buffer_size,
prev->subrequest_output_buffer_size,
(size_t) ngx_pagesize);
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index ae5e518b7..148696641 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -508,8 +508,8 @@ ngx_int_t ngx_http_gzip_ok(ngx_http_request_t *r);
ngx_int_t ngx_http_subrequest(ngx_http_request_t *r,
- ngx_str_t *uri, ngx_str_t *args, ngx_http_request_t **sr,
- ngx_http_post_subrequest_t *psr, ngx_uint_t flags);
+ ngx_str_t *uri, ngx_str_t *args, ngx_http_request_t **psr,
+ ngx_http_post_subrequest_t *ps, ngx_uint_t flags);
ngx_int_t ngx_http_internal_redirect(ngx_http_request_t *r,
ngx_str_t *uri, ngx_str_t *args);
ngx_int_t ngx_http_named_location(ngx_http_request_t *r, ngx_str_t *name);
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index e37ef8024..88516cb4d 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -617,7 +617,7 @@ ngx_http_alloc_request(ngx_connection_t *c)
}
#if (NGX_HTTP_SSL)
- if (c->ssl) {
+ if (c->ssl && !c->ssl->sendfile) {
r->main_filter_need_in_memory = 1;
}
#endif
@@ -816,8 +816,7 @@ ngx_http_ssl_handshake_handler(ngx_connection_t *c)
c->ssl->no_wait_shutdown = 1;
#if (NGX_HTTP_V2 \
- && (defined TLSEXT_TYPE_application_layer_protocol_negotiation \
- || defined TLSEXT_TYPE_next_proto_neg))
+ && defined TLSEXT_TYPE_application_layer_protocol_negotiation)
{
unsigned int len;
const unsigned char *data;
@@ -827,19 +826,8 @@ ngx_http_ssl_handshake_handler(ngx_connection_t *c)
if (hc->addr_conf->http2) {
-#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
SSL_get0_alpn_selected(c->ssl->connection, &data, &len);
-#ifdef TLSEXT_TYPE_next_proto_neg
- if (len == 0) {
- SSL_get0_next_proto_negotiated(c->ssl->connection, &data, &len);
- }
-#endif
-
-#else /* TLSEXT_TYPE_next_proto_neg */
- SSL_get0_next_proto_negotiated(c->ssl->connection, &data, &len);
-#endif
-
if (len == 2 && data[0] == 'h' && data[1] == '2') {
ngx_http_v2_init(c->read);
return;
diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c
index e4d9ff5be..d2bec7820 100644
--- a/src/http/ngx_http_request_body.c
+++ b/src/http/ngx_http_request_body.c
@@ -1330,7 +1330,7 @@ ngx_http_request_body_save_filter(ngx_http_request_t *r, ngx_chain_t *in)
if (rb->rest > 0) {
- if (rb->buf && rb->buf->last == rb->buf->end
+ if (rb->bufs && rb->buf && rb->buf->last == rb->buf->end
&& ngx_http_write_request_body(r) != NGX_OK)
{
return NGX_HTTP_INTERNAL_SERVER_ERROR;
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index 7ca75d3b7..d27a53ea4 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -1531,8 +1531,9 @@ ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
static void
ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u)
{
- ngx_int_t rc;
- ngx_connection_t *c;
+ ngx_int_t rc;
+ ngx_connection_t *c;
+ ngx_http_core_loc_conf_t *clcf;
r->connection->log->action = "connecting to upstream";
@@ -1619,10 +1620,12 @@ ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u)
/* init or reinit the ngx_output_chain() and ngx_chain_writer() contexts */
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
u->writer.out = NULL;
u->writer.last = &u->writer.out;
u->writer.connection = c;
- u->writer.limit = 0;
+ u->writer.limit = clcf->sendfile_max_chunk;
if (u->request_sent) {
if (ngx_http_upstream_reinit(r, u) != NGX_OK) {
@@ -1703,9 +1706,6 @@ ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r,
return;
}
- c->sendfile = 0;
- u->output.sendfile = 0;
-
if (u->conf->ssl_server_name || u->conf->ssl_verify) {
if (ngx_http_upstream_ssl_name(r, u, c) != NGX_OK) {
ngx_http_upstream_finalize_request(r, u,
@@ -1811,6 +1811,11 @@ ngx_http_upstream_ssl_handshake(ngx_http_request_t *r, ngx_http_upstream_t *u,
}
}
+ if (!c->ssl->sendfile) {
+ c->sendfile = 0;
+ u->output.sendfile = 0;
+ }
+
c->write->handler = ngx_http_upstream_handler;
c->read->handler = ngx_http_upstream_handler;
diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c
index c25d80ccf..942dacd70 100644
--- a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -1179,6 +1179,10 @@ ngx_http_variable_content_length(ngx_http_request_t *r,
v->no_cacheable = 0;
v->not_found = 0;
+ } else if (r->headers_in.chunked) {
+ v->not_found = 1;
+ v->no_cacheable = 1;
+
} else {
v->not_found = 1;
}
diff --git a/src/http/ngx_http_write_filter_module.c b/src/http/ngx_http_write_filter_module.c
index 2a4996251..8ef19b645 100644
--- a/src/http/ngx_http_write_filter_module.c
+++ b/src/http/ngx_http_write_filter_module.c
@@ -325,18 +325,13 @@ ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
delay = (ngx_msec_t) ((nsent - sent) * 1000 / r->limit_rate);
if (delay > 0) {
- limit = 0;
c->write->delayed = 1;
ngx_add_timer(c->write, delay);
}
}
- if (limit
- && c->write->ready
- && c->sent - sent >= limit - (off_t) (2 * ngx_pagesize))
- {
- c->write->delayed = 1;
- ngx_add_timer(c->write, 1);
+ if (chain && c->write->ready && !c->write->delayed) {
+ ngx_post_event(c->write, &ngx_posted_next_events);
}
for (cl = r->out; cl && cl != chain; /* void */) {
diff --git a/src/http/v2/ngx_http_v2.h b/src/http/v2/ngx_http_v2.h
index 65fc65812..70ee287ae 100644
--- a/src/http/v2/ngx_http_v2.h
+++ b/src/http/v2/ngx_http_v2.h
@@ -13,8 +13,7 @@
#include <ngx_http.h>
-#define NGX_HTTP_V2_ALPN_ADVERTISE "\x02h2"
-#define NGX_HTTP_V2_NPN_ADVERTISE NGX_HTTP_V2_ALPN_ADVERTISE
+#define NGX_HTTP_V2_ALPN_PROTO "\x02h2"
#define NGX_HTTP_V2_STATE_BUFFER_SIZE 16