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

No CaptivePortal support? #26

Closed
UnexpectedMaker opened this issue Mar 1, 2020 · 6 comments
Closed

No CaptivePortal support? #26

UnexpectedMaker opened this issue Mar 1, 2020 · 6 comments

Comments

@UnexpectedMaker
Copy link

I've tried everything, but I can't get TinyWeb to serve me a webpage when my DNS is setup for a CaptivePortal.

DNS is set as a wildcard for 192.168.4.1, and I can surf to that page, and see the website, but it doesn't auto load it on connection to the AP.

It works correctly with other web servers (MicroWebSrv2, Sockets server).

Is there something I am missing? Should this be working, or if not, can this be added?

Thanks,
Seon

@UnexpectedMaker
Copy link
Author

The issue here seems to be no ability to do a catch-all route, like I've done before and like what MicroWebSrv2 has, so I added it myself with the following code:

class webserver:
    def __init__(self, request_timeout=3, max_concurrency=3, backlog=16, debug=False, handlenotfound=False):
        """Tiny Web Server class.
        Keyword arguments:
            request_timeout - Time for client to send complete request
                              after that connection will be closed.
            max_concurrency - How many connections can be processed concurrently.
                              It is very important to limit this number because of
                              memory constrain.
                              Default value depends on platform
            backlog         - Parameter to socket.listen() function. Defines size of
                              pending to be accepted connections queue.
                              Must be greater than max_concurrency
            debug           - Whether send exception info (text + backtrace)
                              to client together with HTTP 500 or not.
            handlenotfound  - If True, then if 'find_handler' can't find a matching url, and '/' is in 
                              the dictionary, it will use that instead. If False, it behaves like previous
                              functionality and 'find_hanlder' returns (None,None)
        """

and then in _find_handler

def _find_url_handler(self, req):
        """Helper to find URL handler.
        Returns tuple of (function, opts, param) or (None, None) if not found.
        """
        # First try - lookup in explicit (non parameterized URLs)
        if req.path in self.explicit_url_map:
            return self.explicit_url_map[req.path]
        # Second try - strip last path segment and lookup in another map
        idx = req.path.rfind(b'/') + 1
        path2 = req.path[:idx]
        if len(path2) > 0 and path2 in self.parameterized_url_map:
            # Save parameter into request
            req._param = req.path[idx:].decode()
            return self.parameterized_url_map[path2]
        # No handler found
        if self.handlenotfound and '/'.encode() in self.explicit_url_map:
            return self.explicit_url_map['/'.encode()]
        else:
            return (None, None)

It's not a fantastic solution, so maybe something better can be added to support a "not found" fallback route?

Cheers :)

@belyalov
Copy link
Owner

belyalov commented Mar 3, 2020

Hey! :)

I remember I was able to make captive portal work using tinyweb + tinydns. Since it was awhile back ago and I've switched from python away (to STM32), a few points that may help you:

@belyalov
Copy link
Owner

belyalov commented Mar 3, 2020

So basically solution (apart from DNS part) is to just handle few URLs, like:

    # Add URLs
    web.add_route('/generate_204', captive_portal)
    web.add_route('/hotspot-detect.html', captive_portal)
    web.add_route('/library/test/success.html', captive_portal)

@UnexpectedMaker
Copy link
Author

UnexpectedMaker commented Mar 3, 2020

Ohai!
I didn't know you had tinydns - Excellent.

Yeah, my issue with adding all of the "usual captive portal routes" for the different platforms is that I have no way of testing them other than Mac/iOS based ones, so I was wanting to just do the "catch-all" approach.

Catch all works for me because for this part of the application I can always be assured all traffic is for the captive portal experience.

I have to say though, I've been struggling to work out how to get TinyWeb routes working in my own classes (I'm fairly new to MP and Python in general) - but your open_neopixel_controller just solved that problem for me... it's quite clear from that how to do it now, so BIG THANKS!

@belyalov
Copy link
Owner

belyalov commented Mar 3, 2020

🎉
Cool, you're welcome :)

@belyalov
Copy link
Owner

belyalov commented Mar 4, 2020

Seems you're happy with solution, closing issue - feel free to reopen it :)

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

No branches or pull requests

2 participants