<reponame>callmexss/learn-python<filename>shiyanlou/web_server/server_v4.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""""""""""""""""""""""""""""""""""""""""""""""
"      Filename: server.py
"
"        Author: xss - <EMAIL>
"   Description: Simple http server 3.0
"        Create: 2018-07-02 17:11:20
"""""""""""""""""""""""""""""""""""""""""""""""
import os
import subprocess

from http.server import BaseHTTPRequestHandler, HTTPServer


class ServerException(Exception):
    '''服务器内部错误'''

    pass


class base_case(object):
    '''条件处理基类'''

    def handle_file(self, handler, full_path):
        try:
            with open(full_path, 'rb') as reader:
                content = reader.read()
            handler.send_content(content)
        except IOError as msg:
            msg = "'{0}' can not be read: {1}".format(full_path, msg)
            handler.handle_error(msg)

    def index_path(self, handler):
        return os.path.join(handler.full_path, 'index.html')
        # path is not a member of Requesthandler
        # return os.path.join(handler.path, 'index.html')

    # 要求子类必须实现该接口
    def test(self, handler):
        assert False, "Not implemented."

    def act(self, handler):
        assert False, "Not implemented."


class case_no_file(base_case):
    '''路径不存在'''

    def test(self, handler):
        return not os.path.exists(handler.full_path)

    def act(self, handler):
        raise ServerException("'{0} not found".format(handler.path))


class case_existing_file(base_case):
    '''路径是文件'''

    def test(self, handler):
        return os.path.isfile(handler.full_path)

    def act(self, handler):
        self.handle_file(handler, handler.full_path)


class case_always_fail(base_case):
    '''所有情况都不符合时的默认处理类'''

    def test(self, handler):
        return True

    def act(self, handler):
        raise ServerException("Unknown object '{0}'".format(handler.path))


class case_directory_index_file(base_case):
    '''主页'''

    def test(self, handler):
        return os.path.isdir(handler.full_path) and \
               os.path.isfile(self.index_path(handler))

    def act(self, handler):
        self.handle_file(handler, self.index_path(handler))


class case_cgi_file(base_case):
    '''可执行脚本'''

    def run_cgi(self, handler):
        data = subprocess.check_output(
               ["python3", handler.full_path],
               shell=False)
        handler.send_content(data)

    def test(self, handler):
        return os.path.isfile(handler.full_path) and \
               handler.full_path.endswith('py')

    def act(self, handler):
        self.run_cgi(handler)


class RequestHandler(BaseHTTPRequestHandler):
    '''处理请求并返回页面'''

    Error_Page = '''\
            <html>
            <body>
            <h1>Error accessing {path}</h1>
            <p>{msg}</p>
            <p></p>
            </body>
            </html>
            '''
    Cases = [case_no_file(),
             case_cgi_file(),
             case_existing_file(),
             case_directory_index_file(),
             case_always_fail()]

    def do_GET(self):
        try:

            self.full_path = os.getcwd() + self.path

            for case in self.Cases:
                if case.test(self):
                    case.act(self)
                    break

        except Exception as msg:
            self.handle_error(msg)

    def handle_error(self, msg):
        content = self.Error_Page.format(path=self.path, msg=msg)
        self.send_content(content.encode('utf-8'), 404)

    def send_content(self, page, statue=200):
        self.send_response(statue)
        self.send_header("Content-Type", "text/html")
        self.send_header("Content-Length", str(len(page)))
        self.end_headers()
        self.wfile.write(page)


if __name__ == '__main__':
    serverAddress = ('', 8080)
    server = HTTPServer(serverAddress, RequestHandler)
    server.serve_forever()

#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""""""""""""""""""""""""""""""""""""""""""""""
"      Filename: server.py
"
"        Author: xss - <EMAIL>
"   Description: Simple http server 3.0
"        Create: 2018-07-02 17:11:20
"""""""""""""""""""""""""""""""""""""""""""""""
import os
import subprocess

from http.server import BaseHTTPRequestHandler, HTTPServer


class ServerException(Exception):
    '''服务器内部错误'''

    pass


class base_case(object):
    '''条件处理基类'''

    def handle_file(self, handler, full_path):
        try:
            with open(full_path, 'rb') as reader:
                content = reader.read()
            handler.send_content(content)
        except IOError as msg:
            msg = "'{0}' can not be read: {1}".format(full_path, msg)
            handler.handle_error(msg)

    def index_path(self, handler):
        return os.path.join(handler.full_path, 'index.html')
        # path is not a member of Requesthandler
        # return os.path.join(handler.path, 'index.html')

    # 要求子类必须实现该接口
    def test(self, handler):
        assert False, "Not implemented."

    def act(self, handler):
        assert False, "Not implemented."


class case_no_file(base_case):
    '''路径不存在'''

    def test(self, handler):
        return not os.path.exists(handler.full_path)

    def act(self, handler):
        raise ServerException("'{0} not found".format(handler.path))


class case_existing_file(base_case):
    '''路径是文件'''

    def test(self, handler):
        return os.path.isfile(handler.full_path)

    def act(self, handler):
        self.handle_file(handler, handler.full_path)


class case_always_fail(base_case):
    '''所有情况都不符合时的默认处理类'''

    def test(self, handler):
        return True

    def act(self, handler):
        raise ServerException("Unknown object '{0}'".format(handler.path))


class case_directory_index_file(base_case):
    '''主页'''

    def test(self, handler):
        return os.path.isdir(handler.full_path) and \
               os.path.isfile(self.index_path(handler))

    def act(self, handler):
        self.handle_file(handler, self.index_path(handler))


class case_cgi_file(base_case):
    '''可执行脚本'''

    def run_cgi(self, handler):
        data = subprocess.check_output(
               ["python3", handler.full_path],
               shell=False)
        handler.send_content(data)

    def test(self, handler):
        return os.path.isfile(handler.full_path) and \
               handler.full_path.endswith('py')

    def act(self, handler):
        self.run_cgi(handler)


class RequestHandler(BaseHTTPRequestHandler):
    '''处理请求并返回页面'''

    Error_Page = '''\
            <html>
            <body>
            <h1>Error accessing {path}</h1>
            <p>{msg}</p>
            <p></p>
            </body>
            </html>
            '''
    Cases = [case_no_file(),
             case_cgi_file(),
             case_existing_file(),
             case_directory_index_file(),
             case_always_fail()]

    def do_GET(self):
        try:

            self.full_path = os.getcwd() + self.path

            for case in self.Cases:
                if case.test(self):
                    case.act(self)
                    break

        except Exception as msg:
            self.handle_error(msg)

    def handle_error(self, msg):
        content = self.Error_Page.format(path=self.path, msg=msg)
        self.send_content(content.encode('utf-8'), 404)

    def send_content(self, page, statue=200):
        self.send_response(statue)
        self.send_header("Content-Type", "text/html")
        self.send_header("Content-Length", str(len(page)))
        self.end_headers()
        self.wfile.write(page)


if __name__ == '__main__':
    serverAddress = ('', 8080)
    server = HTTPServer(serverAddress, RequestHandler)
    server.serve_forever()
#!/usr/bin/python3 # -*- coding: utf-8 -*- "" "      Filename: server.py " "        Author: xss - <EMAIL> "   Description: Simple http server 3.0 "        Create: 2018-07-02 17:11:20 服务器内部错误 条件处理基类 # path is not a member of Requesthandler # return os.path.join(handler.path, 'index.html') # 要求子类必须实现该接口 路径不存在 路径是文件 所有情况都不符合时的默认处理类 主页 可执行脚本 处理请求并返回页面 \             <html>             <body>             <h1>Error accessing {path}</h1>             <p>{msg}</p>             <p></p>             </body>             </html>