#!/usr/bin/python3#-*- coding: utf-8 -*-#Author: hkey
importosimportsocketserverimportsubprocessfrom os.path importgetsize, joinfrom modules.auth importAuthfrom modules.log importLoggerclassMyServer(socketserver.BaseRequestHandler):defhandle(self):try:whileTrue:
auth_info= self.request.recv(1024).decode()
auth_type, user, pwd= auth_info.split(':')
auth_user=Auth(user, pwd)if auth_type == 'register':
status_code=auth_user.register()
self.request.sendall(status_code.encode())elif auth_type == 'login':
user_dict=auth_user.login()ifuser_dict:
self.request.sendall(b'200')
self.user_current_path= user_dict['home_path']
self.user_home_path= user_dict['home_path']
self.user_limit_size= user_dict['limit_size']whileTrue:
command= self.request.recv(1024).decode()
command_str=command.split()[0]ifhasattr(self, command_str):
func=getattr(self, command_str)
func(command)else:
self.request.sendall(b'400')exceptConnectionResetError as e:print('Error:', e)defdir(self, command):if len(command.split()) == 1:
Logger.info('[%s] 执行成功.' %command)
self.request.sendall(b'202')
response= self.request.recv(1024)
cmd_res= subprocess.Popen('dir %s' % self.user_current_path, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, shell=True)
stdout=cmd_res.stdout.read()
stderr=cmd_res.stderr.read()
result= stdout if stdout elsestderr
self.request.sendall(result)else:
Logger.warning('[%s] 命令格式错误.' %command)
self.request.sendall(b'402')defpwd(self, command):if len(command.split()) == 1:
self.request.sendall(b'202')
Logger.info('[%s] 执行成功.' %command)
response= self.request.recv(1024)
self.request.sendall(self.user_current_path.encode())else:
Logger.warning('[%s] 命令格式错误.' %command)
self.request.sendall(b'402')defmkdir(self, command):if len(command.split()) > 1:
dir_name= command.split()[1]
dir_path=os.path.join(self.user_current_path, dir_name)if notos.path.isdir(dir_path):
Logger.info('[%s] 执行成功.' %command)
self.request.sendall(b'202')
response= self.request.recv(1024)
os.makedirs(dir_path)else:
Logger.warning('[%s] 命令格式错误.' %command)
self.request.sendall(b'402')defcd(self, command):if len(command.split()) > 1:
dir_name= command.split()[1]
dir_path=os.path.join(self.user_current_path, dir_name)if dir_name == '..' and len(self.user_current_path) >len(self.user_home_path):
self.request.sendall(b'202')
response= self.request.recv(1024)
self.user_current_path=os.path.dirname(self.user_current_path)elifos.path.isdir(dir_path):
self.request.sendall(b'202')
response= self.request.recv(1024)if dir_name != '.' and dir_name != '..':
self.user_current_path=dir_pathelse:
self.request.sendall(b'403')else:
Logger.warning('[%s] 命令格式错误.' %command)
self.request.sendall(b'402')defput(self, command):
filename= command.split()[1]
file_path=os.path.join(self.user_current_path, filename)
response= self.request.sendall(b'000')
file_size= self.request.recv(1024).decode()
file_size=int(file_size)
used_size= self.__getdirsize(self.user_home_path)if self.user_limit_size > file_size +used_size:
self.request.sendall(b'202')
Logger.info('[%s] 执行成功.' %command)
recv_size=0
Logger.info('[%s] 文件开始上传.' %file_path)
with open(file_path,'wb') as f:while recv_size !=file_size:
data= self.request.recv(1024)
recv_size+=len(data)
f.write(data)
Logger.info('[%s] 文件上传完成.' %file_path)else:
self.request.sendall(b'403')def __getdirsize(self, user_home_path):
size=0for root, dirs, files inos.walk(user_home_path):
size+= sum([getsize(join(root, name)) for name infiles])returnsizedefget(self, command):if len(command.split()) > 1:
filename= command.split()[1]
file_path=os.path.join(self.user_current_path, filename)ifos.path.isfile(file_path):
self.request.sendall(b'202')
file_size=os.path.getsize(file_path)
status_code= self.request.recv(1024).decode()if status_code == '406':
self.request.sendall(b'000')
recv_size= int(self.request.recv(1024).decode())if file_size >recv_size:
self.request.sendall(b'405')
respon= self.request.recv(1024)elif file_size ==recv_size:
self.request.sendall(b'203')print('一致.')return
else:
recv_size=0
self.request.sendall(str(file_size).encode())
resonse= self.request.recv(1024)
with open(file_path,'rb') as f:
f.seek(recv_size)whileTrue:
data= f.read(1024)if not data: breakself.request.sendall(data)else:
self.request.sendall(b'402')