首页 > 解决方案 > python post server是否有更好的方法来处理不同的文件类型?

问题描述

我有一个用 python3.6.9 编写的 post 服务器,在 apache2 反向代理后面的 localhost 上运行。它接收通过 Powershell 上传的 base64 文件并对其进行解码。文本文件被保存到目录 ./Public/example.txt。如果上传了字节,它会使用“除了 binascii.Error”来处理错误,我可以将其正确地写入目录。以这种方式保存的两种文件类型都是通过获取 URI 并将 '/store.json' 替换为空来实现的。如果 post 数据中不存在 FileName,则 'except IOError' 会将其写入当前目录中的 ./store.json。

这是主要代码:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Usage::
    ./server.py [<port>]
"""
from http.server import BaseHTTPRequestHandler, HTTPServer
import logging
import base64
import json
import os
import datetime
import binascii
from os import curdir
from optparse import OptionParser
from os.path import join as pjoin
from pathlib import Path

class S(BaseHTTPRequestHandler):
    store_path = pjoin(curdir, 'store.json')
    def _set_response(self):
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()

    def do_GET(self):
        logging.info("GET request,\nPath: %s\nHeaders:\n%s\n", str(self.path), str(self.headers))
        self._set_response()
        self.wfile.write("GET request for {}".format(self.path).encode('utf-8'))

    def do_POST(self):
        content_length = int(self.headers['Content-Length'])
        post_data = self.rfile.read(content_length)
        try:
            b64_string = post_data
            post_data = base64.b64decode(b64_string)
            logging.info("POST request,\nPath: %s\nHeaders:\n%s\n\nBody:\n%s\n",
                str(self.path), str(self.headers), post_data) #.decode('utf-8'))

        except binascii.Error as err:
            logging.info("POST request,\nPath: %s\nHeaders:\n%s\n\nBody:\n%s\n",
                str(self.path), str(self.headers), post_data.decode('utf-8'))

        path = str(self.path)
        store_path = pjoin(curdir, 'store.json')
        for char in ' /':
            path = path.replace(char,'')
        path = path.replace("store.json", "")
        dirname='/opt/server/Public/'
        filename = path
        path = Path(dirname, filename)
        try:
            log_file = open(path, "wb")
            log_file.write(post_data)
            log_file.close()
            print("Wrote contents to %s." % path)
        except IOError:
            f=open(store_path, "ab+")
            f.write(post_data)
            f.close()
            log_file = open(store_path, "a")
            log_file.write("\n")
            log_file.write("%s\n" % datetime.datetime.now())
            log_file.write("\n")
            log_file.close()
            print("Wrote contents to %s." % store_path)

        self._set_response()
        self.wfile.write("POST request for {}".format(self.path).encode('utf-8'))

我是使用python的初学者。我觉得这是一种处理文件的草率方式。有没有更好的方法来识别文件,而不会让我的服务器“错误”地做我想做的事?另外,我是否总是需要指定我要处理的错误?在 Powershell 中,我可以懒洋洋地尝试 { catch { $_ } 自动化。我找了一段时间,但还没有找到一种方法来盲目地处理python中的错误。它总是最终挂起我的服务器。任何帮助或建议将不胜感激。

标签: pythonposterror-handlingserver

解决方案


首先欢迎来到SO。

所以有几件事可以帮助你。人们通常不使用python HTTPServer,除非你想控制http请求和响应的下部。如果您想使用易于使用/设置的 http 服务器flask是一个不错的选择,因为它将处理解析 POST 数据以及在文件通过时保存文件。

Q1。有没有更好的方法来识别文件?

A1。这取决于。在上传文件的 http 请求期间,http 标准是上传文件名和扩展名以及文件的字节。如果您只上传字节,那么大多数 http 服务器将忽略它并返回错误。因此,如果您将名称和扩展名与字节一起发送,您就会知道它是什么类型的数据以及如何存储它。

base64也是一种编码。因此,了解编码是否良好(格式错误/丢失字节)的唯一方法是实际尝试对其进行解码,然后在找到任何错误时捕获它们。如果没有实际尝试解码数据,就无法询问它是否是有效编码。

Q2。你能盲目地处理python中的错误吗?

A2。是的,尽管不鼓励这样做,但您可以。

try:
   do_something()
except:
   print("I catch everything no matter what broke inside of this try")

推荐阅读