From a41a230fdcc2d1024f7bf808c8c655073b8056d7 Mon Sep 17 00:00:00 2001 From: pengbo <1117111@qq.com> Date: Tue, 1 Aug 2017 22:32:34 +0800 Subject: [PATCH] Patch for libnghttp2_asio to support Visual Studio 2015. Author: Liu Yong Guan --- src/HttpServer.cc | 8 +- src/allocator.h | 10 ++- src/asio_client_session_impl.cc | 2 +- src/asio_common.cc | 7 +- src/asio_server_http2_handler.cc | 2 +- src/buffer.h | 8 +- src/h2load.cc | 18 ++--- src/http2.cc | 4 +- src/libevent_util.cc | 2 +- src/memchunk.h | 52 ++++++++++--- src/network.h | 10 +++ src/nghttp.cc | 4 +- src/shrpx_client_handler.cc | 8 +- src/shrpx_connect_blocker.cc | 4 +- src/shrpx_connection.cc | 12 +-- src/shrpx_connection_handler.cc | 2 +- src/shrpx_http.cc | 2 +- src/shrpx_http2_downstream_connection.cc | 2 +- src/shrpx_http2_upstream.cc | 12 +-- src/shrpx_live_check.cc | 4 +- src/shrpx_log.cc | 10 +-- src/shrpx_memcached_connection.cc | 10 +-- src/shrpx_rate_limit.cc | 2 +- src/shrpx_router.cc | 10 +-- src/shrpx_spdy_upstream.cc | 8 +- src/shrpx_worker_process.cc | 2 +- src/util.cc | 95 ++++++++++++++++++++---- src/util.h | 2 +- 28 files changed, 214 insertions(+), 98 deletions(-) diff --git a/src/HttpServer.cc b/src/HttpServer.cc index 8466fec0..ad1bc2e7 100644 --- a/src/HttpServer.cc +++ b/src/HttpServer.cc @@ -586,7 +586,7 @@ void Http2Handler::start_settings_timer() { int Http2Handler::fill_wb() { if (data_pending_) { - auto n = std::min(wb_.wleft(), data_pendinglen_); + auto n = (std::min)(wb_.wleft(), data_pendinglen_); wb_.write(data_pending_, n); if (n < data_pendinglen_) { data_pending_ += n; @@ -1084,7 +1084,7 @@ ssize_t file_read_callback(nghttp2_session *session, int32_t stream_id, auto hd = static_cast(user_data); auto stream = hd->get_stream(stream_id); - auto nread = std::min(stream->body_length - stream->body_offset, + auto nread = (std::min)(stream->body_length - stream->body_offset, static_cast(length)); *data_flags |= NGHTTP2_DATA_FLAG_NO_COPY; @@ -1583,7 +1583,7 @@ int hd_on_frame_send_callback(nghttp2_session *session, if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) { remove_stream_write_timeout(stream); - } else if (std::min(nghttp2_session_get_stream_remote_window_size( + } else if ((std::min)(nghttp2_session_get_stream_remote_window_size( session, frame->hd.stream_id), nghttp2_session_get_remote_window_size(session)) <= 0) { // If stream is blocked by flow control, enable write timeout. @@ -1681,7 +1681,7 @@ ssize_t select_padding_callback(nghttp2_session *session, const nghttp2_frame *frame, size_t max_payload, void *user_data) { auto hd = static_cast(user_data); - return std::min(max_payload, frame->hd.length + hd->get_config()->padding); + return (std::min)(max_payload, frame->hd.length + hd->get_config()->padding); } } // namespace diff --git a/src/allocator.h b/src/allocator.h index 7fa0b8ec..7d3ace71 100644 --- a/src/allocator.h +++ b/src/allocator.h @@ -27,7 +27,11 @@ #include "nghttp2_config.h" +#ifdef WIN32 +#include +#else #include +#endif #include @@ -56,7 +60,7 @@ struct BlockAllocator { : retain(nullptr), head(nullptr), block_size(block_size), - isolation_threshold(std::min(block_size, isolation_threshold)) { + isolation_threshold((std::min)(block_size, isolation_threshold)) { assert(isolation_threshold <= block_size); } @@ -112,7 +116,7 @@ struct BlockAllocator { void *alloc(size_t size) { if (size + sizeof(size_t) >= isolation_threshold) { - auto len = std::max(static_cast(16), size); + auto len = (std::max)(static_cast(16), size); // We will store the allocated size in size_t field. auto mb = alloc_mem_block(len + sizeof(size_t)); auto sp = reinterpret_cast(mb->begin); @@ -161,7 +165,7 @@ struct BlockAllocator { return ptr; } - auto nalloclen = std::max(size + 1, alloclen * 2); + auto nalloclen = (std::max)(size + 1, alloclen * 2); auto res = alloc(nalloclen); std::copy_n(p, alloclen, static_cast(res)); diff --git a/src/asio_client_session_impl.cc b/src/asio_client_session_impl.cc index 025254b4..2d078523 100644 --- a/src/asio_client_session_impl.cc +++ b/src/asio_client_session_impl.cc @@ -473,7 +473,7 @@ stream *session_impl::create_push_stream(int32_t stream_id) { } std::unique_ptr session_impl::create_stream() { - return make_unique(this); + return nghttp2::make_unique(this); } const request *session_impl::submit(boost::system::error_code &ec, diff --git a/src/asio_common.cc b/src/asio_common.cc index c93b3619..1d2f3893 100644 --- a/src/asio_common.cc +++ b/src/asio_common.cc @@ -79,7 +79,7 @@ generator_cb string_generator(std::string data) { return [strio](uint8_t *buf, size_t len, uint32_t *data_flags) { auto &data = strio->first; auto &left = strio->second; - auto n = std::min(len, left); + auto n = (std::min)(len, left); std::copy_n(data.c_str() + data.size() - left, n, buf); left -= n; if (left == 0) { @@ -102,7 +102,12 @@ std::shared_ptr> defer_shared(F &&f, T &&... t) { } generator_cb file_generator(const std::string &path) { +#ifdef WIN32 + auto fd = open(path.c_str(), 0x0000); +#else auto fd = open(path.c_str(), O_RDONLY); +#endif // WIN32 + if (fd == -1) { return generator_cb(); } diff --git a/src/asio_server_http2_handler.cc b/src/asio_server_http2_handler.cc index 5a784ed8..1a0e2ad9 100644 --- a/src/asio_server_http2_handler.cc +++ b/src/asio_server_http2_handler.cc @@ -305,7 +305,7 @@ int http2_handler::start() { } stream *http2_handler::create_stream(int32_t stream_id) { - auto p = streams_.emplace(stream_id, make_unique(this, stream_id)); + auto p = streams_.emplace(stream_id, nghttp2::make_unique(this, stream_id)); assert(p.second); return (*p.first).second.get(); } diff --git a/src/buffer.h b/src/buffer.h index 1921edf1..0e533b7e 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -42,24 +42,24 @@ template struct Buffer { // Writes up to min(wleft(), |count|) bytes from buffer pointed by // |src|. Returns number of bytes written. size_t write(const void *src, size_t count) { - count = std::min(count, wleft()); + count = (std::min)(count, wleft()); auto p = static_cast(src); last = std::copy_n(p, count, last); return count; } size_t write(size_t count) { - count = std::min(count, wleft()); + count = (std::min)(count, wleft()); last += count; return count; } // Drains min(rleft(), |count|) bytes from start of the buffer. size_t drain(size_t count) { - count = std::min(count, rleft()); + count = (std::min)(count, rleft()); pos += count; return count; } size_t drain_reset(size_t count) { - count = std::min(count, rleft()); + count = (std::min)(count, rleft()); std::copy(pos + count, last, std::begin(buf)); last = std::begin(buf) + (last - (pos + count)); pos = std::begin(buf); diff --git a/src/h2load.cc b/src/h2load.cc index 492d8d9f..b1de64e6 100644 --- a/src/h2load.cc +++ b/src/h2load.cc @@ -224,7 +224,7 @@ void rate_period_timeout_w_cb(struct ev_loop *loop, ev_timer *w, int revents) { auto worker = static_cast(w->data); auto nclients_per_second = worker->rate; auto conns_remaining = worker->nclients - worker->nconns_made; - auto nclients = std::min(nclients_per_second, conns_remaining); + auto nclients = (std::min)(nclients_per_second, conns_remaining); for (size_t i = 0; i < nclients; ++i) { auto req_todo = worker->nreqs_per_client; @@ -865,7 +865,7 @@ int Client::connection_made() { record_connect_time(); if (!config.timing_script) { - auto nreq = std::min(req_left, session->max_concurrent_streams()); + auto nreq = (std::min)(req_left, session->max_concurrent_streams()); for (; nreq > 0; --nreq) { if (submit_request() != 0) { process_request_failure(); @@ -1177,9 +1177,9 @@ Worker::Worker(uint32_t id, SSL_CTX *ssl_ctx, size_t req_todo, size_t nclients, max_samples(max_samples), next_client_id(0) { if (!config->is_rate_mode()) { - progress_interval = std::max(static_cast(1), req_todo / 10); + progress_interval = (std::max)(static_cast(1), req_todo / 10); } else { - progress_interval = std::max(static_cast(1), nclients / 10); + progress_interval = (std::max)(static_cast(1), nclients / 10); } // create timer that will go off every rate_period @@ -1187,8 +1187,8 @@ Worker::Worker(uint32_t id, SSL_CTX *ssl_ctx, size_t req_todo, size_t nclients, config->rate_period); timeout_watcher.data = this; - stats.req_stats.reserve(std::min(req_todo, max_samples)); - stats.client_stats.reserve(std::min(nclients, max_samples)); + stats.req_stats.reserve((std::min)(req_todo, max_samples)); + stats.client_stats.reserve((std::min)(nclients, max_samples)); sampling_init(request_times_smp, req_todo, max_samples); sampling_init(client_smp, nclients, max_samples); @@ -1286,8 +1286,8 @@ SDStat compute_time_stat(const std::vector &samples, std::numeric_limits::min()}; for (const auto &t : samples) { ++n; - res.min = std::min(res.min, t); - res.max = std::max(res.max, t); + res.min = (std::min)(res.min, t); + res.max = (std::max)(res.max, t); sum += t; auto na = a + (t - a) / n; @@ -2424,7 +2424,7 @@ int main(int argc, char **argv) { ssize_t rate_per_thread_rem = config.rate % config.nthreads; size_t max_samples_per_thread = - std::max(static_cast(256), MAX_SAMPLES / config.nthreads); + (std::max)(static_cast(256), MAX_SAMPLES / config.nthreads); std::mutex mu; std::condition_variable cv; diff --git a/src/http2.cc b/src/http2.cc index 9ee1679b..19fba1af 100644 --- a/src/http2.cc +++ b/src/http2.cc @@ -1625,8 +1625,8 @@ StringRef path_join(BlockAllocator &balloc, const StringRef &base_path, const StringRef &rel_query) { auto res = make_byte_ref( balloc, - std::max(static_cast(1), base_path.size()) + rel_path.size() + 1 + - std::max(base_query.size(), rel_query.size()) + 1); + (std::max)(static_cast(1), base_path.size()) + rel_path.size() + 1 + + (std::max)(base_query.size(), rel_query.size()) + 1); auto p = res.base; if (rel_path.empty()) { diff --git a/src/libevent_util.cc b/src/libevent_util.cc index 3b60b6d9..7d8c5b3b 100644 --- a/src/libevent_util.cc +++ b/src/libevent_util.cc @@ -73,7 +73,7 @@ int EvbufferBuffer::write_buffer() { for (auto pos = buf_, end = buf_ + buflen_; pos < end;) { // To avoid merging chunks in evbuffer, we first add to temporal // buffer bucket_ and then move its chain to evbuffer_. - auto nwrite = std::min(end - pos, limit_); + auto nwrite = (std::min)(end - pos, limit_); auto rv = evbuffer_add(bucket_, pos, nwrite); if (rv == -1) { return -1; diff --git a/src/memchunk.h b/src/memchunk.h index b5fec00b..8e0b38e0 100644 --- a/src/memchunk.h +++ b/src/memchunk.h @@ -28,7 +28,11 @@ #include "nghttp2_config.h" #include +#ifdef WIN32 +#include +#else #include +#endif // WIN32 #include #include @@ -39,8 +43,30 @@ #include "template.h" + namespace nghttp2 { + +#ifdef WIN32 + +struct iovec { /* Scatter/gather array items */ + void *iov_base; /* Starting address */ + size_t iov_len; /* Number of bytes to transfer */ + }; + +struct msghdr { + void *msg_name; /* optional address */ + socklen_t msg_namelen; /* size of address */ + struct iovec *msg_iov; /* scatter/gather array */ + size_t msg_iovlen; /* # elements in msg_iov */ + void *msg_control; /* ancillary data, see below */ + socklen_t msg_controllen; /* ancillary data buffer len */ + int msg_flags; /* flags on received message */ +}; + +#endif + + #define DEFAULT_WR_IOVCNT 16 #if defined(IOV_MAX) && IOV_MAX < DEFAULT_WR_IOVCNT @@ -56,7 +82,11 @@ template struct Memchunk { size_t left() const { return std::end(buf) - last; } void reset() { pos = last = std::begin(buf); } std::array buf; - uint8_t *pos, *last; + + std::_Array_iterator pos; + std::_Array_iterator last; + + // uint8_t *pos, *last; Memchunk *knext; Memchunk *next; static const size_t size = N; @@ -160,7 +190,7 @@ template struct Memchunks { } for (;;) { - auto n = std::min(static_cast(last - first), tail->left()); + auto n = (std::min)(static_cast(last - first), tail->left()); tail->last = std::copy_n(first, n, tail->last); first += n; len += n; @@ -194,7 +224,7 @@ template struct Memchunks { while (m) { auto next = m->next; - auto n = std::min(static_cast(last - first), m->len()); + auto n = (std::min)(static_cast(last - first), m->len()); assert(m->len()); first = std::copy_n(m->pos, n, first); @@ -223,7 +253,7 @@ template struct Memchunks { while (m) { auto next = m->next; - auto n = std::min(left, m->len()); + auto n = (std::min)(left, m->len()); assert(m->len()); dest.append(m->pos, n); @@ -248,7 +278,7 @@ template struct Memchunks { auto m = head; while (m) { auto next = m->next; - auto n = std::min(count, m->len()); + auto n = (std::min)(count, m->len()); m->pos += n; count -= n; len -= n; @@ -362,7 +392,7 @@ template struct PeekMemchunks { auto last = first + count; for (;;) { - auto n = std::min(last - first, cur_last - cur_pos); + auto n = (std::min)(last - first, cur_last - cur_pos); first = std::copy_n(cur_pos, n, first); cur_pos += n; @@ -427,7 +457,7 @@ inline int limit_iovec(struct iovec *iov, int iovcnt, size_t max) { return 0; } for (int i = 0; i < iovcnt; ++i) { - auto d = std::min(max, iov[i].iov_len); + auto d = (std::min)(max, iov[i].iov_len); iov[i].iov_len = d; max -= d; if (max == 0) { @@ -500,23 +530,23 @@ template struct MemchunkBuffer { size_t rleft() const { return chunk->len(); } size_t wleft() const { return chunk->left(); } size_t write(const void *src, size_t count) { - count = std::min(count, wleft()); + count = (std::min)(count, wleft()); auto p = static_cast(src); chunk->last = std::copy_n(p, count, chunk->last); return count; } size_t write(size_t count) { - count = std::min(count, wleft()); + count = (std::min)(count, wleft()); chunk->last += count; return count; } size_t drain(size_t count) { - count = std::min(count, rleft()); + count = (std::min)(count, rleft()); chunk->pos += count; return count; } size_t drain_reset(size_t count) { - count = std::min(count, rleft()); + count = (std::min)(count, rleft()); std::copy(chunk->pos + count, chunk->last, std::begin(chunk->buf)); chunk->last = std::begin(chunk->buf) + (chunk->last - (chunk->pos + count)); chunk->pos = std::begin(chunk->buf); diff --git a/src/network.h b/src/network.h index 3fb765d0..a4105453 100644 --- a/src/network.h +++ b/src/network.h @@ -33,7 +33,15 @@ #ifdef HAVE_SYS_SOCKET_H #include #endif // HAVE_SYS_SOCKET_H +#ifdef WIN32 +#include +#include +#include +#include +#include +#else #include +#endif #ifdef HAVE_NETINET_IN_H #include #endif // HAVE_NETINET_IN_H @@ -48,7 +56,9 @@ union sockaddr_union { sockaddr sa; sockaddr_in6 in6; sockaddr_in in; + #ifndef WIN32 sockaddr_un un; + #endif }; struct Address { diff --git a/src/nghttp.cc b/src/nghttp.cc index 47fc5127..97f87831 100644 --- a/src/nghttp.cc +++ b/src/nghttp.cc @@ -1750,7 +1750,7 @@ namespace { ssize_t select_padding_callback(nghttp2_session *session, const nghttp2_frame *frame, size_t max_payload, void *user_data) { - return std::min(max_payload, frame->hd.length + config.padding); + return (std::min)(max_payload, frame->hd.length + config.padding); } } // namespace @@ -2915,7 +2915,7 @@ int main(int argc, char **argv) { exit(EXIT_FAILURE); } config.header_table_size = n; - config.min_header_table_size = std::min(config.min_header_table_size, n); + config.min_header_table_size = (std::min)(config.min_header_table_size, n); break; } case 'y': diff --git a/src/shrpx_client_handler.cc b/src/shrpx_client_handler.cc index 14900616..4af17b45 100644 --- a/src/shrpx_client_handler.cc +++ b/src/shrpx_client_handler.cc @@ -307,7 +307,7 @@ int ClientHandler::upstream_write() { } int ClientHandler::upstream_http2_connhd_read() { - auto nread = std::min(left_connhd_len_, rb_.rleft()); + auto nread = (std::min)(left_connhd_len_, rb_.rleft()); if (memcmp(NGHTTP2_CLIENT_MAGIC + NGHTTP2_CLIENT_MAGIC_LEN - left_connhd_len_, rb_.pos(), nread) != 0) { // There is no downgrade path here. Just drop the connection. @@ -336,7 +336,7 @@ int ClientHandler::upstream_http2_connhd_read() { } int ClientHandler::upstream_http1_connhd_read() { - auto nread = std::min(left_connhd_len_, rb_.rleft()); + auto nread = (std::min)(left_connhd_len_, rb_.rleft()); if (memcmp(NGHTTP2_CLIENT_MAGIC + NGHTTP2_CLIENT_MAGIC_LEN - left_connhd_len_, rb_.pos(), nread) != 0) { if (LOG_ENABLED(INFO)) { @@ -952,7 +952,7 @@ bool pri_less(const WeightedPri &lhs, const WeightedPri &rhs) { namespace { uint32_t next_cycle(const WeightedPri &pri) { - return pri.cycle + WEIGHT_MAX / std::min(WEIGHT_MAX, pri.weight); + return pri.cycle + WEIGHT_MAX / (std::min)(WEIGHT_MAX, pri.weight); } } // namespace @@ -1296,7 +1296,7 @@ int ClientHandler::proxy_protocol_read() { constexpr size_t MAX_PROXY_LINELEN = 107; - auto bufend = rb_.pos() + std::min(MAX_PROXY_LINELEN, rb_.rleft()); + auto bufend = rb_.pos() + (std::min)(MAX_PROXY_LINELEN, rb_.rleft()); auto end = std::find_first_of(rb_.pos(), bufend, std::begin(chrs), std::end(chrs)); diff --git a/src/shrpx_connect_blocker.cc b/src/shrpx_connect_blocker.cc index e261b815..0b553f8e 100644 --- a/src/shrpx_connect_blocker.cc +++ b/src/shrpx_connect_blocker.cc @@ -82,14 +82,14 @@ void ConnectBlocker::on_failure() { ++fail_count_; auto base_backoff = - util::int_pow(MULTIPLIER, std::min(MAX_BACKOFF_EXP, fail_count_)); + util::int_pow(MULTIPLIER, (std::min)(MAX_BACKOFF_EXP, fail_count_)); auto dist = std::uniform_real_distribution<>(-JITTER * base_backoff, JITTER * base_backoff); auto &downstreamconf = *get_config()->conn.downstream; auto backoff = - std::min(downstreamconf.timeout.max_backoff, base_backoff + dist(gen_)); + (std::min)(downstreamconf.timeout.max_backoff, base_backoff + dist(gen_)); LOG(WARN) << "Could not connect " << fail_count_ << " times in a row; sleep for " << backoff << " seconds"; diff --git a/src/shrpx_connection.cc b/src/shrpx_connection.cc index 06ad9581..6a3a251f 100644 --- a/src/shrpx_connection.cc +++ b/src/shrpx_connection.cc @@ -605,8 +605,8 @@ ssize_t Connection::write_tls(const void *data, size_t len) { // this, we keep last legnth passed to SSL_write to // tls.last_writelen if SSL_write indicated I/O blocking. if (tls.last_writelen == 0) { - len = std::min(len, wlimit.avail()); - len = std::min(len, get_tls_write_limit()); + len = (std::min)(len, wlimit.avail()); + len = (std::min)(len, get_tls_write_limit()); if (len == 0) { return 0; } @@ -662,7 +662,7 @@ ssize_t Connection::read_tls(void *data, size_t len) { // to SSL_read to tls_last_readlen_ if SSL_read indicated I/O // blocking. if (tls.last_readlen == 0) { - len = std::min(len, rlimit.avail()); + len = (std::min)(len, rlimit.avail()); if (len == 0) { return 0; } @@ -705,7 +705,7 @@ ssize_t Connection::read_tls(void *data, size_t len) { } ssize_t Connection::write_clear(const void *data, size_t len) { - len = std::min(len, wlimit.avail()); + len = (std::min)(len, wlimit.avail()); if (len == 0) { return 0; } @@ -759,7 +759,7 @@ ssize_t Connection::writev_clear(struct iovec *iov, int iovcnt) { } ssize_t Connection::read_clear(void *data, size_t len) { - len = std::min(len, rlimit.avail()); + len = (std::min)(len, rlimit.avail()); if (len == 0) { return 0; } @@ -833,7 +833,7 @@ int Connection::get_tcp_hint(TCPHint *hint) const { LOG(INFO) << "writable_size is too small: " << writable_size; } // TODO is this required? - writable_size = std::max(writable_size, static_cast(536 * 2)); + writable_size = (std::max)(writable_size, static_cast(536 * 2)); } // if (LOG_ENABLED(INFO)) { diff --git a/src/shrpx_connection_handler.cc b/src/shrpx_connection_handler.cc index cf078a12..144fb353 100644 --- a/src/shrpx_connection_handler.cc +++ b/src/shrpx_connection_handler.cc @@ -726,7 +726,7 @@ void ConnectionHandler::on_tls_ticket_key_network_error(ev_timer *w) { auto base_backoff = util::int_pow( MULTIPLIER, - std::min(MAX_BACKOFF_EXP, tls_ticket_key_memcached_get_retry_count_)); + (std::min)(MAX_BACKOFF_EXP, tls_ticket_key_memcached_get_retry_count_)); auto dist = std::uniform_real_distribution<>(-JITTER * base_backoff, JITTER * base_backoff); diff --git a/src/shrpx_http.cc b/src/shrpx_http.cc index c7ade2d1..56b2073f 100644 --- a/src/shrpx_http.cc +++ b/src/shrpx_http.cc @@ -161,7 +161,7 @@ std::string colorizeHeaders(const char *hdrs) { ssize_t select_padding_callback(nghttp2_session *session, const nghttp2_frame *frame, size_t max_payload, void *user_data) { - return std::min(max_payload, frame->hd.length + get_config()->padding); + return (std::min)(max_payload, frame->hd.length + get_config()->padding); } } // namespace http diff --git a/src/shrpx_http2_downstream_connection.cc b/src/shrpx_http2_downstream_connection.cc index 9c10f5aa..f2859629 100644 --- a/src/shrpx_http2_downstream_connection.cc +++ b/src/shrpx_http2_downstream_connection.cc @@ -181,7 +181,7 @@ ssize_t http2_data_read_callback(nghttp2_session *session, int32_t stream_id, const auto &req = downstream->request(); auto input = downstream->get_request_buf(); - auto nread = std::min(input->rleft(), length); + auto nread = (std::min)(input->rleft(), length); auto input_empty = input->rleft() == nread; *data_flags |= NGHTTP2_DATA_FLAG_NO_COPY; diff --git a/src/shrpx_http2_upstream.cc b/src/shrpx_http2_upstream.cc index 36b975d1..eba0f660 100644 --- a/src/shrpx_http2_upstream.cc +++ b/src/shrpx_http2_upstream.cc @@ -1032,7 +1032,7 @@ Http2Upstream::Http2Upstream(ClientHandler *handler) faddr->alt_mode ? std::numeric_limits::max() : http2conf.upstream.optimize_window_size - ? std::min(http2conf.upstream.connection_window_size, + ? (std::min)(http2conf.upstream.connection_window_size, NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE) : http2conf.upstream.connection_window_size; @@ -1140,13 +1140,13 @@ int Http2Upstream::on_write() { rv = conn->get_tcp_hint(&hint); if (rv == 0) { if (http2conf.upstream.optimize_write_buffer_size) { - max_buffer_size_ = std::min(MAX_BUFFER_SIZE, hint.write_buffer_size); + max_buffer_size_ = (std::min)(MAX_BUFFER_SIZE, hint.write_buffer_size); } if (http2conf.upstream.optimize_window_size) { auto faddr = handler_->get_upstream_addr(); if (!faddr->alt_mode) { - auto window_size = std::min(http2conf.upstream.connection_window_size, + auto window_size = (std::min)(http2conf.upstream.connection_window_size, static_cast(hint.rwin * 2)); rv = nghttp2_session_set_local_window_size( @@ -1388,21 +1388,21 @@ ssize_t downstream_data_read_callback(nghttp2_session *session, const auto &resp = downstream->response(); - auto nread = std::min(body->rleft(), length); + auto nread = (std::min)(body->rleft(), length); auto max_buffer_size = upstream->get_max_buffer_size(); auto buffer = upstream->get_response_buf(); if (max_buffer_size < - std::min(nread, static_cast(256)) + 9 + buffer->rleft()) { + (std::min)(nread, static_cast(256)) + 9 + buffer->rleft()) { if (LOG_ENABLED(INFO)) { ULOG(INFO, upstream) << "Buffer is almost full. Skip write DATA"; } return NGHTTP2_ERR_PAUSE; } - nread = std::min(nread, max_buffer_size - 9 - buffer->rleft()); + nread = (std::min)(nread, max_buffer_size - 9 - buffer->rleft()); auto body_empty = body->rleft() == nread; diff --git a/src/shrpx_live_check.cc b/src/shrpx_live_check.cc index 863ffa51..a6e8e4dd 100644 --- a/src/shrpx_live_check.cc +++ b/src/shrpx_live_check.cc @@ -174,14 +174,14 @@ constexpr auto JITTER = 0.2; void LiveCheck::schedule() { auto base_backoff = - util::int_pow(MULTIPLIER, std::min(fail_count_, MAX_BACKOFF_EXP)); + util::int_pow(MULTIPLIER, (std::min)(fail_count_, MAX_BACKOFF_EXP)); auto dist = std::uniform_real_distribution<>(-JITTER * base_backoff, JITTER * base_backoff); auto &downstreamconf = *get_config()->conn.downstream; auto backoff = - std::min(downstreamconf.timeout.max_backoff, base_backoff + dist(gen_)); + (std::min)(downstreamconf.timeout.max_backoff, base_backoff + dist(gen_)); ev_timer_set(&backoff_timer_, backoff, 0.); ev_timer_start(conn_.loop, &backoff_timer_); diff --git a/src/shrpx_log.cc b/src/shrpx_log.cc index 19896549..aebdf904 100644 --- a/src/shrpx_log.cc +++ b/src/shrpx_log.cc @@ -155,7 +155,7 @@ Log::~Log() { return; } - auto nwrite = std::min(static_cast(rv), sizeof(buf) - 1); + auto nwrite = (std::min)(static_cast(rv), sizeof(buf) - 1); while (write(lgconf->errorlog_fd, buf, nwrite) == -1 && errno == EINTR) ; @@ -167,7 +167,7 @@ std::pair copy(const char *src, size_t srclen, OutputIterator d_first, OutputIterator d_last) { auto nwrite = - std::min(static_cast(std::distance(d_first, d_last)), srclen); + (std::min)(static_cast(std::distance(d_first, d_last)), srclen); return std::make_pair(std::copy_n(src, nwrite, d_first), d_last); } } // namespace @@ -217,7 +217,7 @@ template std::pair copy_hex_low(const uint8_t *src, size_t srclen, OutputIterator d_first, OutputIterator d_last) { - auto nwrite = std::min(static_cast(std::distance(d_first, d_last)), + auto nwrite = (std::min)(static_cast(std::distance(d_first, d_last)), srclen * 2) / 2; for (size_t i = 0; i < nwrite; ++i) { @@ -312,7 +312,7 @@ copy_escape(const char *src, size_t srclen, OutputIterator d_first, } auto n = - std::min(std::distance(d_first, d_last), std::distance(safe_first, p)); + (std::min)(std::distance(d_first, d_last), std::distance(safe_first, p)); d_first = std::copy_n(safe_first, n, d_first); if (std::distance(d_first, d_last) < 4) { return std::make_pair(d_first, d_last); @@ -324,7 +324,7 @@ copy_escape(const char *src, size_t srclen, OutputIterator d_first, safe_first = p + 1; } - auto n = std::min(std::distance(d_first, d_last), + auto n = (std::min)(std::distance(d_first, d_last), std::distance(safe_first, src + srclen)); return std::make_pair(std::copy_n(safe_first, n, d_first), d_last); } diff --git a/src/shrpx_memcached_connection.cc b/src/shrpx_memcached_connection.cc index d087ac83..2a5e918a 100644 --- a/src/shrpx_memcached_connection.cc +++ b/src/shrpx_memcached_connection.cc @@ -309,7 +309,7 @@ int MemcachedConnection::write_tls() { auto p = std::begin(buf); for (size_t i = 0; i < iovcnt; ++i) { auto &v = iov[i]; - auto n = std::min(static_cast(std::end(buf) - p), v.iov_len); + auto n = (std::min)(static_cast(std::end(buf) - p), v.iov_len); p = std::copy_n(static_cast(v.iov_base), n, p); if (p == std::end(buf)) { break; @@ -506,7 +506,7 @@ int MemcachedConnection::parse_packet() { } case MEMCACHED_PARSE_EXTRA: { // We don't use extra for now. Just read and forget. - auto n = std::min(static_cast(recvbuf_.last - in), + auto n = (std::min)(static_cast(recvbuf_.last - in), parse_state_.read_left); parse_state_.read_left -= n; @@ -524,7 +524,7 @@ int MemcachedConnection::parse_packet() { break; } case MEMCACHED_PARSE_VALUE: { - auto n = std::min(static_cast(recvbuf_.last - in), + auto n = (std::min)(static_cast(recvbuf_.last - in), parse_state_.read_left); parse_state_.value.insert(std::end(parse_state_.value), in, in + n); @@ -636,10 +636,10 @@ void MemcachedConnection::drain_send_queue(size_t nwrite) { continue; } assert(buf.req == req.get()); - auto n = std::min(static_cast(nwrite), buf.headbuf.rleft()); + auto n = (std::min)(static_cast(nwrite), buf.headbuf.rleft()); buf.headbuf.drain(n); nwrite -= n; - n = std::min(static_cast(nwrite), buf.send_value_left); + n = (std::min)(static_cast(nwrite), buf.send_value_left); buf.send_value_left -= n; nwrite -= n; diff --git a/src/shrpx_rate_limit.cc b/src/shrpx_rate_limit.cc index 77a1fe22..79472098 100644 --- a/src/shrpx_rate_limit.cc +++ b/src/shrpx_rate_limit.cc @@ -67,7 +67,7 @@ void RateLimit::drain(size_t n) { if (rate_ == 0) { return; } - n = std::min(avail_, n); + n = (std::min)(avail_, n); avail_ -= n; if (avail_ == 0) { ev_io_stop(loop_, w_); diff --git a/src/shrpx_router.cc b/src/shrpx_router.cc index 82547c20..106665e2 100644 --- a/src/shrpx_router.cc +++ b/src/shrpx_router.cc @@ -94,7 +94,7 @@ size_t Router::add_route(const StringRef &pattern, size_t idx, bool wildcard) { auto slen = pattern.size() - i; auto s = pattern.c_str() + i; - auto n = std::min(node->len, slen); + auto n = (std::min)(node->len, slen); size_t j; for (j = 0; j < n && node->s[j] == s[j]; ++j) ; @@ -177,7 +177,7 @@ const RNode *match_complete(size_t *offset, const RNode *node, node = next_node; - auto n = std::min(node->len, static_cast(last - p)); + auto n = (std::min)(node->len, static_cast(last - p)); if (memcmp(node->s, p, n) != 0) { return nullptr; } @@ -207,7 +207,7 @@ const RNode *match_partial(bool *pattern_is_wildcard, const RNode *node, const RNode *found_node = nullptr; if (offset > 0) { - auto n = std::min(node->len - offset, static_cast(last - first)); + auto n = (std::min)(node->len - offset, static_cast(last - first)); if (memcmp(node->s + offset, first, n) != 0) { return nullptr; } @@ -250,7 +250,7 @@ const RNode *match_partial(bool *pattern_is_wildcard, const RNode *node, node = next_node; - auto n = std::min(node->len, static_cast(last - p)); + auto n = (std::min)(node->len, static_cast(last - p)); if (memcmp(node->s, p, n) != 0) { return found_node; } @@ -349,7 +349,7 @@ const RNode *match_prefix(size_t *nread, const RNode *node, const char *first, node = next_node; - auto n = std::min(node->len, static_cast(last - p)); + auto n = (std::min)(node->len, static_cast(last - p)); if (memcmp(node->s, p, n) != 0) { return nullptr; } diff --git a/src/shrpx_spdy_upstream.cc b/src/shrpx_spdy_upstream.cc index 904d0839..244962d1 100644 --- a/src/shrpx_spdy_upstream.cc +++ b/src/shrpx_spdy_upstream.cc @@ -56,7 +56,7 @@ constexpr size_t MAX_BUFFER_SIZE = 32_k; namespace { int32_t get_connection_window_size() { - return std::max(get_config()->http2.upstream.connection_window_size, + return (std::max)(get_config()->http2.upstream.connection_window_size, static_cast(64_k)); } } // namespace @@ -104,7 +104,7 @@ ssize_t recv_callback(spdylay_session *session, uint8_t *buf, size_t len, return SPDYLAY_ERR_WOULDBLOCK; } - auto nread = std::min(rb->rleft(), len); + auto nread = (std::min)(rb->rleft(), len); memcpy(buf, rb->pos(), nread); rb->drain(nread); @@ -439,7 +439,7 @@ void on_data_chunk_recv_callback(spdylay_session *session, uint8_t flags, // spdy/3), spdylay_session_get_recv_data_length() is always // returns 0. if (spdylay_session_get_recv_data_length(session) > - std::max(SPDYLAY_INITIAL_WINDOW_SIZE, get_connection_window_size())) { + (std::max)(SPDYLAY_INITIAL_WINDOW_SIZE, get_connection_window_size())) { if (LOG_ENABLED(INFO)) { ULOG(INFO, upstream) << "Flow control error on connection: " << "recv_window_size=" @@ -450,7 +450,7 @@ void on_data_chunk_recv_callback(spdylay_session *session, uint8_t flags, return; } if (spdylay_session_get_stream_recv_data_length(session, stream_id) > - std::max(SPDYLAY_INITIAL_WINDOW_SIZE, get_window_size())) { + (std::max)(SPDYLAY_INITIAL_WINDOW_SIZE, get_window_size())) { if (LOG_ENABLED(INFO)) { ULOG(INFO, upstream) << "Flow control error: recv_window_size=" << spdylay_session_get_stream_recv_data_length( diff --git a/src/shrpx_worker_process.cc b/src/shrpx_worker_process.cc index 558029f3..e7b8f0fd 100644 --- a/src/shrpx_worker_process.cc +++ b/src/shrpx_worker_process.cc @@ -232,7 +232,7 @@ void renew_ticket_key_cb(struct ev_loop *loop, ev_timer *w, int revents) { get_config()->tls.session_timeout) .count()); - new_keys.resize(std::min(max_tickets, old_keys.size() + 1)); + new_keys.resize((std::min)(max_tickets, old_keys.size() + 1)); std::copy_n(std::begin(old_keys), new_keys.size() - 1, std::begin(new_keys) + 1); } else { diff --git a/src/util.cc b/src/util.cc index aeaddebb..c156ce6c 100644 --- a/src/util.cc +++ b/src/util.cc @@ -41,7 +41,12 @@ #ifdef HAVE_NETINET_IN_H #include #endif // HAVE_NETINET_IN_H +#ifdef WIN32 +#include +#include +#else #include +#endif #ifdef HAVE_ARPA_INET_H #include #endif // HAVE_ARPA_INET_H @@ -61,6 +66,32 @@ #include "ssl_compat.h" #include "timegm.h" + +#ifdef WIN32 +#include +#include +#include + +extern "C" char* strptime(const char* s, + const char* f, + struct tm* tm) { + // Isn't the C++ standard lib nice? std::get_time is defined such that its + // format parameters are the exact same as strptime. Of course, we have to + // create a string stream first, and imbue it with the current C locale, and + // we also have to make sure we return the right things if it fails, or + // if it succeeds, but this is still far simpler an implementation than any + // of the versions in any of the C standard libraries. + std::istringstream input(s); + input.imbue(std::locale(setlocale(LC_ALL, nullptr))); + input >> std::get_time(tm, f); + if (input.fail()) { + return nullptr; + } + return (char*)(s + input.tellg()); +} +#endif + + namespace nghttp2 { namespace util { @@ -221,9 +252,15 @@ std::string http_date(time_t t) { char *http_date(char *res, time_t t) { struct tm tms; - if (gmtime_r(&t, &tms) == nullptr) { +#ifdef WIN32 + if (gmtime_s( &tms,&t) !=0) { return res; } +#else + if (gmtime_r(&t, &tms) == nullptr) { + return res; + } +#endif auto p = res; @@ -259,9 +296,15 @@ std::string common_log_date(time_t t) { char *common_log_date(char *res, time_t t) { struct tm tms; +#ifdef WIN32 + if (localtime_s(&tms, &t) != 0) { + return res; + } +#else if (localtime_r(&t, &tms) == nullptr) { return res; } +#endif auto p = res; @@ -310,9 +353,16 @@ char *iso8601_date(char *res, int64_t ms) { time_t sec = ms / 1000; tm tms; + +#ifdef WIN32 + if (localtime_s(&tms, &sec) != 0) { + return res; + } +#else if (localtime_r(&sec, &tms) == nullptr) { return res; } +#endif auto p = res; @@ -462,10 +512,10 @@ int levenshtein(const char *a, int alen, const char *b, int blen, int swapcost, dp[0][j] = dp[1][j - 1] + (a[i - 1] == b[j - 1] ? 0 : subcost); if (i >= 2 && j >= 2 && a[i - 1] != b[j - 1] && a[i - 2] == b[j - 1] && a[i - 1] == b[j - 2]) { - dp[0][j] = std::min(dp[0][j], dp[2][j - 2] + swapcost); + dp[0][j] = (std::min)(dp[0][j], dp[2][j - 2] + swapcost); } - dp[0][j] = std::min(dp[0][j], - std::min(dp[1][j] + delcost, dp[0][j - 1] + addcost)); + dp[0][j] = (std::min)(dp[0][j], + (std::min)(dp[1][j] + delcost, dp[0][j - 1] + addcost)); } std::rotate(std::begin(dp), std::begin(dp) + 2, std::end(dp)); } @@ -628,10 +678,13 @@ std::string numeric_name(const struct sockaddr *sa, socklen_t salen) { std::string to_numeric_addr(const Address *addr) { auto family = addr->su.storage.ss_family; + +#ifndef WIN32 if (family == AF_UNIX) { return addr->su.un.sun_path; } - +#endif + std::array host; std::array serv; auto rv = @@ -818,6 +871,11 @@ std::vector parse_config_str_list(const StringRef &s, char delim) { } int make_socket_closeonexec(int fd) { + +#ifdef WIN32 + return 0; +#else + int flags; int rv; while ((flags = fcntl(fd, F_GETFD)) == -1 && errno == EINTR) @@ -825,16 +883,25 @@ int make_socket_closeonexec(int fd) { while ((rv = fcntl(fd, F_SETFD, flags | FD_CLOEXEC)) == -1 && errno == EINTR) ; return rv; +#endif } int make_socket_nonblocking(int fd) { int flags; + +#ifdef WIN32 + u_long non_blk = 1; + return ioctlsocket(fd, FIONBIO, &non_blk); + +#else + int rv; while ((flags = fcntl(fd, F_GETFL, 0)) == -1 && errno == EINTR) ; while ((rv = fcntl(fd, F_SETFL, flags | O_NONBLOCK)) == -1 && errno == EINTR) ; return rv; +#endif } int make_socket_nodelay(int fd) { @@ -874,7 +941,7 @@ int create_nonblock_socket(int family) { bool check_socket_connected(int fd) { int error; socklen_t len = sizeof(error); - if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) != 0) { + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char *)&error, &len) != 0) { return false; } @@ -884,7 +951,7 @@ bool check_socket_connected(int fd) { int get_socket_error(int fd) { int error; socklen_t len = sizeof(error); - if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) != 0) { + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char *)&error, &len) != 0) { return -1; } @@ -904,7 +971,7 @@ std::pair parse_uint_digits(const void *ss, size_t len) { if (len == 0) { return {-1, 0}; } - constexpr int64_t max = std::numeric_limits::max(); + constexpr int64_t max = (std::numeric_limits::max)(); for (i = 0; i < len; ++i) { if ('0' <= s[i] && s[i] <= '9') { if (n > max / 10) { @@ -964,7 +1031,7 @@ int64_t parse_uint_with_unit(const uint8_t *s, size_t len) { default: return -1; } - constexpr int64_t max = std::numeric_limits::max(); + constexpr int64_t max = (std::numeric_limits::max)(); if (n > max / mul) { return -1; } @@ -1003,7 +1070,7 @@ double parse_duration_with_unit(const StringRef &s) { } double parse_duration_with_unit(const uint8_t *s, size_t len) { - constexpr auto max = std::numeric_limits::max(); + constexpr auto max = (std::numeric_limits::max)(); int64_t n; size_t i; @@ -1189,7 +1256,7 @@ StringRef make_hostport(BlockAllocator &balloc, const StringRef &host, namespace { void hexdump8(FILE *out, const uint8_t *first, const uint8_t *last) { - auto stop = std::min(first + 8, last); + auto stop = (std::min)(first + 8, last); for (auto k = first; k != stop; ++k) { fprintf(out, "%02x ", *k); } @@ -1213,7 +1280,7 @@ void hexdump(FILE *out, const uint8_t *src, size_t len) { auto i = src; for (;;) { auto nextlen = - std::min(static_cast(16), static_cast(end - i)); + (std::min)(static_cast(16), static_cast(end - i)); if (nextlen == buflen && std::equal(std::begin(buf), std::begin(buf) + buflen, i)) { // as long as adjacent 16 bytes block are the same, we just @@ -1233,9 +1300,9 @@ void hexdump(FILE *out, const uint8_t *src, size_t len) { } fputs(" ", out); hexdump8(out, i, end); - hexdump8(out, i + 8, std::max(i + 8, end)); + hexdump8(out, i + 8, (std::max)(i + 8, end)); fputc('|', out); - auto stop = std::min(i + 16, end); + auto stop = (std::min)(i + 16, end); buflen = stop - i; auto p = buf.data(); for (; i != stop; ++i) { diff --git a/src/util.h b/src/util.h index 49d0c4b1..db3d35d3 100644 --- a/src/util.h +++ b/src/util.h @@ -30,7 +30,7 @@ #ifdef HAVE_UNISTD_H #include #endif // HAVE_UNISTD_H -#include +#include "getopt.h" #ifdef HAVE_NETDB_H #include #endif // HAVE_NETDB_H