This is a hack, but it works.
UploadFile[url_, filePath_, urlParams___] := With[
{
bytes = Import[filePath, "Byte"],
filename = StringJoin[FileBaseName[filePath], ".", FileExtension[filePath]]
},
URLExecute[
url,
urlParams,
"Method" -> "POST",
"MultipartElements" -> {
{"file\"; filename=\"" <> filename, "application/octet-stream", bytes}
},
"Headers" -> {
"Accept" -> "application/json; charset=UTF-8",
"Content-Type" -> "multipart/form-data",
"Expect" -> "" (* See edit 2.5 below *)
}
]
]
Notice that I'm stuffing the filename
parameter in the first element of "MultipartElements"
along with the field name in order to get it in Content-Disposition
for that element.
(* Get a new ephemeral RequestBin from http://requestb.in/, then put URL below: *)
UploadFile["http://requestb.in/1hyjbdl1", "ExampleData/rose.gif"]
result:
Content-Disposition: form-data; name="file"; filename="rose.gif"
Theoretically you could also specify "Content-Disposition" -> "form-data; filename=\"foo\""
in the request header, but the server would have to be expecting exactly one file in the form-data and parse accordingly, whereas the above approach with filenames in each part I think is more commonly expected.
Edit
In version 11, there's a no-hack way to do this:
image = FindFile["ExampleData/Ocelot.jpg"];
req = HTTPRequest[url, <|"Body"<|
"Body" -> {"image" -> File[image]},
"Expect" -> "" (* See edit 2.5 below *)
|>];
URLRead[req, "Body"]
Docs (see Scope > "To send files...")
Edit 2, 2.5 This evidentlyMathematica's HTTP client uses expectExpect: "100-continue"
, which is not supported by some common load balancers that may be between you and your server. ThusTo disable that, it may not work in many casesadd the header "Expect" -> ""
.