Cisco ThreatGrid提交示例API ...如何发送示例文件?

问题描述 投票:0回答:1

我无法使用Java成功调用ThreatGrid Submit Sample API。我过去曾使用Java来调用API,因此我有设置这些调用的经验。

我应该发布到https://panacea.threatgrid.com/api/v2/samples并在我的请求正文中提供参数。

我还需要将示例文件(正在评估的文件)写入请求的主体。

我知道我需要将'Content-Type'设置为'multipart / form-data;'并提供一个Boundary字符串来分隔请求的各个部分。

在调用提交API时,我收到一个HTTP 400 Bad Request,返回以下错误:

{"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":"[email protected]"}]}}

这就是说我没有提供'sample'参数。 Sample是提交威胁评估的文件。请注意,我在请求正文中发送的第二部分(数据部分)名称为“sample”。

以下是我在连接中设置请求标头的方法:

    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--

构建我的请求主体的代码:

        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。我在请求正文中将'private','vm','email_notification'和'sample'项设置为form-data。 Postman允许您将这些项目设置为文本或文件(有一个下拉列表)。在'sample'的情况下,我将其设置为file并且Postman允许我'附加'文件。我使用Postman控制台查看请求中发送的内容,并尝试尽可能在我的Java代码中模拟它。必须有我需要的其他细节,Postman没有在控制台中显示我。

java rest cisco
1个回答
1
投票

我终于能够(头部略带血迹)让API成功响应(HTTP 200消息)。如果这可以帮助将来的任何人,我将提供使其工作的细节。

在查看API的定义时,它声明“请求参数将被编码为'multipart / form-data'”。我发送了一些参数作为JSON数据。我决定我需要将每个参数作为一个单独的表单变量发送,每个参数由一个Boundary标记分隔(我之前尝试过这个,但我回到了同样的想法)。

在这之后,我开始关注Request主体中每个项目之后的空格(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回应成功。

© www.soinside.com 2019 - 2024. All rights reserved.