Есть ли лучший способ для python почтового сервера обрабатывать файлы разных типов? - PullRequest
0 голосов
/ 03 августа 2020

У меня есть почтовый сервер, написанный на python3 .6.9, работающий на локальном хосте за обратным прокси-сервером apache2. Он получает файл base64, загруженный через Powershell, и декодирует их. Текстовые файлы сохраняются в каталоге ./Public/example.txt. Если байты загружены, он обрабатывает ошибку с помощью 'except binascii.Error', и я могу правильно записать ее в каталог. Оба типа файлов, сохраненные таким образом, делают это, взяв URI и заменив «/store.json» ничем. Если 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 я могу просто попробовать {поймать {$ _} свой путь через автоматизацию. Я долго искал, но не нашел способа слепо обрабатывать ошибки в python. Это всегда приводит к зависанию моего сервера. Мы будем очень благодарны за любую помощь или совет.

1 Ответ

0 голосов
/ 03 августа 2020

Прежде всего, добро пожаловать в SO.

Итак, несколько вещей, которые могут вам помочь. Люди обычно не используют python s 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")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...