https_server.py
def retrieve_http_req(sock, message_queues, sock_to_ja3, poller):
    """Attempts to process incoming bytes and get the HTTP GET request.

    Reads input from the given socket and if it sees a GET request, it parses
    the User-Agent string for browser metadata.

    Arguments:
        sock (:obj: `socket`) socket object to process any incoming bytes on
        message_queues (:obj: `queue.queue`) standard queue for outgoing messages
        sock_to_ja3 (:obj: `dict`) Dictionary mapping socket object to ja3 fingerprints
        poller (:obj: `select.poll`) polling object from the select module for
            concurrent socket IO.

    Returns:
        bool: True on successful GET request, False otherwise and on error
    """

    # hopefully get the GET request here for UA string processing
    try:
        init_request = sock.recv(2048)
    except BlockingIOError as err:
        _LOGGER.warning("Nothing to read")
        return False

    except ConnectionResetError as err:
        _LOGGER.warning("Connection reset: %s", err)
        return False

    # data exists from the previous read
    if init_request:
        try:
            # it's a GET request
            if b"GET" in init_request:
                _LOGGER.debug(init_request)
                ua_str = extract_ua_str(init_request)
                browser_name = "Unknown"
                browser_version = "Unknown"

                # it could extract the UA section of the header
                if ua_str != b"Unknown":
                    # real quick check for any headless browser(s)
                    found_headless = \
                        check_for_headless_browsers(ua_str.decode("utf-8"))

                    # it got a hit from a headless browser
                    if found_headless is not None:
                        _LOGGER.debug("Detected headless")
                        # splits and extracts name/version
                        headless_info = found_headless.split("/")
                        browser_name = headless_info[0]
                        browser_version = headless_info[1]

                    else:
                        # need to decode utf-8 because the agent
                        # parser requires a str input
                        parsed_ua = httpagentparser.detect(ua_str.decode("utf-8"))
                        browser = parsed_ua.get("browser", None)
                        # the UA parser was able to
                        # successfully extract a browser
                        if browser is not None:
                            browser_name = parsed_ua["browser"].get("name", None)
                            browser_version = \
                                parsed_ua["browser"].get("version", None)

                # grab the ja3 associated with the socket
                ja3_digest = sock_to_ja3[sock]
                browser_info = [ja3_digest, browser_name, \
                        browser_version, \
                        ua_str.decode("utf-8")]

                _LOGGER.info(browser_info)

                # real quick edge case if we can't parse the UA
                # string properly, it won't crash the server
                b_name = b""
                b_version = b""

                if browser_name is not None:
                    b_name = browser_name.encode("utf-8")
                if browser_version is not None:
                    b_version = browser_version.encode("utf-8")

                reply = b"HTTP/1.1 200 OK\r\n" \
                        +b"Content-Type: text/html\r\n" \
                        +b"\r\n" \
                        +b"<html><h1>%b</h1><h1>%b</h1><h1>%b</h1></html>" % \
                        (ja3_digest.encode("utf-8"), b_name, b_version)

                # add the message reply to the queue
                message_queues[sock].put(reply)
                # tell the poller we ready to send it
                poller.modify(sock, READ_WRITE)

                return True

        except (OSError, NameError)  as err:
            # this needs to be warning because these errors are
            # always expected to happen
            # don't want this printing out every time
            _LOGGER.warning(err)
            return False

    _LOGGER.warning("Nothing Read")
    return False
Attempts to process incoming bytes and get the HTTP GET request.

    Reads input from the given socket and if it sees a GET request, it parses
    the User-Agent string for browser metadata.

    Arguments:
        sock (:obj: `socket`) socket object to process any incoming bytes on
        message_queues (:obj: `queue.queue`) standard queue for outgoing messages
        sock_to_ja3 (:obj: `dict`) Dictionary mapping socket object to ja3 fingerprints
        poller (:obj: `select.poll`) polling object from the select module for
            concurrent socket IO.

    Returns:
        bool: True on successful GET request, False otherwise and on error
    
Attempts to process incoming bytes and get the HTTP GET request.
Reads input from the given socket and if it sees a GET request, it parses
the User-Agent string for browser metadata.
Attempts to process incoming bytes and get the HTTP GET request . Reads input from the given socket and if it sees a GET request it parses the User - Agent string for browser metadata .
def retrieve_http_req(sock, message_queues, sock_to_ja3, poller):
    try:
        init_request = sock.recv(2048)
    except BlockingIOError as err:
        _LOGGER.warning("Nothing to read")
        return False
    except ConnectionResetError as err:
        _LOGGER.warning("Connection reset: %s", err)
        return False
    if init_request:
        try:
            if b"GET" in init_request:
                _LOGGER.debug(init_request)
                ua_str = extract_ua_str(init_request)
                browser_name = "Unknown"
                browser_version = "Unknown"
                if ua_str != b"Unknown":
                    found_headless = \
                        check_for_headless_browsers(ua_str.decode("utf-8"))
                    if found_headless is not None:
                        _LOGGER.debug("Detected headless")
                        headless_info = found_headless.split("/")
                        browser_name = headless_info[0]
                        browser_version = headless_info[1]
                    else:
                        parsed_ua = httpagentparser.detect(ua_str.decode("utf-8"))
                        browser = parsed_ua.get("browser", None)
                        if browser is not None:
                            browser_name = parsed_ua["browser"].get("name", None)
                            browser_version = \
                                parsed_ua["browser"].get("version", None)
                ja3_digest = sock_to_ja3[sock]
                browser_info = [ja3_digest, browser_name, \
                        browser_version, \
                        ua_str.decode("utf-8")]
                _LOGGER.info(browser_info)
                b_name = b""
                b_version = b""
                if browser_name is not None:
                    b_name = browser_name.encode("utf-8")
                if browser_version is not None:
                    b_version = browser_version.encode("utf-8")
                reply = b"HTTP/1.1 200 OK\r\n" \
                        +b"Content-Type: text/html\r\n" \
                        +b"\r\n" \
                        +b"<html><h1>%b</h1><h1>%b</h1><h1>%b</h1></html>" % \
                        (ja3_digest.encode("utf-8"), b_name, b_version)
                message_queues[sock].put(reply)
                poller.modify(sock, READ_WRITE)
                return True
        except (OSError, NameError)  as err:
            _LOGGER.warning(err)
            return False
    _LOGGER.warning("Nothing Read")
    return False
def retrieve_http_req ( sock , message_queues , sock_to_ja3 , poller ) : try : init_request = sock . recv ( 2048 ) except BlockingIOError as err : _LOGGER . warning ( "Nothing to read" ) return False except ConnectionResetError as err : _LOGGER . warning ( "Connection reset: %s" , err ) return False if init_request : try : if b"GET" in init_request : _LOGGER . debug ( init_request ) ua_str = extract_ua_str ( init_request ) browser_name = "Unknown" browser_version = "Unknown" if ua_str != b"Unknown" : found_headless = check_for_headless_browsers ( ua_str . decode ( "utf-8" ) ) if found_headless is not None : _LOGGER . debug ( "Detected headless" ) headless_info = found_headless . split ( "/" ) browser_name = headless_info [ 0 ] browser_version = headless_info [ 1 ] else : parsed_ua = httpagentparser . detect ( ua_str . decode ( "utf-8" ) ) browser = parsed_ua . get ( "browser" , None ) if browser is not None : browser_name = parsed_ua [ "browser" ] . get ( "name" , None ) browser_version = parsed_ua [ "browser" ] . get ( "version" , None ) ja3_digest = sock_to_ja3 [ sock ] browser_info = [ ja3_digest , browser_name , browser_version , ua_str . decode ( "utf-8" ) ] _LOGGER . info ( browser_info ) b_name = b"" b_version = b"" if browser_name is not None : b_name = browser_name . encode ( "utf-8" ) if browser_version is not None : b_version = browser_version . encode ( "utf-8" ) reply = b"HTTP/1.1 200 OK\r\n" + b"Content-Type: text/html\r\n" + b"\r\n" + b"<html><h1>%b</h1><h1>%b</h1><h1>%b</h1></html>" % ( ja3_digest . encode ( "utf-8" ) , b_name , b_version ) message_queues [ sock ] . put ( reply ) poller . modify ( sock , READ_WRITE ) return True except ( OSError , NameError ) as err : _LOGGER . warning ( err ) return False _LOGGER . warning ( "Nothing Read" ) return False
Attempts to process incoming bytes and get the HTTP GET request.
Attempts to process incoming bytes and get the HTTP GET request .
"""Attempts to process incoming bytes and get the HTTP GET request.

    Reads input from the given socket and if it sees a GET request, it parses
    the User-Agent string for browser metadata.

    Arguments:
        sock (:obj: `socket`) socket object to process any incoming bytes on
        message_queues (:obj: `queue.queue`) standard queue for outgoing messages
        sock_to_ja3 (:obj: `dict`) Dictionary mapping socket object to ja3 fingerprints
        poller (:obj: `select.poll`) polling object from the select module for
            concurrent socket IO.

    Returns:
        bool: True on successful GET request, False otherwise and on error
    """ # hopefully get the GET request here for UA string processing # data exists from the previous read # it's a GET request # it could extract the UA section of the header # real quick check for any headless browser(s) # it got a hit from a headless browser # splits and extracts name/version # need to decode utf-8 because the agent # parser requires a str input # the UA parser was able to # successfully extract a browser # grab the ja3 associated with the socket # real quick edge case if we can't parse the UA # string properly, it won't crash the server # add the message reply to the queue # tell the poller we ready to send it # this needs to be warning because these errors are # always expected to happen # don't want this printing out every time
True on successful GET request, False otherwise and on error
True on successful GET request False otherwise and on error
bool
sock
message_queues
sock_to_ja3
poller
sock (
`socket`) socket object to process any incoming bytes on
` socket ` ) socket object to process any incoming bytes on
message_queues (
None
sock_to_ja3 (
`dict`) Dictionary mapping socket object to ja3 fingerprints
` dict ` ) Dictionary mapping socket object to ja3 fingerprints
poller (
`select.poll`) polling object from the select module for
concurrent socket IO.
` select . poll ` ) polling object from the select module for concurrent socket IO .