'Do a generic request.'

def _gen_request(self, method, url, params='', headers=None, extra_environ=None, status=None, upload_files=None, expect_errors=False):

    if (headers is None):
        headers = {}
    if (extra_environ is None):
        extra_environ = {}
    environ = self._make_environ()
    if isinstance(params, (list, tuple, dict)):
        params = urlencode(params)
    if hasattr(params, 'items'):
        params = urlencode(params.items())
        if six.PY3:
            params = params.encode('utf8')
    if upload_files:
        params = cgi.parse_qsl(params, keep_blank_values=True)
        (content_type, params) = self.encode_multipart(params, upload_files)
        environ['CONTENT_TYPE'] = content_type
    elif params:
        environ.setdefault('CONTENT_TYPE', 'application/x-www-form-urlencoded')
    if ('?' in url):
        (url, environ['QUERY_STRING']) = url.split('?', 1)
    else:
        environ['QUERY_STRING'] = ''
    environ['CONTENT_LENGTH'] = str(len(params))
    environ['REQUEST_METHOD'] = method
    environ['wsgi.input'] = six.BytesIO(params)
    self._set_headers(headers, environ)
    environ.update(extra_environ)
    req = TestRequest(url, environ, expect_errors)
    return self.do_request(req, status=status)
