Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTTPClientSession fails with "Connection Refused" on localhost #2226

Closed
werasmus opened this issue Mar 16, 2018 · 9 comments
Closed

HTTPClientSession fails with "Connection Refused" on localhost #2226

werasmus opened this issue Mar 16, 2018 · 9 comments
Labels

Comments

@werasmus
Copy link

werasmus commented Mar 16, 2018

Expected behavior

  • I have code that uses a HTTPClientSession to communicate to a webserver via localhost on windows.
  • When I disable my network, I expect the sending of client requests to still resolve, as I'm communicating on localhost. As an example, chrome can IE can still connect to the endpoint, as well as our java client.

Actual behavior

  • The "sendRequest" call fails with "Connection Refused". This even happens when I create a new client session every time.

Steps to reproduce the problem (from https://ideone.com/CE0R6j)

#include <Poco/Net/HTTPSessionInstantiator.h>
#include <Poco/Net/HTTPRequest.h>
#include <Poco/Net/HTTPClientSession.h>
#include <Poco/Net/HTTPSessionFactory.h>
#include <iostream>
#include <memory>
#include <string>
#include <cstdlib>

using namespace Poco::Net;

namespace {
struct SessionInstantiatorRegistrar
{
    SessionInstantiatorRegistrar()
    {
        HTTPSessionInstantiator::registerInstantiator();
    }
    ~SessionInstantiatorRegistrar()
    {
        HTTPSessionInstantiator::unregisterInstantiator();
    }
};
}//anonymous

int main()
{
    try {
        SessionInstantiatorRegistrar scopedRegistrar;
        //NOTE: Pick any valid endpoint... This is ours...
        HTTPRequest statusRequest(HTTPRequest::HTTP_GET, "/api/v1/tray", HTTPMessage::HTTP_1_1);
        Poco::URI uri("http://localhost:28488");
        std::unique_ptr<HTTPClientSession> clientSession(HTTPSessionFactory::defaultFactory().createClientSession(uri));
        auto& requestStream = clientSession->sendRequest(statusRequest);
        std::cout << "Request successfully sent" << std::endl;
    } catch(const Poco::Exception& ex) {
        std::cerr << ex.displayText() << std::endl;
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

POCO version

Poco 1.7.8: "Host not found"
Poco 1.9.0 "Connection Refused"

Compiler and version

Visual Studio 2017

Operating system and version

< Windows 10

Other relevant information

Using 127.0.0.1

  • inet_addr resolves this normally as IPV4 - No Problem

Using localhost

  • In_addr fails to resolve to IPV4
  • Attempts to resolve as IPV6 by calling getaddrinfo with AI_NUMERICHOST (which shouldn’t work, as localhost is not numeric
  • IpAddress::tryParse therefore fails
  • Poco then try to resolve address by calling hostByName from SocketAddress, but by default hintFlag contains option DNS_HINT_AI_ADDRCONFIG. This will never work, as from windows documentation “The IPv6 and IPv4 loopback address is not considered a valid global address.”.
  • It seems clear that Poco has made this choice deliberately, however that makes it impossible to use a valid loopback hostname.
  • Removing DNS_HINT_AI_ADDRCONFIG from the hint will resolve localhost using getaddrinfo (in our case to IPV6 address first, and IPV4 second - Refer HostEntry constructor in HostEntry.cpp). HostEntry now contains two addresses, the first being IPV6 format
  • In SocketAddress.cpp, init is then only called with the first address (IPv6)
  • connect (further down) is also only called with one IP address (IPv6) and fails with 10061

This SO article might be relevant

@zosrothko
Copy link
Member

Could you try to use the ip address with quad number: 127.0.0.1 instead of localhost...

@werasmus
Copy link
Author

werasmus commented Mar 17, 2018 via email

@zosrothko
Copy link
Member

"localhost" is resolving in a IPV6 address, that's why the dotted ip address works

@werasmus werasmus changed the title HTTPClientSession fails with "Host Not Found" on localhost HTTPClientSession fails with "Connection Refused" on localhost Mar 19, 2018
@budric
Copy link

budric commented Apr 4, 2018

I ran into this issue with version 1.8.1. I have a server and it was only listening on IPv4 address. The DNS for FQDN of the server returns 2 entries, IPv6 followed by IPv4. Poco's HTTPClientSession seems to try only the first address which happens to be IPv6, throws connection refused error (which is true) and that's it.

I have not run into the same problem with other clients like curl/chrome/firefox/ie - either by chance (maybe host lookup in those cases always gets IPv4 address first) or intentionally going through through every address, these clients always reach the server.

My question is, is this considered a bug in Poco? Should Poco HTTPClientSession try all addresses returned by DNS before declaring connection refused?

@werasmus
Copy link
Author

werasmus commented Apr 4, 2018 via email

@zosrothko
Copy link
Member

The is a know problem. One solution could be to use a global variable stating which should go in first in the DNS list, either IPV4 or IPV6, defaulted to IPV6. See #1871

@Bittuw
Copy link

Bittuw commented Aug 1, 2018

Is there a correct solution of this problem?

@RaBa64
Copy link

RaBa64 commented Jan 27, 2019

In /etc/hosts, I changed the line
::1 localhost ip6-localhost ip6-loopback
to
::1 ip6-localhost ip6-loopback
Now it works.

@github-actions
Copy link

This issue is stale because it has been open for 365 days with no activity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants