【问题标题】:Why is my request returning incomplete multipart?为什么我的请求返回不完整的多部分?
【发布时间】:2021-06-11 13:12:27
【问题描述】:

我正在使用我的 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>

【问题讨论】:

  • 不要使用strlen 计算Content-Length,因为strlen 返回字符数,您需要字节数(这对于unicode/utf-8 尤其重要)。

标签: arduino jetty multipartform-data multipart


【解决方案1】:

您的Content-Length 计算值得怀疑。

删除多部分中每个子部分的Content-Length 标头,然后重试,多部分不需要这些标头,而且无论如何您的计算都是错误的。

您可以在 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 多部分部分。

【讨论】:

  • 您好,谢谢您的回复。我删除了Content-Length 标头,但是不幸的是,来自服务器的响应仍然是多部分不完整。我也查看了来自 github 的示例,它们似乎与我的要求相似。
  • 您仍然需要修复主要的 HTTP Content-Length 请求标头。它为 http 请求的正文计算不正确。 (记住这是字节数,而不是字符数)帮自己一个忙,使用 Wireshark 之类的工具捕获请求/响应流量,它会为您突出显示问题(例如错误的内容长度标头)
猜你喜欢
  • 2021-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-12
  • 2018-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多