0

I am currently trying to implement a REST interface with casablanca but I keep getting "Error adding url to url group". And I don't really know how to fix that. Here is my main method:

    int main(int argc, char* argv[])
{
    InterruptHandler::hookSIGINT();

    Server server;
    server.setEndpoint(L"http", 41004, L"/api/v1");

    try {
        // wait for server initialization...
        server.accept().wait();
        std::wcout << L"Modern C++ Server now listening for requests at: " << server.endpoint() << '\n';

        InterruptHandler::waitForUserInterrupt();

        server.shutdown().wait();
    }
    catch (std::exception & e) {
        std::cerr << e.what() << '\n'; //this is returning "Error adding url to url group"
    }

    system("pause");
}

I am now trying to figure out where the problem could be but I didn't get far. I am setting the Endpoint and creating the http_listener like this (Server class extends BaseController):

void BaseController::setEndpoint(const std::wstring &scheme, const int port, const std::wstring &path) {
        uri_builder endpointBuilder;

        endpointBuilder.set_scheme(scheme);
        endpointBuilder.set_host(L"0.0.0.0");
        endpointBuilder.set_port(port); //41004
        endpointBuilder.set_path(path);

        _listener = http_listener(endpointBuilder.to_uri());
    }

When the Server accepts, the supporting methods are being set on the listener

void Server::initRestOpHandlers() {
    _listener.support(methods::GET, std::bind(&Server::handleGet, this, std::placeholders::_1));
    _listener.support(methods::POST, std::bind(&Server::handlePost, this, std::placeholders::_1));
}

The exception is thrown in the http_listener.cpp open() method:

pplx::task<void> details::http_listener_impl::open()
{
    // Do nothing if the open operation was already attempted
    // Not thread safe
    if (!m_closed) return pplx::task_from_result();

    if ( m_uri.is_empty() )
        throw std::invalid_argument("No URI defined for listener.");
    m_closed = false;

    return web::http::experimental::details::http_server_api::register_listener(this).then([this](pplx::task<void> openOp)
    {
        try
        {
            // If failed to open need to mark as closed.
            openOp.wait();
        }
        catch(...)
        {
            m_closed = true;
            throw;
        }
        return openOp;
    });
}

I can't find any help elsewhere and I can't seem to figure out why it fails to open. Any help would be appreciated! Thanks.

Salocin
  • 3
  • 4

2 Answers2

0

ok I was able to solve it myself... I had to use 127.0.0.1 for the host in my BaseController

Salocin
  • 3
  • 4
0

For Windows,you have another option that requires two steps.

1) Change the URI that you are listening to http://*:41004

2) Add an application manifest to the application you are building that requests admin privileges when the program runs.

In Visual Studio, you need to add a post build step settings of the project. Assume you have application called "MyApplication.exe"

"mt.exe" -manifest \"MyApplication.exe.manifest\" -outputresource:"$(TargetDir)$(TargetFileName)"\;\#1

The manifest file would be named "MyApplication.exe.manifest" and would contain the following contents:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 
  <assemblyIdentity version="1.0.0.0"
     name="MyApplication"
     type="win32"/> 
  <description>My Application</description> 
  <!-- Identify the application security requirements. -->
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="requireAdministrator" uiAccess="false">
          </requestedExecutionLevel>
        </requestedPrivileges>
        <applicationRequestMinimum>
            <defaultAssemblyRequest permissionSetReference="FullTrust" />
            <PermissionSet version="1" ID="FullTrust" Unrestricted="true" />
        </applicationRequestMinimum>
       </security>
  </trustInfo>
</assembly>

The RC file for MyApplication.exe must also point to the manifest file by having in the file.

#define MANIFEST_RESOURCE_ID 1
MANIFEST_RESOURCE_ID RT_MANIFEST "MyApplication.exe.manifest"

More about application manifests can be found here: https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests

Eldon
  • 1
  • 1