python简易web服务器学习笔记(三)

import sys, os, BaseHTTPServer

#-------------------------------------------------------------------------------

class ServerException(Exception):
    '''For internal error reporting.'''
    pass

#-------------------------------------------------------------------------------

class case_no_file(object):
    '''File or directory does not exist.'''

    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(object):
    '''File exists.'''

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

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

#-------------------------------------------------------------------------------

class case_directory_index_file(object):
    '''Serve index.html page for a directory.'''

    def index_path(self, handler):
        return os.path.join(handler.full_path, 'index.html')

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

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

#-------------------------------------------------------------------------------

class case_directory_no_index_file(object):
    '''Serve listing for a directory without an index.html page.'''

    def index_path(self, handler):
        return os.path.join(handler.full_path, 'index.html')

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

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

#-------------------------------------------------------------------------------

class case_always_fail(object):
    '''Base case if nothing else worked.'''

    def test(self, handler):
        return True

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

#-------------------------------------------------------------------------------

class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    '''
    If the requested path maps to a file, that file is served.
    If anything goes wrong, an error page is constructed.
    '''

    Cases = [case_no_file(),
             case_existing_file(),
             case_directory_index_file(),
             case_directory_no_index_file(),
             case_always_fail()]

    # How to display an error.
    Error_Page = """
        <html>
        <body>
        <h1>Error accessing {path}</h1>
        <p>{msg}</p>
        </body>
        </html>
        """

    # How to display a directory listing.
    Listing_Page = '''
        <html>
        <body>
        <ul>
        {0}
        </ul>
        </body>
        </html>
        '''

    # Classify and handle request.
    def do_GET(self):
        try:

            # Figure out what exactly is being requested.
            self.full_path = os.getcwd() + self.path

            # Figure out how to handle it.
            for case in self.Cases:
                if case.test(self):
                    case.act(self)
                    break

        # Handle errors.
        except Exception as msg:
            self.handle_error(msg)

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

    def list_dir(self, full_path):
        try:
            entries = os.listdir(full_path)
            bullets = ['<li>{0}</li>'.format(e) for e in entries if not e.startswith('.')]
            page = self.Listing_Page.format('
'.join(bullets))
            self.send_content(page)
        except OSError as msg:
            msg = "'{0}' cannot be listed: {1}".format(self.path, msg)
            self.handle_error(msg)

    # Handle unknown objects.
    def handle_error(self, msg):
        content = self.Error_Page.format(path=self.path, msg=msg)
        self.send_content(content, 404)

    # Send actual content.
    def send_content(self, content, status=200):
        self.send_response(status)
        self.send_header("Content-type", "text/html")
        self.send_header("Content-Length", str(len(content)))
        self.end_headers()
        self.wfile.write(content)

#-------------------------------------------------------------------------------

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

这次的任务是在路径代表目录而不是文件时展示目录内容列表。
如何处理一个url(统一资源定位符)呢?这次我们先定义了一个类列表,以后可以将各个可能用到的处理方法放入列表中省去了在源码中加if,增强了代码的复用性

然后依然是三种上节中有的情况:existing_file,no_file,always_fail

然后我们做出修改:添加类case_directory_index_file,在请求"index.html"时返回"index.html",case_directory_no_index在不存在时返回目录列表

 

python编程时,经常和文件、目录打交道,这是就离不了os模块。os模块包含普遍的操作系统功能,与具体的平台无关。以下列举常用的命令

(引用自http://www.cnblogs.com/kaituorensheng/archive/2013/03/18/2965766.html)

1. os.name()——判断现在正在实用的平台,Windows 返回 ‘nt'; Linux 返回’posix'

2. os.getcwd()——得到当前工作的目录。

3. os.listdir()——指定所有目录下所有的文件和目录名。例: 

              

  以列表的形式全部列举出来,其中没有区分目录和文件。

4. os.remove()——删除指定文件

5. os.rmdir()——删除指定目录

6. os.mkdir()——创建目录

  注意:这样只能建立一层,要想递归建立可用:os.makedirs()

7. os.path.isfile()——判断指定对象是否为文件。是返回True,否则False

8. os.path.isdir()——判断指定对象是否为目录。是True,否则False。例:          9. os.path.exists()——检验指定的对象是否存在。是True,否则False.例:

     

10. os.path.split()——返回路径的目录和文件名。例:

     

此处只是把前后两部分分开而已。就是找最后一个'/'。看例子:

     

11. os.getcwd()——获得当前工作的目录(get current work dir)

12. os.system()——执行shell命令。例:

     

注意:此处运行shell命令时,如果要调用python之前的变量,可以用如下方式:

var=123
os.environ['var']=str(var) //注意此处[]内得是 “字符串”
os.system('echo $var')

13. os.chdir()——改变目录到指定目录

14. os.path.getsize()——获得文件的大小,如果为目录,返回0

15. os.path.abspath()——获得绝对路径。例:

    

16. os.path.join(path, name)——连接目录和文件名。例:

    

17.os.path.basename(path)——返回文件名

    

18. os.path.dirname(path)——返回文件路径

    

__name__就是如果是直接运行的这个代码__name__就是__main__啦

嘛。。话说,这并没有教会服务器智能给出目录结构啊啊,这只是改了一下类的结构然后加了个特判进去啊啊。。确定没有逗我?

呃。。然后又放在linux下跑了一下,成功显示了文件目录啊。。在windows下只显示了一个index,什么原因呢?

————————————————————————

更新一下原因。。windows下目录下有个同名的index.html所以显示不了目录。。撒比了

代码来源:500 lines or less

原文地址:https://www.cnblogs.com/bitch1319453/p/6592373.html