python3 web服务器_python3 手动编写的简单的web服务器(HttpServer)

httpserver代码如下

import socket

import pymysql

import re

from uuid import uuid4

from datetime import datetime, timedelta

# 1. 识别不同的网址 --> 返回不同的页面

# 2. 能够加载外部的html文件进来

# 3. 服务器去链接数据库

# 4. 注册功能 --> 插入一条数据到mysql中

# 5. 登陆功能 --> 在数据库中查询 在注册的时候插入的账户密码是否匹配

# 6. 保持登陆 --> cookie 或者 session

HOME_DIR = '.\html'

class HttpServer():

def __init__(self):

self.ss = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 重启不改端口号

self.ss.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

self.ss.bind(('127.0.0.1', 8080))

self.ss.listen(10)

self.session_id = None # session默默认为None

print('HTTP服务器已启动...')

def start(self):

while True:

conn, addr = self.ss.accept()

try:

msg = conn.recv(1024)

url = self.get_url_argument(msg) # url是个列表,里面存了url、用户参数和cookie

func, res, info = self.url_header_list(url) #参数url数据直接返回到info中

# 得到session_id,加入到响应报文

cookie = self.set_cookie(self.session_id)

# 响应报文

response_header = 'HTTP/1.1 OK\r\nContent-Type:text/html\r\n' \

'Connection:Close\r\n'

response_body = func(res, info)

conn.send((response_header + cookie + response_body).encode())

conn.close()

except Exception as e:

conn.close()

print(e)

# 把的url和对应的逻辑函数、资源路径和请求参数返回一个tuple

def url_header_list(self, url):

if url[0] == '/':

res = HOME_DIR + '\\index.html'

return (self.index, res, url)

if url[0] == '/index.html':

res = HOME_DIR + '\\index.html'

return (self.index, res, url)

elif url[0] == '/login.html':

print(url)

res = HOME_DIR + '\\login.html'

return (self.login, res, url)

elif url[0] == '/register.html':

res = HOME_DIR + '\\register.html'

return (self.register, res, url)

elif url[0] == '/exit':

res = HOME_DIR + '\\index.html'

return (self.main_exit, res, url)

else:

res = HOME_DIR + '\\error.html'

return (self.error, res, url[1])

# 请求报文切割url和请求argument

def get_url_argument(self, msg):

msg = msg.decode()

msg_list = msg.split('\r\n\r\n')

info_dict = {} # 参数信息,放入字典

request_info = [] # 打包所有信息的列表

request_msg = msg_list[0].split() # 切割请求报文,找到url

request_info.append(request_msg[1]) # 把url放入列表

cookie = self.get_cookie(msg) # 获取cookie信息

if msg_list[1] != '': # 从请求报文里切割传递的参数,并放入字典

info_list = msg_list[1].split('&')

info1 = info_list[0].split('=')

info2 = info_list[1].split('=')

info_dict[info1[0]] = info1[1]

info_dict[info2[0]] = info2[1]

request_info.append(info_dict) # 把信息字典放入列表

request_info.append(cookie) # 把cookie放入列表

return request_info

else:

request_info.append(info_dict)

request_info.append(cookie) # 把cookie放入列表

return request_info

# 连接mysql数据库

def mysql_conn(self):

conn = pymysql.connect(

host='127.0.0.1',

user='root', password='root',

database='httpweb',

charset='utf8')

return conn

# 进入首页,判断session是否过期,未过期直接登录。

def index(self, res, info):

html = res

count, username = self.get_session(info[2])

if info is not None:

# count, username = self.get_session(info[2])

if count > 0:

html = HOME_DIR + '\\main.html'

with open(html, encoding='utf-8') as f:

response_body = f.read()

try:

response_body = self.render(response_body, username)

except Exception:

print("报错")

print(response_body)

return response_body

def main_exit(self, res, info):

delete = self.del_session(info[2])

print(delete)

with open(res, encoding='utf-8') as f:

response_body = f.read()

return response_body

# 进入错误页面

def error(self, res, info):

with open(res, encoding='utf-8') as f:

response_body = f.read()

return response_body

# 进入登录界面和登录逻辑

def login(self, res, info):

if not info[1]:

with open(res, encoding='utf-8') as f:

response_body = f.read()

return response_body

else:

count, user_info = self.login_dao(info[1])

if count > 0:

session = self.set_session(user_info[0])

html = '\\main.html'

else:

html = '\\login_fail.html'

with open(HOME_DIR+html, encoding='utf-8') as f:

response_body = f.read()

response_body = self.render(response_body, user_info[1])

return response_body

# 进入注册界面和注册逻辑

def register(self, res, info):

if not info[1]:

with open(res, encoding='utf-8') as f:

response_body = f.read()

return response_body

else:

html = ''

is_exist = self.user_exists(info[1])

if is_exist > 0:

html = '\\register_fail.html'

else:

count = self.register_dao(info[1])

if count > 0:

html = '\\login.html'

else:

html = '\\register_error.html'

with open(HOME_DIR+html, encoding='utf-8') as f:

response_body = f.read()

return response_body

# 登录dao函数

def login_dao(self, info):

sql_conn = self.mysql_conn()

username = info['username']

password = info['password']

sql = "select * from users where `name`='{}' and `password`='{}'".format(username, password)

cursor = sql_conn.cursor()

count = cursor.execute(sql)

user_info = cursor.fetchone()

cursor.close()

sql_conn.commit()

sql_conn.close()

return count, user_info

# 注册dao函数

def register_dao(self, info):

sql_conn = self.mysql_conn()

username = info['username']

password = info['password']

sql = "insert into users (`name`,`password`) values ('{}','{}')".format(username, password)

cursor = sql_conn.cursor()

count = cursor.execute(sql)

sql_conn.commit()

sql_conn.close()

return count

# 判断用户是否存在dao函数

def user_exists(self, info):

sql_conn = self.mysql_conn()

username = info['username']

sql = "select * from users where `name`='{}'".format(username)

cursor = sql_conn.cursor()

count = cursor.execute(sql)

cursor.close()

sql_conn.commit()

sql_conn.close()

return count

# 利用正则表达式替换html中的内容,渲染技术

def render(self, data, replace):

pattern = re.compile('{{ }}')

res = re.sub(pattern, replace, data)

return res

# 设置cookie

def set_cookie(self, session_id):

cookie = 'Set-Cookie: session_id={}\r\n\r\n'.format(session_id)

return cookie

# 获取cookie,把session_id从请求报文切割出来

def get_cookie(self, msg):

msg_list = msg.split('\r\n')

for msg in msg_list:

if msg.startswith('Cookie:'):

cookies = msg[len("Cookie:"):]

cookie_list = cookies.split(';')

for cookie in cookie_list:

cookie = cookie.replace(' ', "")

if cookie.startswith('session_id='):

serect_key = cookie.split('=')[-1]

return serect_key

break

return None

# 获取5天后时间

def get_time(self, days=5):

return datetime.now() + timedelta(days=days)

# 设置session,把session放入数据库中

def set_session(self, users_id):

# del_session = self.del_all_session(users_id) # 多浏览器,不使用删除所有session

# print(del_session)

sql_conn = self.mysql_conn()

session_id = self.gen_uuid()

self.session_id = session_id

sql = "insert into `session` (serect_key, validate, users_id) values('{}', '{}', '{}')".format(session_id, self.get_time(), users_id)

cursor = sql_conn.cursor()

count = cursor.execute(sql)

cursor.close()

sql_conn.commit()

sql_conn.close()

return count

# 获取session,从数据库中查找用户是否有未过期的session数据

def get_session(self, info):

session_id = info

sql_conn = self.mysql_conn()

cursor = sql_conn.cursor()

# 根据session有效时间查,暂时没写

sql = "select users.name from `session` join users on `session`.users_id=users.id where `session`.serect_key='{}'".format(session_id)

count = cursor.execute(sql)

res = None

if count > 0:

res = cursor.fetchone()

sql_conn.commit()

cursor.close()

sql_conn.close()

if res is None:

return count, res

else:

return count, res[0]

# 用uuid生成唯一码作为session

def gen_uuid(self):

return uuid4().hex

# 删除用户当前session

def del_session(self, info):

session_id = info

sql_conn = self.mysql_conn()

cursor = sql_conn.cursor()

sql = "delete from `session` where serect_key='{}'".format(session_id)

count = cursor.execute(sql)

sql_conn.commit()

cursor.close()

sql_conn.close()

return count

if __name__ == '__main__':

hp = HttpServer()

hp.start()

目录格式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值