Compare commits

..

12 Commits

Author SHA1 Message Date
Tatsuhiro Tsujikawa
8585599b4b nghttpx: Add doc 2015-07-16 00:03:34 +09:00
Tatsuhiro Tsujikawa
2bac00ea5f nghttpx: Add additional assert just in case 2015-07-16 00:01:26 +09:00
Tatsuhiro Tsujikawa
3396c71c3c Update man pages 2015-07-15 23:48:41 +09:00
Tatsuhiro Tsujikawa
f821f6bd80 Bump up version number to 1.1.1 2015-07-15 23:46:22 +09:00
Tatsuhiro Tsujikawa
7a3012cc1b src: Rename timegm as nghttp2_timegm 2015-07-15 23:44:24 +09:00
Tatsuhiro Tsujikawa
ba31b990a2 nghttpx: Remove dead handling of Downstream::STREAM_CLOSED 2015-07-15 23:33:44 +09:00
Tatsuhiro Tsujikawa
fc062976a1 nghttpx: Delete DownstreamConnection from Downstream explicitly 2015-07-15 23:31:32 +09:00
Tatsuhiro Tsujikawa
20e63151a5 nghttpx: Fix bug that idle timer is used after reuse 2015-07-15 23:18:32 +09:00
Tatsuhiro Tsujikawa
e63e775fea nghttpx: Simplify BlockedLink management 2015-07-15 20:44:44 +09:00
Tatsuhiro Tsujikawa
031fb31248 nghttpx: Fix memory leak, and blocked stream dispatch 2015-07-15 19:47:15 +09:00
Tatsuhiro Tsujikawa
6d10799301 nghttpx: Don't pool failed HTTP/1 backend connection 2015-07-15 19:46:48 +09:00
Tatsuhiro Tsujikawa
f54745fe4c Bump up version number to 1.1.1-DEV 2015-07-15 01:29:57 +09:00
15 changed files with 48 additions and 107 deletions

View File

@@ -25,7 +25,7 @@ dnl Do not change user variables!
dnl http://www.gnu.org/software/automake/manual/html_node/Flag-Variables-Ordering.html
AC_PREREQ(2.61)
AC_INIT([nghttp2], [1.1.0], [t-tujikawa@users.sourceforge.net])
AC_INIT([nghttp2], [1.1.1], [t-tujikawa@users.sourceforge.net])
AC_USE_SYSTEM_EXTENSIONS
LT_PREREQ([2.2.6])

View File

@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "H2LOAD" "1" "July 15, 2015" "1.1.0" "nghttp2"
.TH "H2LOAD" "1" "July 15, 2015" "1.1.1" "nghttp2"
.SH NAME
h2load \- HTTP/2 benchmarking tool
.

View File

@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "NGHTTP" "1" "July 15, 2015" "1.1.0" "nghttp2"
.TH "NGHTTP" "1" "July 15, 2015" "1.1.1" "nghttp2"
.SH NAME
nghttp \- HTTP/2 experimental client
.

View File

@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "NGHTTPD" "1" "July 15, 2015" "1.1.0" "nghttp2"
.TH "NGHTTPD" "1" "July 15, 2015" "1.1.1" "nghttp2"
.SH NAME
nghttpd \- HTTP/2 experimental server
.

View File

@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "NGHTTPX" "1" "July 15, 2015" "1.1.0" "nghttp2"
.TH "NGHTTPX" "1" "July 15, 2015" "1.1.1" "nghttp2"
.SH NAME
nghttpx \- HTTP/2 experimental proxy
.

View File

@@ -152,10 +152,6 @@ Downstream::~Downstream() {
DLOG(INFO, this) << "Deleting";
}
if (blocked_link_) {
detach_blocked_link(blocked_link_);
}
// check nullptr for unittest
if (upstream_) {
auto loop = upstream_->get_client_handler()->get_loop();
@@ -166,6 +162,10 @@ Downstream::~Downstream() {
ev_timer_stop(loop, &downstream_wtimer_);
}
// DownstreamConnection may refer to this object. Delete it now
// explicitly.
dconn_.reset();
if (LOG_ENABLED(INFO)) {
DLOG(INFO, this) << "Deleted";
}
@@ -195,8 +195,6 @@ void Downstream::detach_downstream_connection() {
std::unique_ptr<DownstreamConnection>(dconn_.release()));
}
void Downstream::release_downstream_connection() { dconn_.release(); }
DownstreamConnection *Downstream::get_downstream_connection() {
return dconn_.get();
}
@@ -1200,12 +1198,10 @@ void Downstream::attach_blocked_link(BlockedLink *l) {
blocked_link_ = l;
}
void Downstream::detach_blocked_link(BlockedLink *l) {
assert(blocked_link_);
assert(l->downstream == this);
l->downstream = nullptr;
BlockedLink *Downstream::detach_blocked_link() {
auto link = blocked_link_;
blocked_link_ = nullptr;
return link;
}
void Downstream::add_request_headers_sum(size_t amount) {

View File

@@ -69,8 +69,6 @@ public:
int attach_downstream_connection(std::unique_ptr<DownstreamConnection> dconn);
void detach_downstream_connection();
// Releases dconn_, without freeing it.
void release_downstream_connection();
DownstreamConnection *get_downstream_connection();
// Returns dconn_ and nullifies dconn_.
std::unique_ptr<DownstreamConnection> pop_downstream_connection();
@@ -332,7 +330,7 @@ public:
void set_dispatch_state(int s);
void attach_blocked_link(BlockedLink *l);
void detach_blocked_link(BlockedLink *l);
BlockedLink *detach_blocked_link();
enum {
EVENT_ERROR = 0x1,

View File

@@ -124,17 +124,21 @@ Downstream *DownstreamQueue::remove_and_get_blocked(Downstream *downstream) {
// Delete downstream when this function returns.
auto delptr = std::unique_ptr<Downstream>(downstream);
if (downstream->get_dispatch_state() != Downstream::DISPATCH_ACTIVE) {
assert(downstream->get_dispatch_state() != Downstream::DISPATCH_NONE);
downstreams_.remove(downstream);
return nullptr;
}
downstreams_.remove(downstream);
auto &host = make_host_key(downstream);
auto &ent = find_host_entry(host);
--ent.num_active;
if (downstream->get_dispatch_state() == Downstream::DISPATCH_ACTIVE) {
--ent.num_active;
} else {
// For those downstreams deleted while in blocked state
auto link = downstream->detach_blocked_link();
if (link) {
ent.blocked.remove(link);
delete link;
}
}
if (remove_host_entry_if_empty(ent, host_entries_, host)) {
return nullptr;
@@ -144,21 +148,20 @@ Downstream *DownstreamQueue::remove_and_get_blocked(Downstream *downstream) {
return nullptr;
}
for (auto link = ent.blocked.head; link;) {
auto next = link->dlnext;
if (!link->downstream) {
ent.blocked.remove(link);
link = next;
continue;
}
auto next_downstream = link->downstream;
next_downstream->detach_blocked_link(link);
ent.blocked.remove(link);
delete link;
remove_host_entry_if_empty(ent, host_entries_, host);
return next_downstream;
auto link = ent.blocked.head;
if (!link) {
return nullptr;
}
return nullptr;
auto next_downstream = link->downstream;
auto link2 = next_downstream->detach_blocked_link();
assert(link2 == link);
ent.blocked.remove(link);
delete link;
remove_host_entry_if_empty(ent, host_entries_, host);
return next_downstream;
}
Downstream *DownstreamQueue::get_downstreams() const {

View File

@@ -86,11 +86,7 @@ Http2DownstreamConnection::~Http2DownstreamConnection() {
}
}
http2session_->remove_downstream_connection(this);
// Downstream and DownstreamConnection may be deleted
// asynchronously.
if (downstream_) {
downstream_->release_downstream_connection();
}
if (LOG_ENABLED(INFO)) {
DCLOG(INFO, this) << "Deleted";
}

View File

@@ -884,16 +884,6 @@ ClientHandler *Http2Upstream::get_client_handler() const { return handler_; }
int Http2Upstream::downstream_read(DownstreamConnection *dconn) {
auto downstream = dconn->get_downstream();
if (downstream->get_request_state() == Downstream::STREAM_CLOSED) {
// If upstream HTTP2 stream was closed, we just close downstream,
// because there is no consumer now. Downstream connection is also
// closed in this case.
remove_downstream(downstream);
// downstream was deleted
return 0;
}
if (downstream->get_response_state() == Downstream::MSG_RESET) {
// The downstream stream was reset (canceled). In this case,
// RST_STREAM to the upstream and delete downstream connection
@@ -959,14 +949,6 @@ int Http2Upstream::downstream_eof(DownstreamConnection *dconn) {
if (LOG_ENABLED(INFO)) {
DCLOG(INFO, dconn) << "EOF. stream_id=" << downstream->get_stream_id();
}
if (downstream->get_request_state() == Downstream::STREAM_CLOSED) {
// If stream was closed already, we don't need to send reply at
// the first place. We can delete downstream.
remove_downstream(downstream);
// downstream was deleted
return 0;
}
// Delete downstream connection. If we don't delete it here, it will
// be pooled in on_stream_close_callback.
@@ -1012,13 +994,6 @@ int Http2Upstream::downstream_error(DownstreamConnection *dconn, int events) {
}
}
if (downstream->get_request_state() == Downstream::STREAM_CLOSED) {
remove_downstream(downstream);
// downstream was deleted
return 0;
}
// Delete downstream connection. If we don't delete it here, it will
// be pooled in on_stream_close_callback.
downstream->pop_downstream_connection();

View File

@@ -118,13 +118,7 @@ HttpDownstreamConnection::HttpDownstreamConnection(
ioctrl_(&conn_.rlimit), response_htp_{0}, group_(group), addr_idx_(0),
connected_(false) {}
HttpDownstreamConnection::~HttpDownstreamConnection() {
// Downstream and DownstreamConnection may be deleted
// asynchronously.
if (downstream_) {
downstream_->release_downstream_connection();
}
}
HttpDownstreamConnection::~HttpDownstreamConnection() {}
int HttpDownstreamConnection::attach_downstream(Downstream *downstream) {
if (LOG_ENABLED(INFO)) {
@@ -205,6 +199,8 @@ int HttpDownstreamConnection::attach_downstream(Downstream *downstream) {
ev_set_cb(&conn_.rev, readcb);
conn_.rt.repeat = get_config()->downstream_read_timeout;
// we may set read timer cb to idle_timeoutcb. Reset again.
ev_set_cb(&conn_.rt, timeoutcb);
ev_timer_again(conn_.loop, &conn_.rt);
// TODO we should have timeout for connection establishment
ev_timer_again(conn_.loop, &conn_.wt);
@@ -864,6 +860,8 @@ int HttpDownstreamConnection::on_connect() {
DLOG(INFO, this) << "downstream connect failed";
}
downstream_->set_request_state(Downstream::CONNECT_FAIL);
return -1;
}

View File

@@ -560,16 +560,6 @@ ClientHandler *SpdyUpstream::get_client_handler() const { return handler_; }
int SpdyUpstream::downstream_read(DownstreamConnection *dconn) {
auto downstream = dconn->get_downstream();
if (downstream->get_request_state() == Downstream::STREAM_CLOSED) {
// If upstream SPDY stream was closed, we just close downstream,
// because there is no consumer now. Downstream connection is also
// closed in this case.
remove_downstream(downstream);
// downstrea was deleted
return 0;
}
if (downstream->get_response_state() == Downstream::MSG_RESET) {
// The downstream stream was reset (canceled). In this case,
// RST_STREAM to the upstream and delete downstream connection
@@ -633,14 +623,6 @@ int SpdyUpstream::downstream_eof(DownstreamConnection *dconn) {
if (LOG_ENABLED(INFO)) {
DCLOG(INFO, dconn) << "EOF. stream_id=" << downstream->get_stream_id();
}
if (downstream->get_request_state() == Downstream::STREAM_CLOSED) {
// If stream was closed already, we don't need to send reply at
// the first place. We can delete downstream.
remove_downstream(downstream);
// downstream was deleted
return 0;
}
// Delete downstream connection. If we don't delete it here, it will
// be pooled in on_stream_close_callback.
@@ -686,13 +668,6 @@ int SpdyUpstream::downstream_error(DownstreamConnection *dconn, int events) {
}
}
if (downstream->get_request_state() == Downstream::STREAM_CLOSED) {
remove_downstream(downstream);
// downstream was deleted
return 0;
}
// Delete downstream connection. If we don't delete it here, it will
// be pooled in on_stream_close_callback.
downstream->pop_downstream_connection();

View File

@@ -34,7 +34,7 @@ static int count_leap_year(int y) {
}
/* Based on the algorithm of Python 2.7 calendar.timegm. */
time_t timegm(struct tm *tm) {
time_t nghttp2_timegm(struct tm *tm) {
int days;
int num_leap_year;
int64_t t;

View File

@@ -37,7 +37,7 @@ extern "C" {
#include <time.h>
#endif // HAVE_TIME_H
time_t timegm(struct tm *tm);
time_t nghttp2_timegm(struct tm *tm);
#ifdef __cplusplus
}

View File

@@ -278,7 +278,7 @@ std::string common_log_date(time_t t) {
#ifdef HAVE_STRUCT_TM_TM_GMTOFF
auto gmtoff = tms.tm_gmtoff;
#else // !HAVE_STRUCT_TM_TM_GMTOFF
auto gmtoff = timegm(&tms) - t;
auto gmtoff = nghttp2_timegm(&tms) - t;
#endif // !HAVE_STRUCT_TM_TM_GMTOFF
if (gmtoff >= 0) {
*p++ = '+';
@@ -326,7 +326,7 @@ std::string iso8601_date(int64_t ms) {
#ifdef HAVE_STRUCT_TM_TM_GMTOFF
auto gmtoff = tms.tm_gmtoff;
#else // !HAVE_STRUCT_TM_TM_GMTOFF
auto gmtoff = timegm(&tms) - sec;
auto gmtoff = nghttp2_timegm(&tms) - sec;
#endif // !HAVE_STRUCT_TM_TM_GMTOFF
if (gmtoff == 0) {
*p++ = 'Z';
@@ -354,7 +354,7 @@ time_t parse_http_date(const std::string &s) {
if (r == 0) {
return 0;
}
return timegm(&tm);
return nghttp2_timegm(&tm);
}
namespace {