我认为这个请求失败,因为它无法识别文件名。使用这个HTTP请求插件并在声明性管道中遵循这个API文档,我运行了下面的请求…
script {
env.WORKSPACE = pwd()
def response = httpRequest url: "https://cloud.tenable.com/compliance/export",
customHeaders: [[name: 'X-ApiKeys', value: "${ACCESS_KEY}"]],
httpMode: 'POST',
acceptType: 'APPLICATION_JSON',
uploadFile: "${env.WORKSPACE}/test.zip"
}
错误:
java.lang.IllegalStateException: Name is blank
11:02:40 at org.apache.http.util.Asserts.notBlank(Asserts.java:64)
11:02:40 at org.apache.http.entity.mime.FormBodyPartBuilder.build(FormBodyPartBuilder.java:96)
11:02:40 at org.apache.http.entity.mime.MultipartEntityBuilder.addPart(MultipartEntityBuilder.java:148)
11:02:40 at jenkins.plugins.http_request.HttpRequestExecution.authAndRequest(HttpRequestExecution.java:314)
11:02:40 at jenkins.plugins.http_request.HttpRequestExecution.call(HttpRequestExecution.java:260)
11:02:40 at jenkins.plugins.http_request.HttpRequestExecution.call(HttpRequestExecution.java:80)
11:02:40 at hudson.remoting.LocalChannel.call(LocalChannel.java:46)
11:02:40 at jenkins.plugins.http_request.HttpRequestStep$Execution.run(HttpRequestStep.java:380)
11:02:40 at jenkins.plugins.http_request.HttpRequestStep$Execution.run(HttpRequestStep.java:358)
11:02:40 at org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution$1$1.call(AbstractSynchronousNonBlockingStepExecution.java:47)
11:02:40 at hudson.security.ACL.impersonate2(ACL.java:449)
11:02:40 at hudson.security.ACL.impersonate(ACL.java:461)
11:02:40 at org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution$1.run(AbstractSynchronousNonBlockingStepExecution.java:44)
11:02:40 at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
11:02:40 at java.util.concurrent.FutureTask.run(FutureTask.java:266)
11:02:40 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
11:02:40 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
11:02:40 at java.lang.Thread.run(Thread.java:748)
我相信这与java文档中的addFile方法有关?将内容类型指定为APPLICATION_ZIP或APPLICATION_OCTETSTREAM会导致相同的错误。用不存在的文件替换test.zip会将错误更改为'file does not exist',这表明我正在读取test.zip,但'name'参数不知何故是空白的。
显然你必须设置multipartName
:
httpRequest url: "https://cloud.tenable.com/compliance/export",
customHeaders: [[name: 'X-ApiKeys', value: "${ACCESS_KEY}"]],
httpMode: 'POST',
acceptType: 'APPLICATION_JSON',
uploadFile: "test.zip", // env.WORKSPACE is not necessary, the path is already relative to the current workspace
multipartName: "something" // <--
(我认为这设置了与该文件相关联的HTML表单字段的名称。对于REST API,这个值不重要,我想)
或者,如果你的服务器支持,你也可以将wrapAsMultipart
设置为false,这样文件就不会被包装为multipart/form-data
,而是直接在请求体中发送。