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

Why is an HTTP callback required if I only want a WebSocket server in hs.httpserver? #3468

Closed
danielo515 opened this issue Apr 20, 2023 · 3 comments · Fixed by #3665
Closed
Assignees
Labels

Comments

@danielo515
Copy link

Hello,

I'm using Hammerspoon to create a simple WebSocket server using the hs.httpserver module. However, I noticed that the module requires an HTTP callback function to be set, even if I'm only interested in WebSocket functionality.

Is there a specific reason for this requirement? I would expect that, since WebSocket and HTTP are separate protocols, it would be possible to set up a WebSocket server without having to provide a callback for normal HTTP requests.

Could you please clarify this requirement or consider updating the module to allow for WebSocket-only servers without the need for an HTTP callback?

Thank you for your time and assistance.

Best regards

@danielo515
Copy link
Author

Any answer to this?

@latenitefilms
Copy link
Contributor

Apologies for the lack of a response here!

I've just had a quick look into this - it looks like we need to tweak hs.httpserver:start().

Here's the current code:

/// hs.httpserver:start() -> object
/// Method
/// Starts an HTTP server object
///
/// Parameters:
///  * None
///
/// Returns:
///  * The `hs.httpserver` object
static int httpserver_start(lua_State *L) {
    LuaSkin *skin = [LuaSkin sharedWithState:L];
    HSHTTPServer *server = getUserData(L, 1);

    if (server.fn == LUA_NOREF) {
        [skin logError:@"hs.httpserver:start() called with no callback set. You must call hs.httpserver:setCallback() first"];
    } else {
        NSError *error = nil;
        if (![server start:&error]) {
            [skin logError:[NSString stringWithFormat:@"hs.httpserver:start() Unable to start object: %@", error]];
        }
    }

    lua_pushvalue(L, 1);
    return 1;
}

I believe we just need to change it to:

static int httpserver_start(lua_State *L) {
    LuaSkin *skin = [LuaSkin sharedWithState:L];
    HSHTTPServer *server = getUserData(L, 1);

    if (server.wsCallback != LUA_NOREF) {
        NSError *error = nil;
        if (![server start:&error]) {
            [skin logError:[NSString stringWithFormat:@"hs.httpserver:start() Unable to start object: %@", error]];
        }
    else if (server.fn == LUA_NOREF) {
        [skin logError:@"hs.httpserver:start() called with no callback set. You must call hs.httpserver:setCallback() first"];
    } else {
        NSError *error = nil;
        if (![server start:&error]) {
            [skin logError:[NSString stringWithFormat:@"hs.httpserver:start() Unable to start object: %@", error]];
        }
    }

    lua_pushvalue(L, 1);
    return 1;
}

To test, we can use this Lua code:

websocketCallback = function(message) 
    print(string.format("message: %s", message)) 
end

callback = function(requestType, path, headers, raw)
    print(string.format("requestType: %s", requestType))
    print(string.format("path: %s", path))
    print(string.format("headers: %s", hs.inspect(headers)))
    print(string.format("raw: %s", raw))
end

server = hs.httpserver.new()
server:setName("hs")
server:setPort(64312)

-- Deliberately not set a callback:
--server:setCallback(callback) 

server:websocket("/hs", websocketCallback)
server:start()

As a client we can install this:

brew install websocat

...and then use:

echo "Hello Hammerspoon" | websocat ws://127.0.0.1:64312/hs

I'll make a pull request.

@danielo515
Copy link
Author

Apologies for the lack of a response here!

No worries

cmsj pushed a commit that referenced this issue Nov 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants