I have an http server written in deno like this
import { serve } from "https://deno.land/[email protected]/http/server.ts";
serve((_: Request) => {
// do something with request
// ...
return new Response("hello", {
status: 200,
headers: new Headers({
"content-type": "text/plain",
}),
});
});
I'm trying to upload an image to this server with an iOS shortcut (Get Content of URL). If I debug the server I can see the request come in with the image and I make it to response but the shortcut hangs and then errors with a timeout. It works if I use postman or if I simply change the content of the shortcut to json instead of an image. What could be the issue here? Is iOS expecting some special header I'm not aware of?
Here is a link to the shortcut. Replace the ip address with your machines ip address first https://www.icloud.com/shortcuts/b2de83c34e0448c081b0b38ba79bbc7a
Here is some code for nodejs that does not have the same issue.
const http = require('http');
const hostname = '0.0.0.0';
const port = 8000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
Machine info
10:20:11> lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 22.04.1 LTS
Release: 22.04
Codename: jammy
10:20:18> uname -r
5.15.0-60-generic
10:20:19> deno --version
deno 1.31.0 (release, x86_64-unknown-linux-gnu)
v8 11.0.226.13
typescript 4.9.4
It's not clear at which stage the problem occurs because your question doesn't include reproduction steps — so, in order to help you reproduce success, I'll provide a complete series of reproduction steps with everything needed:
POST
) and responds with a file (GET
) at the/file
path. It expects a single uploaded file to be encoded as aFormData
item:server.ts
:http://localhost:8000/file
I see a blank page in my browser (expected) and these outputs in my terminal as a result:
This screenshot depicts the details of the shortcut in case you don't want to download the data file or you would like to re-create it from scrach:
After installing/creating the shortcut, open this page on your iOS device and take a screenshot of it. This will save an image to your device's photos app.
Open the photos app and find the screenshot from the previous step, and share the image (this opens the share sheet).
Find the share sheet item that corresponds to the shortcut (if you installed it, the share item will be named
so_75583257
), and tap that item in the list.The shortcut will run. You might encounter a permission request to allow connecting to the server address that you defined when importing/creating the shortcut — accept the permission request. After a short time, you should see the shortcut complete — it will look something like this:
Looking back to the terminal, you should also see some new output similar to the following:
At this point, you can terminate the
deno
process in your terminal usingctrl + c
.After following the steps above, I'm confident that you'll be able to determine the cause of your issue. If anything is unclear, feel free to leave a comment on this answer.
Update in response to your comment:
FormData
is the correct mechanism for sending one or more files. Otherwise, you'll have to invent your own encoding and decoding schema — a "file" body is just an unstructured payload of binary data. One way to get binary data from such a request is to use the methodRequest.blob()
.Here's an example of applying the information above to modify the
getFileFromRequest
function: