Example #1
0
def _parseHttpRequestResponse(model, http_request, http_response, protocol):
    try:
        global i_tag
        global var_i
        """ Parses a HTTP Request/Response and generate it's translation in ASLan++. """
        request_parser = HttpParser()
        request_parser.execute(http_request, len(http_request))

        var_i = 0

        # concretization details
        concrete = dict()

        # concretization TAG
        returntag = "tag{}".format(i_tag)

        # URL for concretization
        url = protocol + "://" + request_parser.get_headers(
        )['Host'] + "/" + request_parser.get_url()
        concrete['url'] = url

        # path (this string should not begin with something different from a character)
        # and replace every non alphanumeric character with _
        # the first re.sub is used to replace every non alphanumeric char
        # the second re.sub is used to remove non character from the begining of the string
        page = re.sub("^[^a-z]*", "",
                      re.sub("[^a-zA-Z0-9]", "_",
                             urlparse(url).path))
        # add page in the array _aslanpp_constants
        model._page_constants.add(page)

        # method for concretization
        method = request_parser.get_method()
        concrete['method'] = method

        # query string
        post_query_string = ""
        get_query_string = request_parser.get_query_string()
        if method == "POST" and "Content-type" in request_parser.get_headers(
        ) and "multipart/form-data" not in request_parser.get_headers(
        )['Content-Type']:
            # POST parameters, multipart/form-data not yet supported
            post_query_string = request_parser.recv_body(
            )  #"&".join(a for a in [query_string, request_parser.recv_body()] if len(a)>0)
        if "Content-type" in request_parser.get_headers(
        ) and "multipart/form-data" in request_parser.get_headers(
        )['Content-Type']:
            print("multipart/form-data not yet supported")

        # for each request\response I need
        aslanpp_params_no_questionmark = ""
        aslanpp_params_questionmark = ""
        aslanpp_cookie_no_questionmark = ""
        aslanpp_cookie_questionmark = ""
        aslanpp_cookie2_no_questionmark = ""
        aslanpp_cookie2_questionmark = ""

        # convert GET parameters
        if get_query_string:
            # saving the concrete parameters
            concrete_get_params = [
                couple.split("=") for couple in get_query_string.split("&")
            ]

            # parse the parameters and retrieve ASLan++ code and mapping
            aslanpp_no_questionmark, aslanpp_questionmark, mapping_get = _parse_parameters(
                model, concrete_get_params)
            aslanpp_params_no_questionmark += aslanpp_no_questionmark
            aslanpp_params_questionmark += aslanpp_questionmark

            # save get param in concretization
            concrete['get_params'] = mapping_get

        # convert POST parameters
        if post_query_string:
            # saving the concrete parameters
            concrete_post_params = [
                couple.split("=") for couple in post_query_string.split("&")
            ]

            # parse the parameters and retrieve ASLan++ code and mapping
            aslanpp_no_questionmark, aslanpp_questionmark, mapping_post = _parse_parameters(
                model, concrete_post_params)
            aslanpp_params_no_questionmark += aslanpp_no_questionmark
            aslanpp_params_questionmark += aslanpp_questionmark

            # save get param in concretization
            concrete['post_params'] = mapping_post

        if aslanpp_params_no_questionmark == "":
            aslanpp_params_no_questionmark = "none"
        else:
            aslanpp_params_no_questionmark = aslanpp_params_no_questionmark[:
                                                                            -5]
        if aslanpp_params_questionmark == "":
            aslanpp_params_questionmark = "none"
        else:
            aslanpp_params_questionmark = aslanpp_params_questionmark[:-5]

        # convert cookie in the request
        try:
            cookie_request = request_parser.get_headers()['Cookie']

            simple_cookie = Cookie.SimpleCookie(cookie_request)
            concrete_cookie = [[item, simple_cookie[item].value]
                               for item in simple_cookie]

            # parse the parameters and retrieve ASLan++ code, constants, variables and mapping
            cookie_no_questionmark, cookie_questionmark, cookie_mapping = _parse_parameters(
                model, concrete_cookie)
            aslanpp_cookie_no_questionmark += cookie_no_questionmark[:-5]
            aslanpp_cookie_questionmark += cookie_questionmark[:-5]

            # save the mapping cookies
            concrete['cookies'] = cookie_mapping
        except KeyError:
            aslanpp_cookie_no_questionmark = "none"
            aslanpp_cookie_questionmark = "none"
            pass

        # check the response
        response_parser = HttpParser()
        response_parser.execute(http_response, len(http_response))

        # Location
        # get the returned page by checking the Location field in
        # the header. If Location is set, it means is a 302 Redirect
        # and the client is receiving a different page back in the response
        try:
            location = response_parser.get_headers()['Location']
            # prepend the letter p since in ASLan++ constants should start with a char
            return_page = "p{}".format(
                urlparse(location).path.partition("?")[0].replace(
                    ".", "_").replace("/", "_"))
            model._page_constants.add(return_page)
        except KeyError:
            return_page = page

        # parse cookie in the response
        try:
            set_cookie_header = response_parser.get_headers()['Set-Cookie']
            # parse new cookie
            simple_cookie = Cookie.SimpleCookie(set_cookie_header)
            cookies = [[item, simple_cookie[item].value]
                       for item in simple_cookie]

            # parse the parameters and retrieve ASLan++ code, constants, variables and mapping
            aslanpp_cookie2_no_questionmark, aslanpp_cookie2_questionmark, cookie2_mapping = _parse_parameters(
                model, cookies)
            aslanpp_cookie2_no_questionmark += cookie_no_questionmark[:-5]
            aslanpp_cookie2_questionmark += cookie_questionmark[:-5]

            # save the mapping cookies
            concrete['cookies'] = cookie2_mapping

        except KeyError:
            aslanpp_cookie2_no_questionmark = "none"
            aslanpp_cookie2_questionmark = "non"
            pass

        model._webapp_branch += request_skeleton.format(
            page, aslanpp_params_questionmark, aslanpp_cookie_questionmark,
            returntag, return_page, "none", aslanpp_cookie2_no_questionmark,
            returntag)

        model._client_branch += client_skeleton.format(
            page, aslanpp_params_no_questionmark,
            aslanpp_cookie_no_questionmark, returntag, return_page, returntag)

        model._concretization[returntag] = concrete

        # save tag in taglist and increment the tag number
        model._taglist.add(returntag)

        # increate tag
        i_tag += 1

        return returntag
    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
        print(exc_type, fname, exc_tb.tb_lineno)