New smolweb file transfer service

Have you ever needed to transfer a file to someone, or maybe yourself, but you haven't had access to dropbox or whatever at the time? Or maybe you need to transfer something to or from a machine that you only have terminal access to?

I ran into these issues, so I set up a service for piping data from the command line - literally, it acts like a unix pipe - using ingrix.info as a proxy. You also don't need to sign up for it! (Unless you want to send me a public key, see below).

What do you need to use it?

How does it work?

A lot like a unix pipe, but it uses ssh instead of a local fifo - and no, you don't need a user account on my machine. First, think up some identifier that you want to use to access your file, then you can send a file with a command line similar to:

Where 'file_i_want_to_transfer' is any file you want to send, and 'theidentifierithoughtup' is your made-up identifier - it doesn't matter what it is as long as it's no more than 32 characters and uses only a-zA-Z0-9 . and _.

Once the sender has the file queued for transmission, the receiving end can pick it up with one of two options:

Or

Anyone that's used to using ssh for non-interactive work should recognize this style of workflow.

FAQ

Q: What's the password for the service?

A: The password is 'opensesame'. It will also remind you on the login prompt.

Q: Can I use sftp instead of normal ssh?

A: No. I haven't found a good way of making that work properly. You'll have to use the 'cat | ssh' thing instead.

Q: Why does my terminal just say 'waiting for connection...' after I execute your command line?

A: You aren't uploading a file to ingrix.info, it only acts as a pipe. Whoever is going to receive your file needs to open up the other end of the pipe for any data to get sent. The ssh session only "uploads" whatever the connection buffers hold, and it discards those when the sender disconnects.

Q: Why won't Lagrange display the file on the screen, and it makes me download it?

A: I don't try to figure out what kind of file you're sending (see no-snooping below), so Lagrange will just think that it's an arbitrary binary blob, i.e. an application/octet-stream. Lagrange won't know what to do with that so it will just ask you to save it someplace.

Q: I tried to download the file but something got goofed up, and now it thinks I'm trying to send a file when I try to download it again via ssh, or Gemini tells me that it can't find the file. What do I do?

A: The sender needs to re-send the file. This is a one-shot deal, and once a connection is made the underlying structures are torn down on the server side so you can't get a second download unless the sender re-starts.

Q: What's the maximum file size I can transfer?

A: Senders can do 10MB by default, receivers aren't metered. If you send me an ssh public key I can bump your send limit. See the details page below for contact info.

Q: What do you log?

A: The IP address of both parties, and the total amount of data that gets transferred. I have to be able to tell if this is getting abused. If you are worried that I'm snooping on your data then you should encrypt it before sending. In fact, I encourage doing so because trusting some rando on the net isn't the best security policy. That being said, I'm not doing any snooping (ala no-snooping mentioned above)

Q: Why did you make this?

A: I thought it might be useful. If I get good feedback on this one I might make a more permanent dropbox-like service with the same flexibility that'll keep files around on the server longer, maybe so that we can try to revive the old ftp-style file dumps. So if you like this, or like the dropbox idea then shoot me an email or something to let me know.

Q: Where can I find more information?

A:

Details on ft@ingrix.info

Posted in: s/SmallWeb

๐Ÿš€ ingrix

2025-09-16 ยท 8 months ago ยท ๐Ÿ‘ skyjake, jsreed5, nerd, ps, RubyMaelstrom, Breebee, rolypolyphonic, bsj38381, el3ctron, DdlyHeadshot ยท ๐ŸŽ‰ 1

7 Comments โ†“

๐Ÿš€ jsreed5 ยท 2025-09-17 at 11:35:

This is brilliant! I'd love to see the code for this, especially the FIFO part.

๐Ÿš€ ingrix [OP] ยท 2025-09-17 at 16:27:

@jsreed5 thanks! I'll clean up the code a bit and put it in a tildegit repo. I'll ping you once it's up.

๐Ÿš€ jsreed5 ยท 2025-09-18 at 14:17:

I finally tried the service with a test file and it worked perfectly. Thanks again for creating this! The only suggestion I might make is that when only using a share code, the original name of the file is lost. Might it be possible to supply the file name in an optional second field?

Edit: I realize that wouldn't be feasible for SSH transfers, since the service simply writes a data stream to STDOUT and it's up to the user to redirect it to a file. But on the Gemini side, the service could redirect the share code to a URL with the intended file name.

๐Ÿš€ ingrix [OP] ยท 2025-09-18 at 14:32:

@jsreed5 that's a possibility, but I'm trying to keep the logic as simple as possible to reduce any attack surface either on the server end or for users. I am guessing the filename loss is a concern with accessing it via Gemini? With ssh you could tell someone to access it via 'ssh ft@ingrix.info identifier > The_Offspring_-_Original_Prankster.mp3'. I could probably relax the restrictions on the identifier to allow any printable ascii character except '/'. Would that be a sufficient tradeoff/improvement?

Edit: just saw your edit, so that does clarify things. Would still love your input re the changes to identifier and whether that'd be sufficient

Edit 2: after thinking a few minutes I do think that would be sufficient. If the identifier only forbids / that may be sufficient to do 99% of what you'd want. I'll have to add code to do percent-encoding for the gemini url and a few other safety checks.

๐Ÿš€ jsreed5 ยท 2025-09-18 at 14:48:

@ingrix I don't know how the backend is programmed, but my initial thought would be to escape the given file name into a URL-safe form. For example, supplying the name "My Dad's File.txt" would yield the escaped name My[%]20Dad[%]27s[%]20File.txt. (Ignore the brackets around each percent sign; I have to do that on BBS to stop it from interpreting the code.) Perl, Python and other languages have tools to do that, and if you store the file name server-side already escaped, it'll sanitize the input too.

Suppose the file code is "dadfile". Then on the Gemini side, visiting the URL "gemini://ingrix.info/ft/dadfile" would return a 30 status that redirects to gemini://ingrix.info/ft/My[%]20Dad[%]27s[%]20File.txt (again, ignoring brackets). When the user downloads it, most clients will convert the escaped file name to unescaped form--and even if it doesn't, it can be converted later.

๐Ÿš€ ingrix [OP] ยท 2025-09-18 at 14:53:

@jsreed5 The utility is written in C and statically linked so that it can be aggressively chrooted. The redirect is a good idea that hadn't occured to me, thanks! I'll have to think on how to implement it but I like the idea.

๐Ÿš€ jsreed5 ยท 2025-09-18 at 15:44:

The more I think about it, providing separate file names might introduce too much complexity. How should collisions be resolved? If a share code matches a file name, one runs the risk of either an infinite redirect loop or serving the wrong file. Unless you're willing to implement separate URLs for inputting the code versus downloading the file, it might be better to stick with only a share code.