Esempio n. 1
0
    def dispatch(self, request, response):
        request.log.debug(tools.log_json({
            'API': request.version,
            'Method': request.method,
            'URI': request.URI,
            'vroot': request.vroot
        }, True))

        if request.method == 'POST':
            domain = ''

            try:
                length = int(request.environ.get('CONTENT_LENGTH', '0'))
            except ValueError:
                length = 0

            if length != 0:
                domain = request.environ['wsgi.input'].read(length)
        else:
            domain = '/'.join(request.path)

        """
        extract callable that falls back to the included TLD snapshot, no live
        HTTP fetching
        """
        extract = tldextract.TLDExtract(suffix_list_url=False)
        ext = extract(domain)._asdict()

        # ext = tldextract.extract(domain)._asdict()

        return tools.log_json(ext, 4)
Esempio n. 2
0
    def dispatch(self, request, response):
        request.log.debug(tools.log_json({
            'API': request.version,
            'Method': request.method,
            'URI': request.URI,
            'vroot': request.vroot
        }, True))

        data = {}

        try:
            my_ip = True if request.path[0] == 'ip' else False
        except Exception:
            my_ip = False

        if my_ip:
            data['ip'] = request.environ.get('REMOTE_ADDR', 0)
        else:
            data['API'] = request.version
            data['ip'] = request.environ.get('REMOTE_ADDR', 0)
            data['URI'] = request.URI
            data['method'] = request.method
            data['city'] = request.environ.get('HTTP_X_APPENGINE_CITY', 0)
            data['latlong'] = request.environ.get(
                'HTTP_X_APPENGINE_CITYLATLONG', 0)
            data['country'] = request.environ.get(
                'HTTP_X_APPENGINE_COUNTRY', 0)

        return tools.log_json(data, 4)
Esempio n. 3
0
    def lazy_load(self, py_mod, req, stop=False):
        """
        by default the zun_ prefix is appended
        """
        if isinstance(py_mod, list):
            path = '.'.join([self.prefix + i.lower() for i in py_mod])
            name = '%s%s' % (self.prefix, py_mod[-1].lower())
        else:
            path = name = '%s%s' % (self.prefix, py_mod.lower())

        req.py_mod = '%s.%s.%s.%s.%s' % (
            self.root,
            req.vroot,
            req.version,
            path,
            name)

        if req.py_mod in self.resources:
            req.log.debug(tools.log_json({
                'API': req.version,
                'HOST': (req.host, req.vroot),
                'URI': req.URI,
                'dispatching': (name, req.py_mod),
                'rid': req.request_id
            }, True))
            return self.resources[req.py_mod]

        req.log.debug(tools.log_json({
            'API': req.version,
            'HOST': (req.host, req.vroot),
            'URI': req.URI,
            'loading': (name, req.py_mod),
            'rid': req.request_id
        }, True))

        try:
            __import__(req.py_mod, fromlist=[''])
        except ImportError as e:
            if not stop:
                self.log.debug(tools.log_json({
                    'API': req.version,
                    'ImportError': e,
                    'URI': req.URI,
                    'method': req.method,
                    'py_mod': req.py_mod,
                    'rid': req.request_id
                }, True))
                return self.lazy_load('_catchall', req, stop=(req.py_mod, e))
            raise tools.HTTPException(
                501,
                title="ImportError: %s, %s: %s" % (stop[0], req.py_mod, e),
                description=stop[1])

        module = sys.modules[req.py_mod]
        resource = module.__dict__['APIResource']
        self.resources[req.py_mod] = resource()
        return self.resources[req.py_mod]
Esempio n. 4
0
    def dispatch(self, request, response):

        request.log.debug(
            tools.log_json(
                {"API": request.version, "Method": request.method, "URI": request.URI, "vroot": request.vroot}, True
            )
        )

        return tools.log_json(request.environ, 4)
Esempio n. 5
0
    def __call__(self, environ, start_response):
        """Handle a WSGI application request.
        See pep 3333
        """

        if self.rid and self.rid in environ:
            request_id = environ[self.rid]
        else:
            request_id = str(uuid1())

        req = request.Request(
            self.log,
            request_id,
            environ)

        res = response.Response(
            self.log,
            request_id,
            self._headers.copy(),
            start_response)

        body = []

        try:
            body = self.router(req).dispatch(req, res)
        except tools.HTTPError as e:
            res.status = e.status

            if e.headers:
                res.headers.update(e.headers)

            if e.display:
                body.append(e.to_json())

            if e.log:
                self.log.warning(tools.log_json({
                    'API': req.version,
                    'HTTPError': e.status,
                    'URI': req.URI,
                    'body': e.to_dict(),
                    'method': req.method,
                    'rid': req.request_id
                }, True))

        except Exception as e:
            res.status = 500
            self.log.error(tools.log_json({
                'API': req.version,
                'Exception': e,
                'URI': req.URI,
                'method': req.method,
                'rid': req.request_id
            }, True))

        res.send()
        return body or []
Esempio n. 6
0
    def dispatch(self, request, response):

        request.log.debug(tools.log_json({
            'API': request.version,
            'Method': request.method,
            'URI': request.URI,
            'vroot': request.vroot
        }, True))

        return tools.log_json(request.environ, 4)
Esempio n. 7
0
    def dispatch(self, req, res):

        req.log.info(tools.log_json({
            'API': req.version,
            'URI': req.URI,
            'rid': req.request_id,
            'in': 'dispatch',
            'thread': req.environ.get('thread', '-'),
        }))

        res.headers.update(self.headers)
        res.body = tools.log_json(req.environ, 4)
Esempio n. 8
0
    def dispatch(self, request, response):
        request.log.debug(tools.log_json({
            'API': request.version,
            'Method': request.method,
            'URI': request.URI,
            'vroot': request.vroot
        }, True))

        data = {}
        if request.environ.get('CONTENT_TYPE', '').startswith('multipart'):
            data['files'] = True

        return tools.log_json(data, 4)
Esempio n. 9
0
    def dispatch(self, request, response):
        request.log.debug(tools.log_json({
            'API': request.version,
            'Method': request.method,
            'URI': request.URI,
            'vroot': request.vroot
        }, True))

        data = {}
        data['URI'] = request.URI
        data['py_mod'] = request.py_mod
        data['path'] = request.path

        return tools.log_json(data, 4)
Esempio n. 10
0
    def dispatch(self, request, response):

        request.log.info(tools.log_json({
            'API': request.version,
            'URI': request.URI,
            'rid': request.request_id,
            'in': 'dispatch',
            'thread': request.environ.get('thread', '-'),
            'thread_env': request.environ.get('thread', '-')
        }))

        response.headers.update(self.headers)

        return tools.log_json(request.environ)
Esempio n. 11
0
    def register_routes(self, routes):
        """compile regex pattern for routes per vroot
        :param routes:
            {
                'vroot': tuple(regex, py_mod, methods).
            }
        """
        for vroot, routes in routes.items():
            gen = (route for route in routes if isinstance(route, tuple))
            vroot = vroot.replace('.', '_')
            self.routes[vroot] = []
            for route in gen:
                regex, module = route[:2]
                methods = ['ALL']

                if len(route) > 2:
                    methods = [x.strip().upper()
                               for x in route[2].split(',') if x]

                if regex.startswith('^'):
                    self.routes[vroot].append(
                        (re.compile(r'%s' % regex), module, methods))
                else:
                    self.routes[vroot].append(
                        (re.compile(r'^%s$' % regex), module, methods))

                self.log.debug(tools.log_json({
                    'vroot': vroot,
                    "regex": regex,
                    "py_mod": module,
                    "methods": methods
                }, True))
Esempio n. 12
0
    def dispatch(self, request, response):

        data = {
            'URI': request.URI,
            'resource': request.resource,
            'path': request.path,
        }
        return tools.log_json(data, 4)
Esempio n. 13
0
    def dispatch(self, request, response):
        request.log.debug(tools.log_json({
            'API': request.version,
            'Method': request.method,
            'URI': request.URI,
            'vroot': request.vroot
        }, True))

        data = {}
        try:
            data['status code'] = codes[int(request.path[0], 0)]
        except Exception as _:
            data['status code'] = 'not found'

        data['URI'] = request.URI

        return tools.log_json(data, 4)
Esempio n. 14
0
    def dispatch(self, request, response):

        data = {}
        data['URI'] = request.URI
        data['py_mod'] = request.py_mod
        data['path'] = request.path

        return tools.log_json(data, 4)
Esempio n. 15
0
    def get_status(self):

        try:
            status = int(self.status)
        except Exception as e:
            self.log.error(tools.log_json({"no status": e, "status": self.status}))
            status = 500

        try:
            if status in http_status_codes.codes:
                status = http_status_codes.codes[status]
            else:
                status = http_status_codes.generic_reasons[status // 100]
        except Exception as e:
            self.log.error(tools.log_json({"bad status": e, "status": status}))
            status = "500 Internal Server Error"

        return status
Esempio n. 16
0
    def dispatch(self, request, response):

        request.log.debug(tools.log_json({
            'API': request.version,
            'URI': request.URI,
            'method': request.method,
            'vroot': request.vroot
        }, True))

        data = {}
        data['about'] = ("Hi %s, I am zunzuncito a micro-framework for creating"
                         " REST API's, you can read more about me in: "
                         "www.zunzun.io") % request.environ.get('REMOTE_ADDR', 0)

        data['Request-ID'] = request.request_id
        data['URI'] = request.URI
        data['Method'] = request.method

        return tools.log_json(data, 4)
Esempio n. 17
0
    def dispatch(self, request, response):

        request.log.debug(tools.log_json({
            'API': request.version,
            'Method': request.method,
            'URI': request.URI,
            'path': request.path,
            'vroot': request.vroot
        }, True))

        return __name__
Esempio n. 18
0
    def dispatch(self, request, response):

        request.log.debug(tools.log_json({
            'API': request.version,
            'Method': request.method,
            'URI': request.URI,
            'vroot': request.vroot
        }, True))

        if request.path:
            response.status = int(request.path[0])

        return response.request_id
Esempio n. 19
0
    def dispatch(self, request, response):

        request.log.debug(tools.log_json({
            'API': request.version,
            'Method': request.method,
            'URI': request.URI,
            'vroot': request.vroot
        }, True))

        hash_type = request.resource

        if request.method == 'POST':
            string = ''

            try:
                length = int(request.environ.get('CONTENT_LENGTH', '0'))
            except ValueError:
                length = 0

            if length != 0:
                string = request.environ['wsgi.input'].read(length)
        else:
            string = '/'.join(request.path)

        data = {}
        data['type'] = hash_type
        data['string'] = string

        if hash_type == 'md5':
            data['hash'] = hashlib.md5(string).hexdigest()
        elif hash_type == 'sha1':
            data['hash'] = hashlib.sha1(string).hexdigest()
        elif hash_type == 'sha256':
            data['hash'] = hashlib.sha256(string).hexdigest()
        elif hash_type == 'sha512':
            data['hash'] = hashlib.sha512(string).hexdigest()

        return tools.log_json(data, 4)
Esempio n. 20
0
    def dispatch(self, request, response):

        request.log.debug(tools.log_json({
            'API': request.version,
            'URI': request.URI,
            'method': request.method,
            'vroot': request.vroot
        }, True))

        data = {}
        data['about'] = "Hi %s, I am %s on %s" % (
            request.environ.get('REMOTE_ADDR',
                                0),
            request.host,
            request.vroot)

        data['Method'] = request.method
        data['Request-ID'] = request.request_id
        data['URI'] = request.URI
        data['host'] = request.host
        data['vroot'] = request.vroot

        return tools.log_json(data, 4)
Esempio n. 21
0
    def dispatch(self, request, response):

        request.log.debug(
            tools.log_json(
                {"API": request.version, "Method": request.method, "URI": request.URI, "vroot": request.vroot}, True
            )
        )

        try:
            name = request.path[0]
        except:
            raise tools.HTTPException(400)

        if name != "foo":
            raise tools.HTTPException(
                406, title="exeption example", description="name must be foo", code="my-custom-code", display=True
            )

        return __name__
Esempio n. 22
0
    def dispatch(self, request, response):

        request.log.debug(tools.log_json({
            'API': request.version,
            'Method': request.method,
            'URI': request.URI,
            'vroot': request.vroot
        }, True))

        response.headers.update(self.headers)

        """
        calls start_response
        """
        response.send()

        t = gevent.spawn(long_task)
        t.join()

        yield "sleep 1 second.<br/>"

        gevent.sleep(1)

        yield "sleep 3 seconds...<br/>"

        gevent.sleep(3)

        yield "done.<br/>getting some ips...<br/>"

        urls = [
            'www.google.com',
            'www.example.com',
            'www.python.org',
            'zunzun.io']

        jobs = [gevent.spawn(gevent.socket.gethostbyname, url) for url in urls]
        gevent.joinall(jobs, timeout=2)

        for j in jobs:
            yield "ip = %s<br/>" % j.value

        gevent.spawn(bg_task)
Esempio n. 23
0
    def __init__(self, root, versions=None, hosts=None,
                 routes=None, prefix='zun_', rid=None, debug=False):

        self._headers = tools.CaseInsensitiveDict()
        self.allowed_URI_chars = re.compile(r'^[\w-]+$')
        self.host = '*'
        self.hosts = {'*': 'default'}
        if isinstance(hosts, dict):
            self.hosts = hosts
        self.prefix = prefix
        self.resources = {}
        self.rid = rid
        self.root = root
        self.routes = {}
        self.versions = ['v0', 'v1']
        self.version = self.versions[0]
        self.vroot = 'default'

        if versions and isinstance(versions, list):
            versions = tuple(
                m.group(0) for m in (
                    self.allowed_URI_chars.search(v) for v in map(
                        str,
                        versions)) if m)
            if versions:
                self.versions = versions
            else:
                raise Exception('Versions missing')

        self.log = logging.getLogger()

        if not self.log.handlers:
            self.log.addHandler(logging.StreamHandler())

        self.log.setLevel('DEBUG' if debug else 'INFO')
        self.log.debug(tools.log_json(locals()))

        """
        register / compile the routes regex
        """
        if isinstance(routes, dict):
            self.register_routes(routes)
Esempio n. 24
0
    def dispatch(self, request, response):

        request.log.debug(tools.log_json({
            'API': request.version,
            'Method': request.method,
            'URI': request.URI,
            'vroot': request.vroot
        }, True))

        b = request.environ.get('HTTP_USER_AGENT')

        for k, v in request.environ.items():
            # convert all string values to unicode values and replace
            # malformed data with a suitable
            # replacement marker.
            if isinstance(v, str):
                request.environ[k] = v.decode('utf-8', 'replace')

        a = request.environ.get('HTTP_USER_AGENT')
        return str(type(b)) + str(type(a))
Esempio n. 25
0
    def dispatch(self, request, response):
        req = Request(request.environ)

        # to get a post param
        # field = req.POST['field']

        data = {}
        data["req-GET"] = req.GET
        data["req-POST"] = req.POST
        data["req-application_url"] = req.application_url
        data["req-body"] = req.body
        data["req-content_type"] = req.content_type
        data["req-cookies"] = req.cookies
        data["req-method"] = req.method
        data["req-params"] = req.params
        data["req-path"] = req.path
        data["req-path_info"] = req.path_info
        data["req-path_qs"] = req.path_qs
        data["req-path_url"] = req.path_url
        data["req-query_string"] = req.query_string
        data["req-script_name"] = req.script_name
        data["req-url"] = req.url

        return tools.log_json(data, 4)
Esempio n. 26
0
    def dispatch(self, request, response):

        return tools.log_json(request.__dict__, 4)
Esempio n. 27
0
    def dispatch(self, request, response):

        return tools.log_json(request.environ, 4)
Esempio n. 28
0
    def router(self, req):
        """
        check if the URI is versioned (/v1/resource/...)
        defaults to the first version in versions list (default to v0).
        """
        req.version = self.versions[0]
        for version in self.versions:
            if req.URI.lower().startswith('/%s' % version):
                req.version = version
                """
                if URI is versioned, remove the version '/v0' from URI
                the + 1 if for the starting '/' in the URI
                """
                req.URI = req.URI[len(req.version) + 1:]
                break

        """
        find a python module (py_mod) to handle the request per host
        """
        py_mod = False

        if req.host in self.hosts.keys():
            req.vroot = self.hosts[req.host]
        else:
            for host in self.hosts.keys():
                if re.match(r'^\*\.', host):
                    domain = r'^(?:[^./@]+\.)*%s$' % (
                        host.replace('*.', '').replace('.', r'\.'))
                    if re.match(domain, host):
                        req.vroot = self.hosts[host]
                        break

        req.log.debug(tools.log_json({
            'API': req.version,
            'HOST': (req.host, req.vroot),
            'URI': req.URI,
            'rid': req.request_id,
            'versions': self.versions
        }, True))

        """
        try to match any supplied routes (regex match)
        only if the current host has defined routes

        t[0] = r - regex
        t[1] = p - py_mod
        t[2] = h - HTTP methods
        """
        if req.vroot in self.routes:
            filterf = lambda t: any(i in (req.method.upper(), 'ALL')
                                    for i in t[2])
            for r, p, h in filter(filterf, self.routes[req.vroot]):
                match = r.match(req.URI)
                if match:
                    py_mod = p
                    req.log.debug(tools.log_json({
                        'API': req.version,
                        'HOST': (req.host, req.vroot),
                        'methods': h,
                        'regex_match': (r.pattern, req.URI),
                        'rid': req.request_id
                    }, True))
                    break

        """
        get the API resource and path from URI api_resource/path
        """
        components = [x.strip()
                      for x in req.URI.split('?')[0].split('/')
                      if x.strip()]

        req.resource = ''.join(components[:1])
        req.path = components[1:]

        if not py_mod:
            """
            URI 2 mod: /add/user/ -> zun_add/zun_user/zun_user.py
            """
            if len(req.path) >= 1 and req.URI.endswith('/'):
                if self.allowed_URI_chars.match(''.join(components)):
                    py_mod = components
            elif len(req.path) > 1:
                if self.allowed_URI_chars.match(''.join(components[:-1])):
                    py_mod = components[:-1]
            else:
                py_mod = 'default' if not components else req.resource

        return self.lazy_load(py_mod, req)
Esempio n. 29
0
    def dispatch(self, request, response):
        try:
            temp_name = request.path[0]
        except:
            raise tools.HTTPException(400)

        """rfc2616-sec14.html
        see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
        see http://www.grid.net.ru/nginx/resumable_uploads.en.html
        """
        content_range = request.environ.get('HTTP_CONTENT_RANGE', 0)

        length = int(request.environ.get('CONTENT_LENGTH', 0))

        if content_range:
            content_range = content_range.split()[1].split('/')

            index, offset = [int(x) for x in content_range[0].split('-')]

            total_size = int(content_range[1])

            if length:
                chunk_size = length
            elif offset > index:
                chunk_size = (offset - index) + 1
            elif total_size:
                chunk_size = total_size
            else:
                raise tools.HTTPException(416)
        elif length:
            chunk_size = total_size = length
            index = 0
            offset = 0
        else:
            raise tools.HTTPException(400)

        stream = request.environ['wsgi.input']

        body = []

        try:
            temp_file = os.path.join(
                os.path.dirname('/tmp/test_upload/'),
                temp_name)

            with open(temp_file, 'a+b') as f:
                original_file_size = f.tell()

                f.seek(index)
                f.truncate()

                bytes_to_write = chunk_size

                while chunk_size > 0:
                    # buffer size
                    chunk = stream.read(min(chunk_size, 1 << 13))
                    if not chunk:
                        break
                    f.write(chunk)
                    chunk_size -= len(chunk)

                f.flush()
                bytes_written = f.tell() - index

                if bytes_written != bytes_to_write:
                    f.truncate(original_file_size)
                    f.close()
                    raise tools.HTTPException(416)

            if os.stat(temp_file).st_size == total_size:
                response.status = 200
            else:
                response.status = 201
                body.append('%d-%d/%d' % (index, offset, total_size))

            request.log.info(tools.log_json({
                'index': index,
                'offset': offset,
                'size': total_size,
                'status': response.status,
                'temp_file': temp_file
            }, True))

            return body
        except IOError:
            raise tools.HTTPException(
                500,
                title="upload directory [ %s ]doesn't exist" % temp_file,
                display=True)