felix 3 years ago
commit
3122bebfec
12 changed files with 257 additions and 0 deletions
  1. 179 0
      server.py
  2. 16 0
      www/articles/1.html
  3. 16 0
      www/articles/2.html
  4. 16 0
      www/articles/3.html
  5. 5 0
      www/bootstrap.min.css
  6. 6 0
      www/bootstrap.min.js
  7. BIN
      www/duck.png
  8. 4 0
      www/hello.py
  9. 13 0
      www/index.html
  10. BIN
      www/mouse.swf
  11. BIN
      www/python.jpg
  12. 2 0
      www/test

+ 179 - 0
server.py

@@ -0,0 +1,179 @@
+import socket
+import threading
+import datetime
+import os
+from pathlib import Path
+
+htmlTemplate='''<!DOCTYPE html>
+<html>
+  <head>
+    <title>{title}</title>
+  </head>
+  <body>{content}</body>
+</html>
+'''
+
+EXTS={'jpg' :'image/jpeg',
+      'jpeg':'image/jpeg',
+      'png' :'image/png',
+      'ico' :'image/icon',
+      'htm' :'text/html',
+      'html':'text/html',
+      'js'  :'application:x-javascript',
+      'css' :'text/css',
+      'txt' :'text/plain'}
+
+
+class Request(object):
+    def __init__(self,req):
+        self.__chips=req.split('\r\n')
+        self.__RLChips=self.__chips[0].split(' ')
+        self.method=self.__RLChips[0]
+        self.URL=self.__RLChips[1]
+        self.version=self.__RLChips[2]
+        self.headers=self.__getHeaders()
+        self.requestBody=self.__chips[-1]
+    
+    
+    def __getHeaders(self):
+        header=self.__chips[1:-2]
+        headerDict={}
+        for i in header:
+            key,value=i.split(': ',1)
+            headerDict[key]=value
+        return headerDict
+
+
+
+
+class Response(object):
+    def __init__(self):
+        self.version='HTTP/1.1'
+        self.date=datetime.datetime.now().strftime('%a, %d %b %Y %H:%M:%S GMT')
+        self.contentType='text/html'
+        self.ext=''
+    
+    
+    def dealRequest(self,request):
+        self.version=request.version
+        self.URL=request.URL
+        self.path=os.path.join('www',request.URL[1:])
+        self.ext=self.path.split('.')[-1] if '.' in self.path else ''
+        self.statusCode,self.statusDesc=self.__ifExist()
+        self.content=self.__getContent()
+        self.contentType=self.__getType()
+
+    
+    
+    def __ifExist(self):
+        exist=os.path.exists(self.path)
+        if exist:
+            return ['200','OK']
+        else:
+            return ['404','Not Found']
+    
+    
+    def __getContent(self):
+        if self.statusCode=='200':
+            if Path(self.path).is_file():
+                with open(self.path,'rb') as f:
+                    page=f.read()
+                try:
+                    return page.decode('utf-8')
+                except:
+                    return page
+            
+            else:
+                content=''
+                if self.URL[-1]!='/':
+                    self.redirect(self.URL+'/',tem=False)
+                    return ''
+                for i in os.listdir(self.path):
+                    if Path(os.path.join(self.path,i)).is_dir():
+                        i=i+'/'
+                    content=content+'<li><a href="%s">%s</a></li>' %(self.URL+i,i)
+                if self.URL!='/':
+                    content='<li><a href="../">../</a></li>'+content
+                title='Index of '+self.URL
+                content='<h1> '+title+'</h1><hr/>'+'<ul>'+content+'</ul>'
+                return htmlTemplate.format(title=title,content=content)
+        
+        elif self.statusCode=='404':
+            return htmlTemplate.format(title='404 Not Found',content='<h1>404 Not Found</h1>')
+        else:
+            return ''
+    
+    
+    def __getType(self):
+        if self.statusCode=='200' and Path(self.path).is_file():
+            return EXTS[self.ext] if self.ext in EXTS else 'text/plain'
+        else:
+            return 'text/html'
+    
+    
+    def redirect(self,url,tem=True):
+        if tem:
+            self.statusCode='302'
+            self.statusDesc='Moved Temporarily'
+        else:
+            self.statusCode='301'
+            self.statusDesc='Moved Permanently'
+        self.location=url
+    
+    
+    @property
+    def header(self):
+        statusLine=self.version+' '+self.statusCode+' '+self.statusDesc
+        baseHeader=statusLine+\
+                   '\r\nDate: '+self.date+\
+                   '\r\nContent-Type: '+self.contentType+\
+                   '\r\nContent-Length: '+str(len(self.content))
+        if self.statusCode=='302' or self.statusCode=='301':
+            baseHeader=baseHeader+'\r\nLocation: '+self.location
+        return baseHeader+"\r\n\r\n"
+
+
+
+def http(sock,addr):
+    buffer=b''
+    while True:
+        data=sock.recv(1024)
+        buffer=buffer+data
+        if len(data)<1024:
+            break
+    
+    data=buffer.decode('utf-8')
+    if len(data)==0:
+        sock.close()
+        return ''
+    
+    response=Response()
+    try:
+        request=Request(data)
+        response.dealRequest(request)
+        if request.URL=='/123456':
+            response.redirect('/index.html')
+    except:
+        response.statusCode='500'
+        response.statusDesc='Internal Server Error'
+        response.content=htmlTemplate.format(title='500 Internal Server Error',content='<h1>500 Internal Server Error</h1>')
+    sock.send(response.header.encode('utf-8'))
+    
+    if isinstance(response.content,bytes):
+        sock.send(response.content)
+    else:
+        sock.send(response.content.encode('utf-8'))
+    
+    print(addr[0]+' === '+request.method+" === "+request.URL+" === "+response.statusCode)
+    sock.close()
+
+
+s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
+s.bind(('0.0.0.0',5000))
+s.listen(5)
+print('httpserver running...')
+
+while True:
+    sock,addr=s.accept()
+    t=threading.Thread(target=http,args=(sock,addr))
+    t.start()

+ 16 - 0
www/articles/1.html

@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <link href="/bootstrap.min.css" rel="stylesheet" media="screen">
+    <script type="text/javascript" src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
+    <script src="/bootstrap.min.js"></script>
+    <title>article1</title>
+    </head>
+    <body>
+        <div class='container'>
+        <h1>hello article1</h1>
+        </div>
+    </body>
+</html>

+ 16 - 0
www/articles/2.html

@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <link href="/bootstrap.min.css" rel="stylesheet" media="screen">
+    <script type="text/javascript" src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
+    <script src="/bootstrap.min.js"></script>
+    <title>article2</title>
+    </head>
+    <body>
+        <div class='container'>
+        <h1>hello article2</h1>
+        </div>
+    </body>
+</html>

+ 16 - 0
www/articles/3.html

@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <link href="/bootstrap.min.css" rel="stylesheet" media="screen">
+    <script type="text/javascript" src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
+    <script src="/bootstrap.min.js"></script>
+    <title>article3</title>
+    </head>
+    <body>
+        <div class='container'>
+        <h1>hello article3</h1>
+        </div>
+    </body>
+</html>

File diff suppressed because it is too large
+ 5 - 0
www/bootstrap.min.css


File diff suppressed because it is too large
+ 6 - 0
www/bootstrap.min.js


BIN
www/duck.png


+ 4 - 0
www/hello.py

@@ -0,0 +1,4 @@
+def abc():
+    return '<h1>hello</h1>'
+
+print(abc())

+ 13 - 0
www/index.html

@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <meta charset='utf-8'>
+        <title>index</title>
+        <script>
+            
+        </script>
+    </head>
+    <body>
+        <h1>hello world</h1>
+    </body>
+</html>

BIN
www/mouse.swf


BIN
www/python.jpg


+ 2 - 0
www/test

@@ -0,0 +1,2 @@
+I am a test page
+<h1>hello world</h1> it doesn't work