Skip to main content
added 91 characters in body
Source Link
ZachB
  • 1.2k
  • 10
  • 19

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

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"
    }
  ]
]

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" -> {"image" -> File[image]}|>];
URLRead[req, "Body"]

Docs (see Scope > "To send files...")

Edit 2 This evidently uses expect: "100-continue", which is not supported by some common load balancers that may be between you and your server. Thus, it may not work in many cases.

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" -> {"image" -> File[image]},
  "Expect" -> "" (* See edit 2.5 below *)
|>];
URLRead[req, "Body"]

Docs (see Scope > "To send files...")

Edit 2, 2.5 Mathematica's HTTP client uses Expect: "100-continue", which is not supported by some common load balancers that may be between you and your server. To disable that, add the header "Expect" -> "".

deleted 18 characters in body
Source Link
ZachB
  • 1.2k
  • 10
  • 19

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"
    }
  ]
]

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" -> {"image" -> File[image]}|>];
URLRead[req, "Body"]

Docs (see Scope > "To send files...")

Edit 2 This evidently uses expect: "100-continue", which is not supported by manysome common load balancers and other devices that may be between you and your server. Thus, it may not work in many cases.

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"
    }
  ]
]

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" -> {"image" -> File[image]}|>];
URLRead[req, "Body"]

Docs (see Scope > "To send files...")

Edit 2 This evidently uses expect: "100-continue", which is not supported by many common load balancers and other devices that may be between you and your server. Thus, it may not work in many cases.

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"
    }
  ]
]

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" -> {"image" -> File[image]}|>];
URLRead[req, "Body"]

Docs (see Scope > "To send files...")

Edit 2 This evidently uses expect: "100-continue", which is not supported by some common load balancers that may be between you and your server. Thus, it may not work in many cases.

added 209 characters in body
Source Link
ZachB
  • 1.2k
  • 10
  • 19

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"
    }
  ]
]

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" -> {"image" -> File[image]}|>];
URLRead[req, "Body"]

Docs (see Scope > "To send files...")

Edit 2 This evidently uses expect: "100-continue", which is not supported by many common load balancers and other devices that may be between you and your server. Thus, it may not work in many cases.

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"
    }
  ]
]

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" -> {"image" -> File[image]}|>];
URLRead[req, "Body"]

Docs (see Scope > "To send files...")

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"
    }
  ]
]

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" -> {"image" -> File[image]}|>];
URLRead[req, "Body"]

Docs (see Scope > "To send files...")

Edit 2 This evidently uses expect: "100-continue", which is not supported by many common load balancers and other devices that may be between you and your server. Thus, it may not work in many cases.

added 317 characters in body
Source Link
ZachB
  • 1.2k
  • 10
  • 19
Loading
Source Link
ZachB
  • 1.2k
  • 10
  • 19
Loading