libs.callback   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 143
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 18
eloc 72
dl 0
loc 143
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A WebServer.listen() 0 15 1
A WSHandler.open() 0 4 1
A WebServer._server_response() 0 17 4
A WebServer.__init__() 0 4 1
A WSHandler.on_close() 0 2 1
A HttpHandler.post() 0 8 2
A HttpHandler.get() 0 3 1
A WebServer.server_response() 0 19 4
A WSHandler.check_origin() 0 2 1
A WSHandler.on_message() 0 5 2
1
import json
2
import validators
3
4
from abc import ABC
5
6
from tornado.httpserver import HTTPServer
7
from tornado.ioloop import IOLoop
8
from tornado.web import Application, RequestHandler
9
from tornado.websocket import WebSocketHandler
10
11
from .tools import Tools
12
13
"""
14
    Copyright (c) 2020 Star Inc.(https://starinc.xyz)
15
16
    This Source Code Form is subject to the terms of the Mozilla Public
17
    License, v. 2.0. If a copy of the MPL was not distributed with this
18
    file, You can obtain one at http://mozilla.org/MPL/2.0/.
19
"""
20
21
response_handle = ()
22
23
hello_msg = '''
24
<b>PBP API Server</b>
25
<br>The security project for Internet.
26
<hr>(c)2020 <a href="https://github.com/supersonictw">SuperSonic</a>.
27
'''
28
29
30
class HttpHandler(RequestHandler, ABC):
31
    """
32
    Http Handle
33
    ---
34
    Default URL:
35
        http://localhost:2020/
36
    """
37
38
    async def get(self):
39
        self.write(hello_msg)
40
        await self.finish()
41
42
    async def post(self):
43
        req_body = self.request.body
44
        req_str = req_body.decode('utf8')
45
        result = {"status": 202}
46
        for handle in response_handle:
47
            result = await handle(req_str)
48
        self.write(json.dumps(result))
49
        await self.finish()
50
51
52
class WSHandler(WebSocketHandler, ABC):
53
    """
54
    WebSocket handle
55
    ---
56
    Default URL:
57
        http://localhost:2020/ws
58
    """
59
60
    def check_origin(self, origin):
61
        return True
62
63
    def open(self):
64
        self.write_message(json.dumps({
65
            "status": 201,
66
            "msg": hello_msg
67
        }))
68
69
    async def on_message(self, message):
70
        result = {"status": 202}
71
        for handle in response_handle:
72
            result = await handle(message)
73
        await self.write_message(json.dumps(result))
74
75
    def on_close(self):
76
        pass
77
78
79
class WebServer:
80
    """
81
    Web service of API protocol
82
    """
83
84
    def __init__(self, pbp_handle):
85
        global response_handle
86
        response_handle = (self.server_response,)
87
        self.handle = pbp_handle
88
89
    async def server_response(self, message: str):
90
        """
91
        Check responses from web service
92
93
        :param message: string of JSON format
94
        :return: dict to response
95
        """
96
        try:
97
            req_res = json.loads(message)
98
        except json.decoder.JSONDecodeError:
99
            return {"status": 401}
100
        if req_res.get("version") is not None:
101
            try:
102
                return await self._server_response(req_res)
103
            except:
104
                error_report = Tools.error_report()
105
                Tools.logger(error_report)
106
                return {"status": 500}
107
        return {"status": 400}
108
109
    async def _server_response(self, data: dict):
110
        """
111
        Handle responses from web service
112
113
        :param data: dict from message decoded
114
        :return: dict to response
115
        """
116
        if data.get("version") < 1:
117
            return {
118
                "status": 505
119
            }
120
121
        if "url" in data and validators.url(data["url"]):
122
            return await self.handle.analyze(data)
123
124
        return {
125
            "status": 401
126
        }
127
128
    @staticmethod
129
    def listen(port: int):
130
        """
131
        Start listen on web services
132
133
        :return:
134
        """
135
        app = Application([
136
            ('/', HttpHandler),
137
            ('/ws', WSHandler)
138
        ])
139
        server = HTTPServer(app)
140
        server.listen(port)
141
        server.start(0)
142
        IOLoop.current().start()
143