localhost does not work but 127.0.0.1 does

Jan 24, 2015 at 4:16 PM
Hi,
I know there are other posts on this subject but I still cannot resolve my issue. I have written a server application based on the BlackJack sample code (my first Windows App) which works well but due to explicitly using 127.0.0.1 it requires admin privileges to run. This app communicates with a client application over a socket.

If I use 'localhost' the application does not communicate with the client but will at least start without admin privileges.

I have read about modifying the hosts file and IPv4/IPv6 and it didn't make any difference. (My host file is standard Windows 8.1 - all commented out). I don't want to make bespoke changes to my machine as I need a way to distribute my application as an msi to install the software to run without administrator privileges.

I can't get access to the client code so I don't know if 127.0.0.1 has been defined explicitly, but shouldn't it resolve to the same thing?
 int _tmain(void)
{
    utility::string_t port = U("27016");

    utility::string_t address = U("http://127.0.0.1:");
    address.append(port);

    on_initialize(address);
    
    std::cout << "Press ENTER to exit." << std::endl;

    std::string line;
    std::getline(std::cin, line);

    on_shutdown();
    
    return 0;

}
Thanks,

Andy
Jan 26, 2015 at 9:48 AM
Here's my version of this issue.

https://casablanca.codeplex.com/discussions/532385
Marked as answer by roschuma on 1/27/2015 at 5:03 PM
Jan 26, 2015 at 6:48 PM
Hi Andy,

This is an artifact of the fact that we build on top of the Windows HTTP Server API. You can find more details in the discussion thread BSalitia referenced, but administrative privileges are required.

Steve
Jan 27, 2015 at 9:42 PM
Hi Steve & BSalita,

Thank you for your responses.

I had already read the posts and have 127.0.0.1 working (with admin privileges): it's localhost I cannot get working but after re-reading I think I understand.

So just to clarify, to get localhost working, I don't need admin privileges at run time, but I need to add a URL HTTP Namespace reservation during program installation, and register at runtime in the application code.

One thing I don't understand, is that localhost still doesn't work even with admin privileges, whereas 127.0.0.1 does, without any URL HTTP Namespace reservation. Is the namespace reservation required because DNS is used for localhost and not for 127.0.0.1?

This is all quite new to me...

Thanks,

Andy
Feb 1, 2015 at 4:38 PM
Hi,

I am trying to combine C++ REST with registering the URL in my application. I think I am tantalisingly close but cannot get to grips with HttpSetServiceConfiguration and its associated code.

I have based my code on this for the time being: https://github.com/JamesDunne/cpphttp/blob/master/cpphttp/cpphttp.cpp

The error I am getting is that HttpSetServiceConfiguration is returning an invalid parameter error. Can anyone tell me why this might be?

Is this the right way to register a url? I am confused about the code required to register a url in an application, and that to reserve a url during installation.
int _tmain(void)
{
    
    utility::string_t port = U("27016");

    utility::string_t address = U("http://localhost:");
    address.append(port);
    
    //***************************************
    // Attempting to register a url
        //***************************************

    std::wstring url_str = L"http://localhost:27016/";


    HTTPAPI_VERSION apiVersion = HTTPAPI_VERSION_2;
    auto result = HttpInitialize(apiVersion, HTTP_INITIALIZE_SERVER, 0);
    if (NO_ERROR != result) return 0;

    std::cout << "HTTP initialized." << std::endl;

    HANDLE reqQueue = 0;
    result = HttpCreateRequestQueue(apiVersion, NULL, NULL, 0, &reqQueue);
    if (NO_ERROR != result)
    {
        cleanup1();
    }
    std::cout << "HTTP request queue created." << std::endl; 
    

    HTTP_SERVER_SESSION_ID serverSessionId = 0;
    result = HttpCreateServerSession(apiVersion, &serverSessionId, 0);
    if (NO_ERROR != result)
    {
        cleanup2(reqQueue);
        cleanup1();
        return 0;
    }
    std::cout << "HTTP server session created." << std::endl; 
    
    HTTP_URL_GROUP_ID urlGroupId = 0;
    result = HttpCreateUrlGroup(serverSessionId, &urlGroupId, 0);
    if (NO_ERROR != result)
    {
        cleanup3(serverSessionId);
        cleanup2(reqQueue);
        cleanup1();
        return 0; 
    }
    std::cout << "Url group created." << std::endl; 
    
    
    result = HttpAddUrlToUrlGroup(urlGroupId, url_str, NULL, 0);
    if (NO_ERROR != result) 
    {
        cleanup4(urlGroupId);
        cleanup3(serverSessionId);
        cleanup2(reqQueue);
        cleanup1();
        return 0;
    }
    std::cout << "Url added to group." << std::endl; 

    
    //*****************************************

    
    HTTP_SERVICE_CONFIG_IP_LISTEN_PARAM ip_listen_param;
    ip_listen_param.pAddress = (PSOCKADDR)&url_str;
    ip_listen_param.AddrLength = sizeof(url_str);
    result = HttpSetServiceConfiguration(reqQueue, HttpServiceConfigIPListenList, &ip_listen_param, sizeof(HTTP_SERVICE_CONFIG_IP_LISTEN_PARAM), NULL);
    if (NO_ERROR != result)
    {
        switch (result)
        {
            case (ERROR_ALREADY_EXISTS) :
                std::cout << "ERROR_ALREADY_EXISTS" << std::endl;
            break;

            case (ERROR_INSUFFICIENT_BUFFER) :
                std::cout << "ERROR_INSUFFICIENT_BUFFER" << std::endl;
            break;

            case (ERROR_INVALID_HANDLE) :
                std::cout << "ERROR_INVALID_HANDLE" << std::endl;
            break;
            
            case (ERROR_INVALID_PARAMETER) :
                std::cout << "ERROR_INVALID_PARAMETER" << std::endl;
            break;

            case (ERROR_NO_SUCH_LOGON_SESSION) :
                std::cout << "ERROR_NO_SUCH_LOGON_SESSION" << std::endl;
            break;
            
            default:
                std::cout << "Other Error" << std::endl;
            break;

        }
        
        
        std::string line;
        std::getline(std::cin, line);
        
        return 0;
    }

        //********************************
        //carry on with casablanca code
       //********************************

       on_initialize(address);
    
    std::string line;
    std::getline(std::cin, line);

    on_shutdown();
    
    return 0;   
Feb 2, 2015 at 5:50 PM
Hi andy5739,

I'm not sure if this is your problem but quickly looking at the code I don't think you are initializing the HTTP_SERVICE_CONFIG_IP_LISTEN_PARAM correctly. You are trying to cast a pointer to a std::wstring to a PSOCKADDR and then calling sizeof on the std::string, I don't think either of these are correct. Take a look here for the documentation on PSOCKADDR.

Also since your question here is about HttpSetServiceConfiguration, which isn't part of the C++ REST SDK, I recommend you ask on the Windows forum.

Steve
Feb 2, 2015 at 5:50 PM
Hi andy5739,

I'm not sure if this is your problem but quickly looking at the code I don't think you are initializing the HTTP_SERVICE_CONFIG_IP_LISTEN_PARAM correctly. You are trying to cast a pointer to a std::wstring to a PSOCKADDR and then calling sizeof on the std::string, I don't think either of these are correct. Take a look here for the documentation on PSOCKADDR.

Also since your question here is about HttpSetServiceConfiguration, which isn't part of the C++ REST SDK, I recommend you ask on the Windows forum.

Steve
Feb 7, 2015 at 2:59 PM
Hi Steve,

Thanks for your reply. I have taken your advice and posted on the Windows forum. Hopefully anyone coming across this thread can find an answer here:

https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/1096f67a-6893-4554-9875-18e6d3b1d9bd/url-registration-reservation-and-casablanca-c-rest?forum=windowsgeneraldevelopmentissues

I have taken HttpSetServiceConfiguration out as I don't think I need it in the application as it is used for reservations. Instead it will be called in a dll as part of the installation: at least that's my understanding. HttpAddUrlToUrlGroup is what's needed for registration.

Andy
Feb 9, 2015 at 10:12 AM
Hi,

As an update to this thread, I have discovered that my client and server applications, when tested with a third-party software, are working well when set to localhost. When tested together though, the server returns a '400 Bad Request Host Name Invalid'.

I have no idea why this is.

I posted on MSDN and they told me to post here. Can you recommend a place to post a question to help solve my above issue?

Thanks,

Andy

BTW, here is the Wireshark (RawCap) capture of the 400 Bad Request:
GET /poll HTTP/1.1
Referer: app:/Scratch.swf
Accept: text/xml, application/xml, application/xhtml+xml, text/html;q=0.9, text/plain;q=0.8, text/css, image/png, image/jpeg, image/gif;q=0.8, application/x-shockwave-flash, video/mp4;q=0.9, flv-application/octet-stream;q=0.8, video/x-flv;q=0.7, audio/mp4, application/futuresplash, */*;q=0.5, application/x-mpegURL
x-flash-version: 16,0,0,252
Accept-Encoding: gzip,deflate
User-Agent: Mozilla/5.0 (Windows; U; en-US) AppleWebKit/533.19.4 (KHTML, like Gecko) AdobeAIR/16.0
Host: 127.0.0.1:1048
Connection: Keep-Alive

HTTP/1.1 400 Bad Request
Content-Type: text/html; charset=us-ascii
Server: Microsoft-HTTPAPI/2.0
Date: Sun, 08 Feb 2015 23:41:10 GMT
Connection: close
Content-Length: 334

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<HTML><HEAD><TITLE>Bad Request</TITLE>
<META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
<BODY><h2>Bad Request - Invalid Hostname</h2>
<hr><p>HTTP Error 400. The request hostname is invalid.</p>
</BODY></HTML> 
Oct 6, 2015 at 9:49 PM
I did two things to fix this the "invalid hostname issue" for me
1) Changed the address to ----> std::wstring address = U("http://+:62222); // Listen to any host on port 62222, The magic is the //+ thingie 2) run as admin, and make sure you run VS2015 as admin if debugging.