Cisco ThreatGrid 提交示例 API... 我如何发送示例文件?
Cisco ThreatGrid Submit Sample API... How do I send a Sample File?
我无法使用 Java 成功调用 ThreatGrid 提交示例 API。我过去曾使用 Java 调用 API,因此我有设置这些调用的经验。
我应该发布到 https://panacea.threatgrid.com/api/v2/samples 并在我的请求的 body 中提供参数。
我还需要将示例文件(正在评估的文件)写入请求的body。
我知道我需要将 'Content-Type' 设置为 'multipart/form-data;' 并提供一个边界字符串来分隔请求的各个部分。
调用提交 API 后,我收到 HTTP 400 错误请求,错误如下 return:
{"api_version":2,"id":7162013,"error":{"message":"The parameter sample is required. ","code":400,"errors":[{"code":400,"message":"The parameter sample is required. ","help":"/doc/main/index.html","report":"support@threatgrid.com"}]}}
这是说我没有提供'sample'参数。样本是提交用于威胁评估的文件。请注意,我在请求 body 中发送的第二部分(数据部分)的名称为 'sample'.
以下是我在连接中设置请求 headers 的方式:
connection.addRequestProperty("Content-Type", "multipart/form-data; boundary=BOUNDARY");
connection.addRequestProperty("cache-control", "no-cache");
connection.addRequestProperty("accept", "*/*");
connection.addRequestProperty("Content-Length", "164784" );
connection.addRequestProperty("Host", "panacea.threatgrid.com");
这是我认为我正在写入连接输出流的示例:
--BOUNDARY
Content-Disposition: form-data; name="application/json"
{"private":"true","vm":"win7-x64","email_notification":false}
--BOUNDARY
Content-Disposition: form-data; name="sample"; filename="GracePeriod.pdf"
Content-Type: application/pdf
[Bytes of the Sample File being submitted to ThreatGrid api]
--BOUNDARY--
构建我请求的 body 的代码:
String boundaryString = "BOUNDARY";
String LINE_FEED = "\r\n";
File sampleFileToUpload = new File(fileUrl);
outputStream.writeBytes(LINE_FEED);
outputStream.writeBytes(LINE_FEED);
outputStream.writeBytes("--" + boundaryString);
outputStream.writeBytes(LINE_FEED);
outputStream.writeBytes(LINE_FEED);
outputStream.writeBytes("Content-Disposition: form-data; name=\"application/json\"");
outputStream.writeBytes(LINE_FEED);
// Build the parameters that get placed into the Header
Map<String, Object> headers = new HashMap<String, Object>();
headers.put("private", "true");
headers.put("vm", "win7-x64");
headers.put("email_notification", false);
Gson gson = new Gson();
String body = gson.toJson(headers);
outputStream.writeBytes( body );
outputStream.writeBytes(LINE_FEED);
outputStream.writeBytes(LINE_FEED);
outputStream.writeBytes("--" + boundaryString);
outputStream.writeBytes(LINE_FEED);
outputStream.writeBytes(LINE_FEED);
outputStream.writeBytes("Content-Disposition: form-data; name='sample'; filename='"+sampleFileToUpload.getName()+"'");
outputStream.writeBytes(LINE_FEED);
outputStream.writeBytes("Content-Type: application/pdf");
outputStream.writeBytes(LINE_FEED);
outputStream.writeBytes(LINE_FEED);
// Write the contents of the file being submitted...
FileInputStream inputStream = new FileInputStream(sampleFileToUpload);
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] dataArray = new byte[16384];
while ((nRead = inputStream.read(dataArray, 0, dataArray.length)) != -1) {
buffer.write(dataArray, 0, nRead);
}
buffer.flush();
byte[] bytes = buffer.toByteArray();
inputStream.close();
outputStream.write(bytes);
outputStream.writeBytes(LINE_FEED);
outputStream.writeBytes(LINE_FEED);
outputStream.writeBytes("--" + boundaryString + "--");
outputStream.writeBytes(LINE_FEED);
outputStream.writeBytes(LINE_FEED);
outputStream.flush();
outputStream.close();
我应该收到 HTTP 200 消息和包含有关我提交的详细信息的响应消息。
希望有人以前做过这个并且可以告诉我我的方法中的错误。
谢谢!
编辑:我忘了说我可以使用 Postman 应用程序来设置并成功调用 API。我将请求的body中的'private'、'vm'、'email_notification'和'sample'项设置为form-data。 Postman 允许您将这些项目设置为文本或文件(有一个下拉菜单)。在 'sample' 的情况下,我将其设置为文件,Postman 允许我 'attach' 该文件。我使用 Postman 控制台查看请求中发送的内容,并尝试在我的 Java 代码中尽可能地模拟它。肯定还有我需要的其他细节,但 Postman 没有在控制台中向我显示。
我终于能够(头有点血)让 API 成功响应(HTTP 200 消息)。如果这对以后的任何人都有帮助,我将提供使它起作用的详细信息。
在查看 API 的定义时,它指出 "The request parameters are to encoded as 'multipart/form-data'"。我将一些参数作为 JSON 数据发送。我决定我需要将每个参数作为一个单独的表单变量发送,每个参数由一个边界标记分隔(我之前尝试过一次,但我又回到了同样的想法)。
这样做之后,我开始注意请求正文中每个项目之后的空格 (CRLF) 的细节。 API 对正文中数据的格式非常敏感。我发现它在您发送的表单数据的实际值之前需要一个 CRLF。
这是我发送的请求正文示例:
--BOUNDARY
Content-Disposition: form-data; name="private"
[CRLF (a space)]
true
--BOUNDARY
Content-Disposition: form-data; name="vm"
[CRLF (a space)]
win7-x64
--BOUNDARY
Content-Disposition: form-data; name="email_notification"
[CRLF (a space)]
false
--BOUNDARY
Content-Disposition: form-data; name="sample";
filename="CourseCompletionCertificate.pdf"
Content-Type: application/pdf
[CRLF (a space)]
[data stream of the Sample file in a byte array...]
--BOUNDARY--
我找到了 multipart/form-data 的例子,我注意到数据中使用了 CRLF,我尽力复制了数据的发送方式。正是在那个细节之后,API 成功响应。
我无法使用 Java 成功调用 ThreatGrid 提交示例 API。我过去曾使用 Java 调用 API,因此我有设置这些调用的经验。
我应该发布到 https://panacea.threatgrid.com/api/v2/samples 并在我的请求的 body 中提供参数。
我还需要将示例文件(正在评估的文件)写入请求的body。
我知道我需要将 'Content-Type' 设置为 'multipart/form-data;' 并提供一个边界字符串来分隔请求的各个部分。
调用提交 API 后,我收到 HTTP 400 错误请求,错误如下 return:
{"api_version":2,"id":7162013,"error":{"message":"The parameter sample is required. ","code":400,"errors":[{"code":400,"message":"The parameter sample is required. ","help":"/doc/main/index.html","report":"support@threatgrid.com"}]}}
这是说我没有提供'sample'参数。样本是提交用于威胁评估的文件。请注意,我在请求 body 中发送的第二部分(数据部分)的名称为 'sample'.
以下是我在连接中设置请求 headers 的方式:
connection.addRequestProperty("Content-Type", "multipart/form-data; boundary=BOUNDARY");
connection.addRequestProperty("cache-control", "no-cache");
connection.addRequestProperty("accept", "*/*");
connection.addRequestProperty("Content-Length", "164784" );
connection.addRequestProperty("Host", "panacea.threatgrid.com");
这是我认为我正在写入连接输出流的示例:
--BOUNDARY
Content-Disposition: form-data; name="application/json"
{"private":"true","vm":"win7-x64","email_notification":false}
--BOUNDARY
Content-Disposition: form-data; name="sample"; filename="GracePeriod.pdf"
Content-Type: application/pdf
[Bytes of the Sample File being submitted to ThreatGrid api]
--BOUNDARY--
构建我请求的 body 的代码:
String boundaryString = "BOUNDARY";
String LINE_FEED = "\r\n";
File sampleFileToUpload = new File(fileUrl);
outputStream.writeBytes(LINE_FEED);
outputStream.writeBytes(LINE_FEED);
outputStream.writeBytes("--" + boundaryString);
outputStream.writeBytes(LINE_FEED);
outputStream.writeBytes(LINE_FEED);
outputStream.writeBytes("Content-Disposition: form-data; name=\"application/json\"");
outputStream.writeBytes(LINE_FEED);
// Build the parameters that get placed into the Header
Map<String, Object> headers = new HashMap<String, Object>();
headers.put("private", "true");
headers.put("vm", "win7-x64");
headers.put("email_notification", false);
Gson gson = new Gson();
String body = gson.toJson(headers);
outputStream.writeBytes( body );
outputStream.writeBytes(LINE_FEED);
outputStream.writeBytes(LINE_FEED);
outputStream.writeBytes("--" + boundaryString);
outputStream.writeBytes(LINE_FEED);
outputStream.writeBytes(LINE_FEED);
outputStream.writeBytes("Content-Disposition: form-data; name='sample'; filename='"+sampleFileToUpload.getName()+"'");
outputStream.writeBytes(LINE_FEED);
outputStream.writeBytes("Content-Type: application/pdf");
outputStream.writeBytes(LINE_FEED);
outputStream.writeBytes(LINE_FEED);
// Write the contents of the file being submitted...
FileInputStream inputStream = new FileInputStream(sampleFileToUpload);
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] dataArray = new byte[16384];
while ((nRead = inputStream.read(dataArray, 0, dataArray.length)) != -1) {
buffer.write(dataArray, 0, nRead);
}
buffer.flush();
byte[] bytes = buffer.toByteArray();
inputStream.close();
outputStream.write(bytes);
outputStream.writeBytes(LINE_FEED);
outputStream.writeBytes(LINE_FEED);
outputStream.writeBytes("--" + boundaryString + "--");
outputStream.writeBytes(LINE_FEED);
outputStream.writeBytes(LINE_FEED);
outputStream.flush();
outputStream.close();
我应该收到 HTTP 200 消息和包含有关我提交的详细信息的响应消息。
希望有人以前做过这个并且可以告诉我我的方法中的错误。
谢谢!
编辑:我忘了说我可以使用 Postman 应用程序来设置并成功调用 API。我将请求的body中的'private'、'vm'、'email_notification'和'sample'项设置为form-data。 Postman 允许您将这些项目设置为文本或文件(有一个下拉菜单)。在 'sample' 的情况下,我将其设置为文件,Postman 允许我 'attach' 该文件。我使用 Postman 控制台查看请求中发送的内容,并尝试在我的 Java 代码中尽可能地模拟它。肯定还有我需要的其他细节,但 Postman 没有在控制台中向我显示。
我终于能够(头有点血)让 API 成功响应(HTTP 200 消息)。如果这对以后的任何人都有帮助,我将提供使它起作用的详细信息。
在查看 API 的定义时,它指出 "The request parameters are to encoded as 'multipart/form-data'"。我将一些参数作为 JSON 数据发送。我决定我需要将每个参数作为一个单独的表单变量发送,每个参数由一个边界标记分隔(我之前尝试过一次,但我又回到了同样的想法)。
这样做之后,我开始注意请求正文中每个项目之后的空格 (CRLF) 的细节。 API 对正文中数据的格式非常敏感。我发现它在您发送的表单数据的实际值之前需要一个 CRLF。
这是我发送的请求正文示例:
--BOUNDARY
Content-Disposition: form-data; name="private"
[CRLF (a space)]
true
--BOUNDARY
Content-Disposition: form-data; name="vm"
[CRLF (a space)]
win7-x64
--BOUNDARY
Content-Disposition: form-data; name="email_notification"
[CRLF (a space)]
false
--BOUNDARY
Content-Disposition: form-data; name="sample";
filename="CourseCompletionCertificate.pdf"
Content-Type: application/pdf
[CRLF (a space)]
[data stream of the Sample file in a byte array...]
--BOUNDARY--
我找到了 multipart/form-data 的例子,我注意到数据中使用了 CRLF,我尽力复制了数据的发送方式。正是在那个细节之后,API 成功响应。