为什么我的请求返回不完整的多部分?

问题描述

我正在使用我的 Arduino 执行多部分/表单数据请求。我完全自己生成请求如下:

client.println(HTTP_METHOD + " " + PATH_NAME + " HTTP/1.1");
    client.println("Host: " + String(HOST_NAME));
  
    client.print(F("Content-Type: multipart/form-data; "));
    client.print(F("boundary=\"AaB03x\"\r\n"));
    client.print(F("Content-Length: "));
    client.print(strlen("{json data here}") 
    + strlen("{json data here}"));
    client.print("\r\nConnection: close\r\n");
    // First part 

    // Boundary 
    client.print(F("\r\n--AaB03x\r\n"));

    // Headers
    client.print(F("Content-disposition: form-data; name=\"header\"\r\n"));
    client.print(F("Content-Type: application/ld+json\r\n"));
    client.print(F("Content-Length: "));
    client.print(strlen("{json data here}"));
    client.print(F("\r\n\r\n"));

    // Content 
    client.print(F("{json data here}"));

    // Second part 

    // Boundary 
    client.print(F("\r\n--AaB03x\r\n"));

    // Headers
    client.print(F("Content-disposition: form-data; name=\"payload\"\r\n"));
    client.print(F("Content-Type: application/ld+json\r\n"));//
    client.print(F("Content-Length: "));
    client.print(strlen("{json data here}"));
    client.print(F("\r\n\r\n"));

    // Content 
    client.print(F("{json data here}"));

    // End of boundary 
    client.print(F("\r\n--AaB03x--\r\n\r\n"));

但是服务器返回“不完整的多部分”,我不明白,因为多部分似乎完全没问题。我认为这可能是由于换行不正确,但我一直无法找到解决方案。

输出如下所示,包括发送的请求以及来自服务器的响应。

GET /router HTTP/1.1
Host: 192.168.178.147
Content-Type: multipart/form-data; boundary="AaB03x"
Content-Length: 4363
Connection: close

--AaB03x
Content-disposition: form-data; name="header"
Content-Type: application/ld+json
Content-Length: 4143

{
   some data here
}
--AaB03x
Content-disposition: form-data; name="payload"
Content-Type: application/ld+json
Content-Length: 220

{
   some data here
}
--AaB03x--

connected to 192.168.178.147
HTTP/1.1 500 Server Error
Connection: close
Cache-Control: must-revalidate,no-cache,no-store
Content-Type: text/html;charset=iso-8859-1
Content-Length: 597
Server: Jetty(9.4.41.v20210516)

<html>
<head>
<Meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>Error 500 Server Error</title>
</head>
<body><h2>HTTP ERROR 500 Server Error</h2>
<table>
<tr><th>URI:</th><td>/router</td></tr>
<tr><th>STATUS:</th><td>500</td></tr>
<tr><th>MESSAGE:</th><td>Server Error</td></tr>
<tr><th>SERVLET:</th><td>org.apache.camel.component.jetty.CamelContinuationServlet-38cb1606</td></tr>
<tr><th>CAUSED BY:</th><td>java.io.IOException: Incomplete Multipart</td></tr>
</table>
<hr><a href="https://eclipse.org/jetty">Powered by Jetty:// 9.4.41.v20210516</a><hr/>

</body>
</html>

解决方法

您的 Content-Length 计算令人怀疑。

删除 multipart 中每个子部分的 Content-Length 标题并重试,multipart 不需要这些标题,无论如何您的计算都是错误的。

您可以在 Jetty 测试中看到来自各种库和浏览器的各种多部分请求的捕获。

https://github.com/eclipse/jetty.project/tree/jetty-9.4.41.v20210516/jetty-http/src/test/resources/multipart

(看看以*.raw结尾的,一般可以用文本编辑器打开)

提示:不要自己做这件事,多部分 mime 充满了边缘情况、陷阱和古老的技巧。去获取 apache httpcomponents httpmime jar 并使用它来正确生成原始 mime 多部分部分。