# The software in this package is distributed under the GNU General # Public License version 2 (with a special exception described below). # # A copy of GNU General Public License (GPL) is included in this distribution, # in the file COPYING.GPL. # # As a special exception, if other files instantiate templates or use macros # or inline functions from this file, or you compile this file and link it # with other works to produce a work based on this file, this file # does not by itself cause the resulting work to be covered # by the GNU General Public License. # # However the source code for this file must still be made available # in accordance with section (3) of the GNU General Public License. # # This exception does not invalidate any other reasons why a work based # on this file might be covered by the GNU General Public License. # # Copyright (c) 2016-2018 Intra2net AG """ Utility for HTTP based interaction with the arnied web page. Copyright: Intra2net AG """ import re import ssl import http.client as client import urllib.parse as parse import socket import logging log = logging.getLogger('pyi2ncommon.web_interface') #: FQDN of local machine LOCALHOST = socket.gethostname() def find_in_form(regex, form="status", escape=False, check_certs=True): """ Find a regex in given I2N web page form. :param str regex: regular expression to find :param str form: form name to open :param bool escape: whether to escape the regex :param check_certs: forwarded to :py:func:`web_page_request`, see doc there :returns: whether the regex was found :rtype: bool """ data = web_page_request(method="GET", url="/arnie?form=" + form, check_certs=check_certs) if escape: regex = re.escape(regex) if re.search(regex, data): return True else: log.debug("'%s' could not be found in:\n%s", regex, data) return False def web_page_request(method="GET", url="/", body=None, check_certs=True): """ Send an HTTPS request and return any response data. SSL certificates are checked against a default set of certificates installed on you system. This can be disabled (not recommended, security implications!) by setting `check_certs` to `False`. To allow a secure connection to host with e.g. a self-signed certificate, the caller can load this certificate by specifying `check_certs=/path/to/cert.pem`. (see also: :py:meth:`ssl.SSLContext.load_verify_locations`). Note that the certificate has to be issued for the same server name that we try to access, i.e. :py:data:`LOCALHOST`. :param str method: GET or POST method for the request :param str url: url location within the remote host :param body: dictionary to be parsed and added to the url :type body: {str, str} or None :param check_certs: Whether or not to check ssl certificates for connection or file name to a certificate file :type check_certs: bool or str :returns: data from the response if any :rtype: str """ body = parse.urlencode(body) if body is not None else "" headers = {"Content-Type": "application/x-www-form-urlencoded", "Accept": "text/plain"} if isinstance(check_certs, str): context = ssl.create_default_context(cafile=check_certs) elif check_certs: context = ssl.create_default_context() else: # disable certificate checks context = ssl._create_unverified_context() conn = client.HTTPSConnection(LOCALHOST, context=context) conn.request(method, url, body, headers) resp = conn.getresponse() logging.info("Request status %s and response %s", resp.status, resp.reason) if resp.status != 200: raise client.HTTPException("POST request failed.") data = resp.read().decode() conn.close() return data