393 |
393 |
const std::string &address,
|
394 |
394 |
Wt::AsioWrapper::error_code &errc)
|
395 |
395 |
{
|
396 |
|
tcp_listeners_.push_back(TcpListener(asio::ip::tcp::acceptor(wt_.ioService()), TcpConnectionPtr()));
|
397 |
|
asio::ip::tcp::acceptor &tcp_acceptor = tcp_listeners_.back().acceptor;
|
|
396 |
tcp_listeners_.push_back(std::make_shared<TcpListener>(asio::ip::tcp::acceptor(wt_.ioService()), TcpConnectionPtr()));
|
|
397 |
asio::ip::tcp::acceptor &tcp_acceptor = tcp_listeners_.back()->acceptor;
|
398 |
398 |
tcp_acceptor.open(endpoint.protocol());
|
399 |
399 |
tcp_acceptor.set_option(asio::ip::tcp::acceptor::reuse_address(true));
|
400 |
400 |
#ifndef WT_WIN32
|
... | ... | |
406 |
406 |
|
407 |
407 |
LOG_INFO_S(&wt_, "started server: " << addressString("http", endpoint, address));
|
408 |
408 |
|
409 |
|
tcp_listeners_.back().new_connection.reset
|
|
409 |
tcp_listeners_.back()->new_connection.reset
|
410 |
410 |
(new TcpConnection(wt_.ioService(), this, connection_manager_,
|
411 |
411 |
request_handler_));
|
412 |
412 |
} else {
|
... | ... | |
450 |
450 |
const std::string &address,
|
451 |
451 |
Wt::AsioWrapper::error_code &errc)
|
452 |
452 |
{
|
453 |
|
ssl_listeners_.push_back(SslListener(asio::ip::tcp::acceptor(wt_.ioService()), SslConnectionPtr()));
|
454 |
|
asio::ip::tcp::acceptor &ssl_acceptor = ssl_listeners_.back().acceptor;
|
|
453 |
ssl_listeners_.push_back(std::make_shared<SslListener>(asio::ip::tcp::acceptor(wt_.ioService()), SslConnectionPtr()));
|
|
454 |
asio::ip::tcp::acceptor &ssl_acceptor = ssl_listeners_.back()->acceptor;
|
455 |
455 |
ssl_acceptor.open(endpoint.protocol());
|
456 |
456 |
ssl_acceptor.set_option(asio::ip::tcp::acceptor::reuse_address(true));
|
457 |
457 |
#ifndef WT_WIN32
|
... | ... | |
463 |
463 |
|
464 |
464 |
LOG_INFO_S(&wt_, "started server: " << addressString("https", endpoint, address));
|
465 |
465 |
|
466 |
|
ssl_listeners_.back().new_connection.reset
|
|
466 |
ssl_listeners_.back()->new_connection.reset
|
467 |
467 |
(new SslConnection(wt_.ioService(), this, ssl_context_, connection_manager_,
|
468 |
468 |
request_handler_));
|
469 |
469 |
} else {
|
... | ... | |
481 |
481 |
if (ssl_listeners_.empty())
|
482 |
482 |
return -1;
|
483 |
483 |
else
|
484 |
|
return ssl_listeners_.front().acceptor.local_endpoint().port();
|
|
484 |
return ssl_listeners_.front()->acceptor.local_endpoint().port();
|
485 |
485 |
#else // HTTP_WITH_SSL
|
486 |
486 |
return -1;
|
487 |
487 |
#endif // HTTP_WITH_SSL
|
488 |
488 |
}
|
489 |
489 |
|
490 |
|
return tcp_listeners_.front().acceptor.local_endpoint().port();
|
|
490 |
return tcp_listeners_.front()->acceptor.local_endpoint().port();
|
491 |
491 |
}
|
492 |
492 |
|
493 |
493 |
void Server::startAccept()
|
... | ... | |
502 |
502 |
* need to access the ConnectionManager mutex in any case).
|
503 |
503 |
*/
|
504 |
504 |
for (std::size_t i = 0; i < tcp_listeners_.size(); ++i) {
|
505 |
|
asio::ip::tcp::acceptor &acceptor = tcp_listeners_[i].acceptor;
|
506 |
|
TcpConnectionPtr &new_connection = tcp_listeners_[i].new_connection;
|
|
505 |
asio::ip::tcp::acceptor &acceptor = tcp_listeners_[i]->acceptor;
|
|
506 |
TcpConnectionPtr &new_connection = tcp_listeners_[i]->new_connection;
|
507 |
507 |
acceptor.async_accept(new_connection->socket(),
|
508 |
508 |
accept_strand_.wrap(
|
509 |
509 |
std::bind(&Server::handleTcpAccept, this,
|
510 |
|
&tcp_listeners_[i],
|
|
510 |
tcp_listeners_[i],
|
511 |
511 |
std::placeholders::_1)));
|
512 |
512 |
}
|
513 |
513 |
|
514 |
514 |
#ifdef HTTP_WITH_SSL
|
515 |
515 |
for (std::size_t i = 0; i < ssl_listeners_.size(); ++i) {
|
516 |
|
asio::ip::tcp::acceptor &acceptor = ssl_listeners_[i].acceptor;
|
517 |
|
SslConnectionPtr &new_connection = ssl_listeners_[i].new_connection;
|
|
516 |
asio::ip::tcp::acceptor &acceptor = ssl_listeners_[i]->acceptor;
|
|
517 |
SslConnectionPtr &new_connection = ssl_listeners_[i]->new_connection;
|
518 |
518 |
acceptor.async_accept(new_connection->socket(),
|
519 |
519 |
accept_strand_.wrap(
|
520 |
520 |
std::bind(&Server::handleSslAccept, this,
|
521 |
|
&ssl_listeners_[i],
|
|
521 |
ssl_listeners_[i],
|
522 |
522 |
std::placeholders::_1)));
|
523 |
523 |
}
|
524 |
524 |
#endif // HTTP_WITH_SSL
|
... | ... | |
539 |
539 |
if (!err) {
|
540 |
540 |
// tcp_listeners_.front() should be fine here:
|
541 |
541 |
// it should be the only acceptor when this is a session process
|
542 |
|
auto port = tcp_listeners_.front().acceptor.local_endpoint().port();
|
|
542 |
auto port = tcp_listeners_.front()->acceptor.local_endpoint().port();
|
543 |
543 |
Wt::WStringStream ss;
|
544 |
544 |
ss << "port:" << port << "\n";
|
545 |
545 |
auto buf = std::make_shared<std::string>(ss.str());
|
... | ... | |
595 |
595 |
void Server::handleResume()
|
596 |
596 |
{
|
597 |
597 |
for (std::size_t i = 0; i < tcp_listeners_.size(); ++i)
|
598 |
|
tcp_listeners_[i].acceptor.close();
|
|
598 |
tcp_listeners_[i]->acceptor.close();
|
599 |
599 |
tcp_listeners_.clear();
|
600 |
600 |
|
601 |
601 |
#ifdef HTTP_WITH_SSL
|
602 |
602 |
for (std::size_t i = 0; i < ssl_listeners_.size(); ++i)
|
603 |
|
ssl_listeners_[i].acceptor.close();
|
|
603 |
ssl_listeners_[i]->acceptor.close();
|
604 |
604 |
ssl_listeners_.clear();
|
605 |
605 |
#endif // HTTP_WITH_SSL
|
606 |
606 |
|
607 |
607 |
start();
|
608 |
608 |
}
|
609 |
609 |
|
610 |
|
void Server::handleTcpAccept(TcpListener *listener, const Wt::AsioWrapper::error_code& e)
|
|
610 |
void Server::handleTcpAccept(const std::weak_ptr<TcpListener>& listener,
|
|
611 |
const Wt::AsioWrapper::error_code& e)
|
611 |
612 |
{
|
612 |
|
if (!e) {
|
613 |
|
connection_manager_.start(listener->new_connection);
|
614 |
|
listener->new_connection.reset(new TcpConnection(wt_.ioService(), this,
|
615 |
|
connection_manager_, request_handler_));
|
616 |
|
} else if (!listener->acceptor.is_open()) {
|
|
613 |
auto l = listener.lock();
|
|
614 |
if (!l || (e && !l->acceptor.is_open())) {
|
617 |
615 |
// server shutdown
|
618 |
|
LOG_DEBUG("handleTcpAccept: async_accept error (acceptor closed, probably server shutdown): " << e.message());
|
|
616 |
LOG_DEBUG("handleTcpAccept: async_accept error (no listener, probably server shutdown): " << e.message());
|
619 |
617 |
return;
|
|
618 |
}
|
|
619 |
|
|
620 |
if (!e) {
|
|
621 |
connection_manager_.start(l->new_connection);
|
|
622 |
l->new_connection.reset(new TcpConnection(wt_.ioService(), this,
|
|
623 |
connection_manager_, request_handler_));
|
620 |
624 |
} else {
|
621 |
625 |
LOG_ERROR("handleTcpAccept: async_accept error: " << e.message());
|
622 |
626 |
}
|
623 |
627 |
|
624 |
|
listener->acceptor.async_accept(listener->new_connection->socket(),
|
625 |
|
accept_strand_.wrap(
|
626 |
|
std::bind(&Server::handleTcpAccept, this,
|
627 |
|
listener, std::placeholders::_1)));
|
|
628 |
l->acceptor.async_accept(l->new_connection->socket(),
|
|
629 |
accept_strand_.wrap(
|
|
630 |
std::bind(&Server::handleTcpAccept, this,
|
|
631 |
listener, std::placeholders::_1)));
|
628 |
632 |
}
|
629 |
633 |
|
630 |
634 |
#ifdef HTTP_WITH_SSL
|
631 |
|
void Server::handleSslAccept(SslListener *listener, const Wt::AsioWrapper::error_code& e)
|
|
635 |
void Server::handleSslAccept(const std::weak_ptr<SslListener>& listener,
|
|
636 |
const Wt::AsioWrapper::error_code& e)
|
632 |
637 |
{
|
633 |
|
if (!e) {
|
634 |
|
connection_manager_.start(listener->new_connection);
|
635 |
|
listener->new_connection.reset(new SslConnection(wt_.ioService(), this,
|
636 |
|
ssl_context_, connection_manager_, request_handler_));
|
637 |
|
} else if (!listener->acceptor.is_open()) {
|
|
638 |
auto l = listener.lock();
|
|
639 |
if (!l || (e && !l->acceptor.is_open())) {
|
638 |
640 |
// server shutdown
|
639 |
|
LOG_DEBUG("handleSslAccept: async_accept error (acceptor closed, probably server shutdown): " << e.message());
|
|
641 |
LOG_DEBUG("handleSslAccept: async_accept error (no listener, probably server shutdown): " << e.message());
|
640 |
642 |
return;
|
|
643 |
}
|
|
644 |
|
|
645 |
if (!e) {
|
|
646 |
connection_manager_.start(l->new_connection);
|
|
647 |
l->new_connection.reset(new SslConnection(wt_.ioService(), this,
|
|
648 |
ssl_context_, connection_manager_, request_handler_));
|
641 |
649 |
} else {
|
642 |
650 |
LOG_ERROR("handleSslAccept: async_accept error: " << e.message());
|
643 |
651 |
}
|
644 |
652 |
|
645 |
|
listener->acceptor.async_accept(listener->new_connection->socket(),
|
646 |
|
accept_strand_.wrap(
|
647 |
|
std::bind(&Server::handleSslAccept, this,
|
648 |
|
listener, std::placeholders::_1)));
|
|
653 |
l->acceptor.async_accept(l->new_connection->socket(),
|
|
654 |
accept_strand_.wrap(
|
|
655 |
std::bind(&Server::handleSslAccept, this,
|
|
656 |
listener, std::placeholders::_1)));
|
649 |
657 |
}
|
650 |
658 |
#endif // HTTP_WITH_SSL
|
651 |
659 |
|
... | ... | |
663 |
671 |
// operations. Once all operations have finished the io_service::run() call
|
664 |
672 |
// will exit.
|
665 |
673 |
for (std::size_t i = 0; i < tcp_listeners_.size(); ++i)
|
666 |
|
tcp_listeners_[i].acceptor.close();
|
|
674 |
tcp_listeners_[i]->acceptor.close();
|
667 |
675 |
tcp_listeners_.clear();
|
668 |
676 |
|
669 |
677 |
#ifdef HTTP_WITH_SSL
|
670 |
678 |
for (std::size_t i = 0; i < ssl_listeners_.size(); ++i)
|
671 |
|
ssl_listeners_[i].acceptor.close();
|
|
679 |
ssl_listeners_[i]->acceptor.close();
|
672 |
680 |
ssl_listeners_.clear();
|
673 |
681 |
#endif // HTTP_WITH_SSL
|
674 |
682 |
|