LINUX.ORG.RU

загрузка файла на python с помощью CGIHTTPServer

 , ,


0

1

День добрый, возник такой вопрос. Ниже есть два варианта обработки POST запроса загрузки файла.

class Handler(CGIHTTPServer.CGIHTTPRequestHandler):
	def do_POST(self):
		form = cgi.FieldStorage(
			fp=self.rfile,
			headers=self.headers,
			environ={'REQUEST_METHOD':'POST',
				'CONTENT_TYPE':self.headers['Content-Type'],
			})
		length = int(self.headers['content-length'])
		data = form['file'].file.read(length)
		open("/tmp/file.a", "wb").write(data)
		self.send_response(200)
class Handler(CGIHTTPServer.CGIHTTPRequestHandler):
	def do_POST(self):
		length = int(self.headers['content-length'])
		data = self.rfile.read(int(length))
		with open("/tmp/file.b", "wb") as f:
			f.write(data)
		self.send_response(200)
Но в первом случае загрузка идёт очень медленно (на loopback скорость не превышает 900КБ/с), а во-втором на полной скорости (макисмум, что видел 100МБ/с). Но во-втором случае в начало файла дописываются куски заголовков:
------WebKitFormBoundaryNWzcRXF9BitXxqdz
Content-Disposition: form-data; name="file"; filename="debian-8.1.0-amd64-netinst.iso"
Content-Type: application/x-cd-image

Можно конечно, во-втором случае, парсить начало загрузки и пропускать до первой пустой строки, но как-то это не кошерно. Что можно сделать в обоих случаях?

Заранее спасибо.

★★★★★
Ответ на: комментарий от cyclon

Я не нашёл. Возможно, если ты опишешь свою проблему мы тебе подскажем более красивое решение. Например, если есть nginx то можно сделать вот так: https://coderwall.com/p/swgfvw/nginx-direct-file-upload-without-passing-them-...

Зачем вообще cgi понадобился?

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

Как ещё красиво убрать

------WebKitFormBoundaryNWzcRXF9BitXxqdz
Content-Disposition: form-data; name="file"; filename="debian-8.1.0-amd64-netinst.iso"
Content-Type: application/x-cd-image
в начале файла, и в конце
------WebKitFormBoundaryNWzcRXF9BitXxqdz
не используя временных файлов.

nginx не подходит, хотелось бы всю балалайку пускать без веб сервера, только на basehttpserver

cyclon ★★★★★
() автор топика
Последнее исправление: cyclon (всего исправлений: 1)
Ответ на: комментарий от true_admin

Будем посмотреть, пока скостылил так:

		count = 0
		size = 0
		content_length = int(self.headers['content-length'])
		boundary_length = len("--" + self.headers['Content-Type'].split('=')[-1:][0] + "--")
		f = open("/tmp/file", "wb")
		data = self.rfile.read(1)
		while data:
			size += 1
			if data == '\n':
				count += 1
			if count > 3:
				data = self.rfile.read(content_length - boundary_length - size - 4)
				f.write(data)
				data = None
			else:
				data = self.rfile.read(1)

cyclon ★★★★★
() автор топика
Ответ на: комментарий от cyclon

Проверь md5sum сохранённых файлов. Потому что вполне возможно оно там закодировано. Т.е. просто взять и отрезать по boundary может и не прокатить.

Хотя, я бы всё равно взял bottle.py. Ну просто потому что модуль cgi уже никто не использует.

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

Проверил, сходится, даже на 200Мб файле. Теперь cgi не нужен.

cyclon ★★★★★
() автор топика
Последнее исправление: cyclon (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.