def wirte_result_data(self, source, request): """ 填充数据内容,并发送 """ try: if isinstance(source, file): request.write( MyChars.build_value_type_unicode_to_string(source.read())) else: global g_import_stringio_type type_string = str(type(source)) #print type_string if type_string.find(".StringO"): request.write( MyChars.build_value_type_unicode_to_string( source.getvalue())) else: rsp_string_data = MyChars.get_string_value( MyChars.STRING_REQUEST_RENDER_ERROR_READ_VALUE_ERROR) request.write( MyChars.build_value_type_unicode_to_string( rsp_string_data)) except Exception, e: rsp_string_data = MyChars.get_string_value( MyChars.STRING_REQUEST_RENDER_ERROR_READ_VALUE_ERROR) request.write( MyChars.build_value_type_unicode_to_string(rsp_string_data))
def process_response_status_code(self): """ 实现响应指定状态码功能模块 """ run_method_flag = False #获取用户权限验证是否打开 rc_enble_status, rc_data = self._get_response_status_code_value() #将请求传递到后续处理模块 if 0 == rc_enble_status: run_method_flag = False #获取属性数据错误 elif -1 == rc_enble_status: #服务器内部错误 self._internal_server_error(e) run_method_flag = True else: #响应固定状态码 rsp_string_data = "Response status code:[%d]" % int(rc_data) #设置响应消息常规头数据 self._construct_response_header(int(rc_data), "text/html; charset=utf-8", str(len(rsp_string_data))) self.write( MyChars.build_value_type_unicode_to_string(rsp_string_data)) self.finish() run_method_flag = True return run_method_flag
def render_POST(self, request): """ POST响应接口 """ r, info = self.deal_post_data(request) f = StringIO() f.write('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">') f.write( '<html>\n<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head>\n<title>Upload Result Page</title>\n' ) f.write('<body>\n<h2>Upload Result Page</h2>\n') f.write('<hr>\n') if r: f.write("<strong>Success:</strong>") else: f.write("<strong>Failed:</strong>") f.write(MyChars.build_value_type_unicode_to_string(info)) f.write("<br><a href=\"%s\">back</a>" % request.getHeader('referer')) f.write("<hr><small>Powered By: bones7456, check new version at ") f.write("<a href=\"http://li2z.cn/?s=SimpleHTTPServerWithUpload\">") f.write("here</a>.</small></body>\n</html>\n") length = f.tell() f.seek(0) request.setResponseCode(200) request.setHeader("Content-type", "text/html; charset=utf-8") request.setHeader("Content-Length", str(length)) if f: self.wirte_result_data(f, request) f.close()
def _internal_server_error(self, except_e): """ 服务器内部错误响应 """ log.debug_info(type(except_e)) log.debug_info(except_e) #服务器内部错误 rsp_string_data = MyChars.get_string_value( MyChars.STRING_REQUEST_PROCESS_500_ERROR) log.debug_info(rsp_string_data) #获取返回数据长度 rsp_string_data_length = len( MyChars.build_value_type_unicode_to_string(rsp_string_data)) #设置响应消息常规头数据 self._construct_response_header(http.INTERNAL_SERVER_ERROR, "text/html; charset=utf-8", str(rsp_string_data_length)) self.write(MyChars.build_value_type_unicode_to_string(rsp_string_data)) self.finish()
def process_authorization_basic(self): """ basic权限验证 """ #读取用户账户信息 client_username = self.getUser() client_password = self.getPassword() if client_username: log.debug_info(u"%s" % client_username) log.debug_info(u"%s" % client_password) #验证用户权限,如果有权限则处理客户端具体数据请求 self.basic_authorization_handle_login(client_username, client_password) else: #未授权的 rsp_string_data = MyChars.get_string_value( MyChars.STRING_REQUEST_PROCESS_401_ERROR) #获取返回数据长度 rsp_string_data_length = len( MyChars.build_value_type_unicode_to_string(rsp_string_data)) #设置响应消息常规头数据 self._construct_response_header(http.UNAUTHORIZED, "text/html; charset=utf-8", str(rsp_string_data_length)) #未授权的, 构建Basic认证返回信息 self.setHeader("WWW-Authenticate", self._construct_auth_basic_response()) self.write( MyChars.build_value_type_unicode_to_string(rsp_string_data)) self.finish()
def render_PUT(self, request): """ PUT响应接口 """ r, info = self.deal_put_data(request) f = StringIO() f.seek(0) f.write(MyChars.build_value_type_unicode_to_string(info)) request.setResponseCode(200) request.setHeader("Content-Length", 0) if f: self.wirte_result_data(f, request) f.close()
def _loginFailed(self, failure): """ 用户登录失败 """ log.debug_info(u"_loginFailed: %s" % failure.getErrorMessage()) rsp_string_data = str(failure.getErrorMessage()) #构建常规响应消息头 self._construct_response_header(http.UNAUTHORIZED, "text/html; charset=utf-8", str(len(rsp_string_data))) #未授权的, 构建Basic认证返回信息 self.setHeader("WWW-Authenticate", self._construct_auth_basic_response()) self.write(MyChars.build_value_type_unicode_to_string(rsp_string_data)) self.finish()
def process_authorization(self): """ 进行权限验证 """ #获取客户端请求认证头数据 authorization_data = self.getHeader('authorization') #获取服务器设置的默认认证模式 rc_status, temp_cfg_client_authorization_type = self._get_client_authorization_string( ) #识别认证类型状态, # ---- 0是初始化状态,表示没有找到认证消息头, # ---- -1表示不识别类型, # ---- -2表示识别类型不匹配, # ---- 1表示识别类型成功 temp_check_authorization_type_state = 0 if authorization_data: #读取客户端请求消息认证头认证类型数据 temp_request_authorization_type = None if 0 == authorization_data.find('Digest'): temp_request_authorization_type = 'Digest' elif 0 == authorization_data.find('Basic'): temp_request_authorization_type = 'Basic' if not temp_request_authorization_type: #不识别认证类型 temp_check_authorization_type_state = -1 else: #配置的认证类型与客户端请求认证类型相同 if (temp_request_authorization_type == temp_cfg_client_authorization_type): #识别类型成功 temp_check_authorization_type_state = 1 #'Digest'认证 if ('Digest' == temp_request_authorization_type): self.process_authorization_digest(authorization_data) #Basic认证 else: self.process_authorization_basic() return else: #不匹配认证类型 temp_check_authorization_type_state = -2 #认证不成功,构造认证失败的消息给客户端响应 if 1 != temp_check_authorization_type_state: rsp_string_data = '401 Unauthorized' #未找到验证头数据 if 0 == temp_check_authorization_type_state: rsp_string_data = MyChars.get_string_value( MyChars.STRING_REQUEST_PROCESS_401_ERROR) #不识别认证类型 elif -1 == temp_check_authorization_type_state: rsp_string_data = MyChars.get_string_value( MyChars.STRING_REQUEST_PROCESS_DOES_NOT_RECOGNIZE_AUTH_TYPE ) #不匹配认证类型 else: rsp_string_data = MyChars.get_string_value( MyChars. STRING_REQUEST_PROCESS_AUTH_TYPE_IS_NOT_CONFIGURED_MODE) #回响应数据给客户端请求 log.debug_info(rsp_string_data) #获取返回数据长度 rsp_string_data_length = len( MyChars.build_value_type_unicode_to_string(rsp_string_data)) #设置响应消息常规头数据 self._construct_response_header(http.UNAUTHORIZED, "text/html; charset=utf-8", str(rsp_string_data_length)) #未授权的, 构建Basic/Digest认证返回信息, 默认为Basic if 'Digest' == temp_cfg_client_authorization_type: self.setHeader("WWW-Authenticate", self._construct_auth_digest_response()) else: self.setHeader("WWW-Authenticate", self._construct_auth_basic_response()) self.write( MyChars.build_value_type_unicode_to_string(rsp_string_data)) self.finish() return
def process_dispath_request(self): """ 处理客户端具体数据请求 """ #调用响应指定状态码功能模块 rc_run_method_flag = self.process_response_status_code() if rc_run_method_flag: return #处理上传类型 rc_status, temp_cfg_client_upload_type = self._get_client_upload_type_string( ) if (not rc_status or ("GET" != self.method and "BOTH" != temp_cfg_client_upload_type and self.method != temp_cfg_client_upload_type)): #上传类型错误 rsp_string_data = MyChars.get_string_value( MyChars. STRING_REQUEST_PROCESS_UPLOAD_TYPE_IS_NOT_CONFIGURED_MODE) #获取返回数据长度 rsp_string_data_length = len( MyChars.build_value_type_unicode_to_string(rsp_string_data)) #设置响应消息常规头数据 self._construct_response_header(http.NOT_ALLOWED, "text/html; charset=utf-8", str(rsp_string_data_length)) self.write( MyChars.build_value_type_unicode_to_string(rsp_string_data)) self.finish() return #处理消息正常流程 self.site = self.channel.factory.site if self.method == "PUT": self.site.render_PUT(self) elif self.method == "POST": self.site.render_POST(self) elif self.method == "GET": self.site.render_GET(self) else: #方法不支持 rsp_string_data = MyChars.get_string_value( MyChars.STRING_REQUEST_PROCESS_405_ERROR) #获取返回数据长度 rsp_string_data_length = len( MyChars.build_value_type_unicode_to_string(rsp_string_data)) #设置响应消息常规头数据 self._construct_response_header(http.NOT_ALLOWED, "text/html; charset=utf-8", str(rsp_string_data_length)) self.write( MyChars.build_value_type_unicode_to_string(rsp_string_data)) self.finish()
def process_authorization_digest(self, authorization_data): """ 调用digest权限验证 """ #保存验证状态,-1表示账户未注册,-2表示密码认证失败 check_request_digest_authorization_stauts = 0 #解析客户端digest认证数据 request_auth_digest_data_dict = DigestAuthorization.parse_request_digest_authorization_data( authorization_data, self.method) #print request_auth_digest_data_dict #查找用户名是否注册,并返回注册的密码数据 client_request_username = request_auth_digest_data_dict.get('username') rc_status, rc_client_register_password = self._get_digest_authorization_uername_register_password( client_request_username) if not rc_status: #账户未注册 check_request_digest_authorization_stauts = -1 else: #配置约定数据 cfg_auth_digest_option = {} cfg_auth_digest_option['username'] = client_request_username cfg_auth_digest_option['password'] = rc_client_register_password cfg_auth_digest_option['realm'] = CFG_AUTH_RELM_VALUE #进行客户端digest权限验证 check_suc_flag = DigestAuthorization.check_digest_authorization_data( cfg_auth_digest_option, request_auth_digest_data_dict) if check_suc_flag: #权限认证通过 check_request_digest_authorization_stauts = 1 #处理客户端具体数据请求 self.process_dispath_request() else: #密码认证失败 check_request_digest_authorization_stauts = -2 #授权不成功 if 1 != check_request_digest_authorization_stauts: if -2 == check_request_digest_authorization_stauts: #授权不成功 rsp_string_data = MyChars.get_string_value( MyChars.STRING_REQUEST_PROCESS_401_ERROR) else: #账户未注册 rsp_string_data = MyChars.get_string_value( MyChars.STRING_REQUEST_CRED_NO_SUCH_USER) #获取返回数据长度 rsp_string_data_length = len( MyChars.build_value_type_unicode_to_string(rsp_string_data)) #设置响应消息常规头数据 self._construct_response_header(http.UNAUTHORIZED, "text/html; charset=utf-8", str(rsp_string_data_length)) #未授权的, 构建Digest认证返回信息 self.setHeader("WWW-Authenticate", self._construct_auth_digest_response()) self.write( MyChars.build_value_type_unicode_to_string(rsp_string_data)) self.finish()
def list_directory(self, path, request): """ 创建一个以目录列表文件为数据来源的HTML文件,并将数据流句柄做为返回值 """ try: list_dir_data = os.listdir(path) except os.error: request.setResponseCode(http.NOT_FOUND) rsp_string_data = MyChars.get_string_value( MyChars. STRING_REQUEST_RENDER_ERROR_NO_PERMISSION_TO_LIST_DIRECTORY) request.write( MyChars.build_value_type_unicode_to_string(rsp_string_data)) request.finish() return None #排序文件列表 list_dir_data.sort(key=lambda a: a.lower()) #构建HTML文件 f = StringIO() displaypath = cgi.escape(urllib.unquote(self.path)) #add by wangjun 20131224 displaypath_string = MyChars.convert_coding(displaypath) if isinstance(displaypath_string, unicode): displaypath_string = displaypath_string.encode("utf8") #写HTML TITLE数据 f.write('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">') f.write( '<html>\n<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head>\n<title>Directory listing for %s</title>\n' % displaypath_string) f.write('<body>\n<h2>Directory listing for %s</h2>\n' % displaypath_string) f.write('<hr>\n') """ #写HTML表单数据(upload) f.write("<form ENCTYPE=\"multipart/form-data\" method=\"post\">") f.write("<input name=\"file\" type=\"file\"/>") f.write("<input type=\"submit\" value=\"upload\"/>") f.write("              ") f.write("<input type=\"button\" value=\"HomePage\" onClick=\"location='/'\">") f.write("</form>\n") f.write("<hr>\n<ul>\n") """ #写文件列表数据 #这里数据节点的数据全部为str类型 for name in list_dir_data: try: fullname = os.path.join(path, name) #获取文件是否文件夹属性 temp_isdir_flag = os.path.isdir(fullname) #获取文件是否连接的属性 temp_islink_flag = os.path.islink(fullname) #转换编码格式 if isinstance(name, unicode): name = name.encode("utf8") #[step-1] temp_workspace_dir = MyChars.convert_coding( self.home_workspace_dir) if isinstance(temp_workspace_dir, unicode): temp_workspace_dir = temp_workspace_dir.encode("utf8") filename = temp_workspace_dir + '/' + displaypath + name #转化编码格式 filename = MyChars.convert_coding(filename) #获取文件长度 file_size = sizeof_fmt(os.path.getsize(filename)) #获取文件修改日期 modif_date = modification_date(filename) #[step-2] colorName = name linkname = name #追加文件和连接 if temp_isdir_flag: colorName = '<span style="background-color: #CEFFCE;">' + name + '/</span>' linkname = name + "/" if temp_islink_flag: colorName = '<span style="background-color: #FFBFFF;">' + name + '@</span>' #文件显示名称 if isinstance(colorName, unicode): colorName = colorName.encode("utf8") #文件或文件夹连接地址 url_item = urllib.quote(copy.deepcopy(linkname)) #将数据写入到HTML数据体中 f.write( '<table><tr><td width="60%%"><a href="%s">%s</a></td><td width="20%%">%s</td><td width="20%%">%s</td></tr>\n' % (url_item, colorName, file_size, modif_date)) except Exception, e: log.debug_info(u"MyRenderPage:list_directory coding error")
def deal_get_data(self, request): """ GET方法数据处理方法 """ #获取文件地址信息 self.path = request.path path = self.translate_path(self.path, request) f = None #转化编码格式 path = MyChars.convert_coding(path) if os.path.isdir(path): if not self.path.endswith('/'): #重定向浏览器 request.setResponseCode(301) request.setHeader("Location", self.path + "/") rsp_string_data = MyChars.get_string_value( MyChars. STRING_REQUEST_RENDER_ERROR_NO_PERMISSION_TO_LIST_DIRECTORY ) request.write( MyChars.build_value_type_unicode_to_string( rsp_string_data)) request.finish() return None #文件地址下是否存在index HTML文件 for index in "index.html", "index.htm": index = os.path.join(path, index) if os.path.exists(index): path = index break else: #创建一个以目录列表文件为数据来源的HTML文件,并将数据流句柄做为返回值 return self.list_directory(path, request) #获取文件类型,获取到的数据用于MIME Content-type头 ctype = self.guess_type(path) #初始化f文件句柄 try: f = open(path, 'rb') except IOError: request.setResponseCode(http.NOT_FOUND) rsp_string_data = MyChars.get_string_value( MyChars.STRING_REQUEST_RENDER_404_ERROR) request.write( MyChars.build_value_type_unicode_to_string(rsp_string_data)) request.finish() return None #获取文件的大小,以位为单位 fs = os.fstat(f.fileno()) request.setResponseCode(200) request.setHeader("Content-type", "%s; charset=utf-8" % ctype) request.setHeader("Content-Length", str(fs[6])) last_modified_data = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(fs.st_mtime)) request.setHeader("Last-Modified", last_modified_data) return f