Hacker News new | past | comments | ask | show | jobs | submit login
Bashbro – Make Any Comp a Web-Based File Server (github.com/victrixsoft)
97 points by ReversedChaos 7 months ago | hide | past | favorite | 47 comments



In a slightly more heavyweight category I've settled on dufs for my single binary file serving / uploading / password-protecting needs.

https://github.com/sigoden/dufs


Does this support starting a webdav server over an ssh tunnel to remote server? It looks like it from the readme, will attempt asap.

Ok, checked it out, dufs is a cool tool. Definitely replaces python -m http.server. This is a new standard rightalong side ripgrep.

Cargo is the package manager that pip wanted to be. We should just use cargo anyway. Why have distros when you have Cargo? Why have homebrew when you have Cargo?

Dufs support of webdav is nascent.

I kid, but only a little bit.


Webd: A 90kB Alternative you might want to try https://github.com/webd90kb/webd


Thanks for this, really handy


Single Rust binary: YES.

I looked at the Bashbro source and said NOPE. And I've written a lot of increasingly complex Bash. At some point you just have to realize that you're using the wrong tool for the job. Dufs even has tests!


rare to see such a useful and popular project with NO open issues.

Congrats!


go's version is this which is my favorite because a single http server serving static files is cool but it's better to program it to do what you want.

    package main

    import (
        "net/http"
        "os"
    )

    func main() {
        if err := http.ListenAndServe(os.Args[1], http.FileServer(http.Dir(os.Args[2]))); err != nil {
            panic(err)
        }
    }


I re-read "Make Any Comp a Web-Based File Server" 10 times and I don't understand what it means. Specifically the word "Comp".

What does this mean?


I think it's just what 12 year olds call a computer. A comp-u-ter.


gotta save todays date into my google cal, so i remember the day i learned this.

("cal" obviously stands for "calculator")



While i appreciate your response, i must say that, for me, it feels somewhat disrespectful to HN to post tiktok / social media links on here.


12 year olds, or non-native English speakers who use some slang and never realized how that slang is local


Computer?


Un ordi?


In case you're wondering the same thing I was, it uses socat to listen on the port


What is wrong with "python -m http.server"?


It requires Python.

Bashbro, on the other hand, seems to require socat. I wonder if there's any bash-istic method of listening to a port...



I solved that problem some time ago with netcat, „coproc nc -l -p PORT“. Makes bash listen to nc‘s stdout and let’s it write to it‘s stdin.

But nc is not bash.


Here's my nc version, works on all shells:

https://gist.github.com/alganet/140c7c12d1603c244a01

nc is almost everywhere, you can count on it.

Ultimately, this is a toy, but it can be handy. I originally made it to attempt using for serving config for networked debian unattended installations[1] while automating VM creation, but never went that far.

[1]: https://debian-handbook.info/browse/en-US/stable/sect.automa...


You can't count on nc being installed but you can count on it being installable.

That's a problematic distinction in some situations.


There might be a way to create a listener using bash's /dev/tcp but I can't remember (I haven't used bash for decades)

edit:

https://unix.stackexchange.com/questions/49936/dev-tcp-liste...

gives some pointers


For Bash with `--enable-net-redirections` set at configure time (not a default, not enabled on popular distros to my knowledge), `/dev/{udp,tcp}/$host/$port` is available for this purpose.


Does anyone know if there is a good reason to disable net-redirections?


Sure. It makes it incredibly easy to establish, for example, a reverse shell.

In a purpose-built environment there is practically no need for such a feature aside from mischief.


It doesn't use https, and doesn't use the system's PAM authentication methods.


Also "For when you really just want to serve some files over HTTP right now! "

https://github.com/svenstaro/miniserve


Nice job.

You can do it in python with python -m http.server also!


Related: list of web server one-liners https://gist.github.com/willurd/5720255


This is cool, but there's currently an overload of ports assigned on my system.

Is there a way to manage all these port numbers? And why can't we use strings, even if just locally?

And what do people use to allocate port numbers in a way that you'll never get clashes?


You can consider the use of Unix sockets (sockets as named files). There are lots of limitations but the most pervasive and frustrating of those is the general lack of support for them across apps.

You could set up Nginx and some local subdomains to reverse proxy to the intended applications, regardless of whether they're hosted on Unix sockets or plain ports, if that makes accessing them easier. It definitely makes them easier to make accessible outside of the local machine.


Thanks! But how would I start bashbro in this case, and assign it to the label "myfiles"? I suspect I need additional scripting to make this easy.


https://github.com/victrixsoft/bashbro/blob/c543d5d42ba2425f... needs amending to listen to a Unix socket instead of a port if that's something you'd like to contribute.

As for using Nginx, you should be able to install Nginx and enable its service and in that way immediately get a local HTTP server. You can then edit the config such that requests for the Host `myfiles.localhost` are `proxy_pass ...` to your bashbro server. Then `http://myfiles.localhost` in your browser should just work.


Ok, I appreciate your suggestions. But now I'm thinking about some utility where you can say:

    run-http-service myfiles bashbro -s -p PORT
And then it would just allocate a new port (clash-free), invoke bashbro with the given flags and substitute PORT by the newly allocated port number, and such that it uses myfiles.localhost as the domain. And when bashbro exits, the port number is garbage collected. Somehow, it feels like this should already exist ...


Perhaps it would be enough to have a folder in your Nginx config that is imported by glob, and to have the port number and service name in the filename of each file in the folder. The contents might be templated out from some template (`envsubst` and `sed` are probably acceptable ways to fill the template). To allocate a service is to check if it's already allocated, then find the greatest port number in use and add 1 (the filesystem can help you with this if you name the files appropriately), then check to make sure nothing else is already listening, then write the config file and restart Nginx.

I would not bother with service management to the extent that you are checking to see if the process is still running. Maybe garbage collection is worth doing, you could do it in a single run of `lsof` (the temptation to do it with multiple should be resisted).

I think this does not exist because stuff like foreman/overmind have their own method for allocating ports per-project (add 100 for each line in the config file, set the PORT env var to that) as would any sort of production-ready solution.

But it is a fun idea. And perhaps it should exist.


You can add things to /etc/services and software that properly uses getservbyname(3) when binding to a port can use those names.


No way to allocate port numbers without clashes ever. What I do is having a Ports.md in my personal knowledge base with all port assignments in my personal projects and networks: port, description, project link and/or service host:port. This works very well, I don’t have tens of thousands of projects so I’m not going to exhaust port numbers. I used to try to use Unix domain sockets as much as possible for anything fronted by nginx, but stopped bothering with that since I started centrally maintaining port assignment.


You can listen on port 0 and print the actual port on the stdout.


Doesn’t work for services talking to each other or bookmarks, or reverse proxies for that matter.


You can listen on an anonymous port. It's similar to how the kernel allocates a port for outgoing connections. It's very useful if you want to listen ephemerally, especially in tests. The downside is that you need your server to report which port it's actually listening on, and if it restarts, it will get a different port.


Well, you need to monitor the process for going down anyway, and

    ss -lntp | grep 'pid=<SERVER'S PID>' | awk '{ print $4 }'
takes care of servers who don't report the port they're actually listening on.


I've seen scripts that probe ports with nc until they find a free one. They usually log to stdout which port they found.


If you can ssh to the remote, you can simply use Emacs (dired and trump). I suppose the advantage here is that once you turn a machine into a file server you can access it from other devices.


One does not "simply" use Emacs.


Still doesn’t beat ksh cgi server. Ugh.


needs a Dockerfile




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: