如果使用HTTP/1.1,模拟S3服务器将暂停

2024-05-18 05:12:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在编写一个测试,其中使用http.server.HTTPServer/http.server.BaseHTTPRequestHandler在测试环境中加载一个简单的模拟S3,以测试涉及Boto的S3Transfer的多部分下载行为。你知道吗

它工作正常,除非我指定服务器使用HTTP/1.1。在这种情况下,它将下载一个100mb文件的28MB部分,然后挂起。我希望模拟服务器使用HTTP/1.1,因为这是真正的S3使用的(我相信)。你知道吗

下面是测试的简化版本,可以由。。。你知道吗

pip3 install boto3
python3 test.py    

# test.py

import http.server
import re
import threading

import boto3
from botocore import (
    UNSIGNED,
)
from botocore.client import (
    Config,
)

length = 100 * 2**20

class MockS3(http.server.BaseHTTPRequestHandler):
    # If the below line is commented, the download completes
    protocol_version = 'HTTP/1.1'

    def do_GET(self):
        range_header = self.headers['Range']
        match = re.search(r'^bytes=(\d+)-(\d*)', range_header)
        start_inclusive_str, end_inclusive_str = match.group(1), match.group(2)
        start = int(start_inclusive_str)
        end = int(end_inclusive_str) + 1 if end_inclusive_str else length
        bytes_to_send = end - start

        self.send_response(206)
        self.send_header('Content-Length', str(bytes_to_send))
        self.end_headers()
        self.wfile.write(bytearray(bytes_to_send))

    def do_HEAD(self):
        self.send_response(200)
        self.send_header('Content-Length', length)
        self.end_headers()

server_address = ('localhost', 5678)
server = http.server.HTTPServer(server_address, MockS3)
thread = threading.Thread(target=server.serve_forever)
thread.daemon = True
thread.start()

class Writable():
    def write(self, data):
        pass

s3_client = boto3.client('s3',
  endpoint_url='http://localhost:5678',
  config=Config(signature_version=UNSIGNED),
)

s3_client.download_fileobj(
  Bucket='some',
  Key='key',
  Fileobj=Writable(),
)

注意Writable故意可查找:在我的实际代码中,我使用的是一个不可查找的类似文件的对象。你知道吗

是的,moto可以用来制作一个模拟S3,对于其他测试,我也是这样做的,但是对于这个特定的测试,我想要“真正的”服务器。涉及到自定义文件对象,希望确保S3Transfer和其他与此问题无关的代码按照我的预期一起工作。你知道吗

如何设置使用HTTP/1.1的模拟S3服务器,并且S3Transfer可以从中下载?你知道吗


Tags: importself服务器clientsendhttpbytess3
1条回答
网友
1楼 · 发布于 2024-05-18 05:12:04

线程逻辑中存在错误。您当前所做的是在一个单独的线程上提供服务,但您真正想做的是在多个线程上并发处理请求。你知道吗

这可以通过创建一个非常愚蠢的HTTP服务器来实现,它只是混合了线程功能:

class ThreadingServer(ThreadingMixIn, HTTPServer):
    pass

从这个服务器而不是从基本服务器服务。你知道吗

至于为什么这适用于HTTP/1.0,连接是在一个请求被服务后关闭的。你知道吗

相关问题 更多 >