Python从multipart / form-data原始套接字解码文件

时间:2019-06-28 22:16:33

标签: python sockets http decode

我正在尝试使用原始套接字获取multipart / form-data。它适用于常规输入,但是当我实现文件类型输入时,我会得到

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x89 in position x: invalid start byte

错误

表单代码

<form action="/login" method="POST" enctype="multipart/form-data">
    <input type="text" name="username" placeholder="Username">
    <input type="password" name="password" placeholder="Password">
    <input type="file" name="files">
    <input type="submit" name="submit" value="Login">
</form>

recv func

    request = conn.recv(10240).decode()

1 个答案:

答案 0 :(得分:0)

request = conn.recv(10240).decode()

此代码假定您在一次读取中得到了完整的正文。但是recv不能保证这一点。相反,在您的情况下,呼叫只会返回最多 10240字节。实际的字节数取决于发送的数据量,如何在网络上对它们进行打包,套接字缓冲区有多大以及已经接收(并放入套接字缓冲区)有多少数据。

正确的方法是预先知道要读取多少数据,然后使用多个recv调用直到读取所有数据。这意味着您需要先阅读HTTP标头以提取content-length标头,其中包含正文中的字节数。从理论上讲,您还需要处理分块传输编码,但是浏览器在您的特定情况下不使用此编码。

除此之外,您得到的不是特定编码的字节。这意味着直接使用decode也是错误的。取而代之的是,您需要根据标头(即MIME边界)中的信息将多部分MIME消息解析为各个部分,然后decode可以 <div class="ui-g-12"> <p-checkbox name="categories" value="Science Fiction" label="Science Fiction" [(ngModel)]="selectedCategories" (onChange)="categoryFilterSelect()" ></p-checkbox> </div> <div class="ui-g-12"> <p-checkbox name="categories" value="Horror" label="Horror" [(ngModel)]="selectedCategories" (onChange)="categoryFilterSelect()" ></p-checkbox> </div> <div class="ui-g-12"> <p-checkbox name="categories" value="Suspense" label="Suspense" [(ngModel)]="selectedCategories" (onChange)="categoryFilterSelect()" ></p-checkbox> </div> <div class="ui-g-12"> <p-checkbox name="categories" value="Romance" label="Romance" [(ngModel)]="selectedCategories" (onChange)="categoryFilterSelect()" ></p-checkbox> </div> <div class="ui-g-12"> <p-checkbox name="categories" value="Action" label="Action" [(ngModel)]="selectedCategories" (onChange)="categoryFilterSelect()" ></p-checkbox> </div> <div style="margin-top: 10%"> <router-outlet></router-outlet> </div> ,但仅当这些值实际编码时才可以。例如,上传的文件不应被解码,而应视为字节。如您所愿,甚至其他值也可能未在utf-8中进行编码-确切的编码取决于您使用的HTML,并且您显示的代码段并未提供足够的信息。

通常:除非您真的了解相关标准(HTTP和MIME),否则最好使用现有的库。而且,如果您了解相关的标准,那么您将很可能也会使用现有的库,因为您已经意识到这些标准的复杂性,并且自己独自解决所有这些极端情况将浪费时间。