Again, this is not suitable for any real world use
Funny you say this because I’m much more inclined to use something like this over any of the alternatives I’ve seen. After running lots of code “in production” (For various definitions of production) I’ve realized that there is no such thing as a black box dependency. You will eventually have to understand how everything you run in production works as time tends toward infinity, and sooner rather than later. Given this state of affairs, over time I’ve become biased towards simple “vendorable” internally managed dependencies like this rather than complex externally managed dependencies.
I would not recommend it directly, as the password management is a little weak (it could benefit of using the newish constant time comparison function), and it doesn’t have proper sanitization in a couple of user provided params. But it’s mostly ok and clear to understand
I wanted to create the simplest possible Fediverse server which can be used as an educational tool to show how ActivityPub / Mastodon works.
I totally agree, I think one hacky implementation is better for building understanding than a dozen prose essays.
I warn you though, it is the nadir of bad coding. There are no tests, bugger-all security, scalability isn’t considered, and it is a mess. But it works.
I think your implementation frankly really improved my understanding of the security & scaling considerations involved in ActivityPub much more than a super-secure/super-“scalable” implementation would have. And more generally I think people are deluding themselves more often than not when they talk about security/scalability. I’ve noticed a pattern of successful systems which were built around standard architectures and unsuccessful systems which were built around extremely complex “scalable” architectures in “safe” languages.
I think a great open-source example of that kind of project is a lot of Fabrice Bellard’s work. The Tiny C Compiler literally started out as a submission to the International Obfuscated C Code Contest. It’s easier to improve simple software that starts around a well-engineered core. It’s much harder to go the other direction and simplify complex over-engineered software.
I have written PHP for similar reasons, and yeah it is impressively simple, though still pretty flawed. Though I wonder what this same server would look like in a single file of Go – it would probably work pretty well.
I don’t disagree with the gist of your ideas, but TCC specifically is completely unreadable and unmaintainable code. I didn’t know it was a submission to the obfuscation contest, but it explains a lot…
This is low-key the best tutorial on ActivityPub I’ve seen (other than honk, lol) and actually causes me to slightly revise my opinion of the whole thing. Well done.
I love the simplicity and directness of honk but I wish the variable naming were a bit less whimsical. Somewhat undoes all the good work the code is doing to make things understandable.
(compare to GotoSocial which is, to me, an unreadable mess of interfaces and packages out the wazoo.)
It requires absolutely no dependencies. You do not need to spin up a dockerised hypervisor to manage your node bundles and re-compile everything to WASM. Just FTP the file up to prod and you’re done.
This is wonderful! I mean the writing - but also the joy of PHP.
Well-commented code is not the same thing as literate programming.
Knuth-style literate programming is two things:
A module system with some flavour of aspect-oriented programming and hypertext.
A system for extracting and publishing documentation from source code.
Knuth was using Pascal which lacks a module system and requires programs to follow a very rigid order of presentation. His tangle/weave tooling allowed him to split his code into chapters and present it in order of theme or functionality.
If your programming language allows you to write code with a nice order of presentation, that doesn’t mean you are doing literate programming, it just means that one of the reasons for literate programming no longer exists.
I was incorporating in my thinking, the text of the web page as ‘informative’ context associated with code.
My take on literate programming ‘evolved’ so to speak, perhaps beyond (or tangenial) of its original intent.
So perhaps my comment that this was a great example of LP, was a bit of oversimplification.
I view literate programming as a practice that involves:
a) Synchronizing descriptive text with the code.
b) Tooling navigate between code and text (and ASCII diagrams, when available)
c) Ensuring that the text includes intent, description of options and why the particular approach was taken, potential gotchas and things to avoid (beyond what can be done via compile-time-constraints), reference to Requirements/stories (if Agile SDLC process was used, or a reference to documented requirements/technical specs).
I’ve not used them for ages but Nearly Free Speech is still around and had a great reputation for scaling costs down to almost nothing for low-traffic sites.
Funny you say this because I’m much more inclined to use something like this over any of the alternatives I’ve seen. After running lots of code “in production” (For various definitions of production) I’ve realized that there is no such thing as a black box dependency. You will eventually have to understand how everything you run in production works as time tends toward infinity, and sooner rather than later. Given this state of affairs, over time I’ve become biased towards simple “vendorable” internally managed dependencies like this rather than complex externally managed dependencies.
Even though he said he likely got security wrong? :D
Yes.
I would not recommend it directly, as the password management is a little weak (it could benefit of using the newish constant time comparison function), and it doesn’t have proper sanitization in a couple of user provided params. But it’s mostly ok and clear to understand
Then you’d be going from one extreme of dependencies to another.
Something something “obviously no deficiencies” vs “no obvious deficiencies”. :D
That’s one interpretation
This is amazing!! Thanks for making this.
I totally agree, I think one hacky implementation is better for building understanding than a dozen prose essays.
I think your implementation frankly really improved my understanding of the security & scaling considerations involved in ActivityPub much more than a super-secure/super-“scalable” implementation would have. And more generally I think people are deluding themselves more often than not when they talk about security/scalability. I’ve noticed a pattern of successful systems which were built around standard architectures and unsuccessful systems which were built around extremely complex “scalable” architectures in “safe” languages.
I think a great open-source example of that kind of project is a lot of Fabrice Bellard’s work. The Tiny C Compiler literally started out as a submission to the International Obfuscated C Code Contest. It’s easier to improve simple software that starts around a well-engineered core. It’s much harder to go the other direction and simplify complex over-engineered software.
It’s actually only 665 lines, which is perfectly reasonable for a single file - https://gitlab.com/edent/activitypub-single-php-file/-/blob/main/index.php?ref_type=heads
I have written PHP for similar reasons, and yeah it is impressively simple, though still pretty flawed. Though I wonder what this same server would look like in a single file of Go – it would probably work pretty well.
I don’t disagree with the gist of your ideas, but TCC specifically is completely unreadable and unmaintainable code. I didn’t know it was a submission to the obfuscation contest, but it explains a lot…
This is low-key the best tutorial on ActivityPub I’ve seen (other than honk, lol) and actually causes me to slightly revise my opinion of the whole thing. Well done.
Cheers mate!
I love the simplicity and directness of honk but I wish the variable naming were a bit less whimsical. Somewhat undoes all the good work the code is doing to make things understandable.
(compare to GotoSocial which is, to me, an unreadable mess of interfaces and packages out the wazoo.)
I love the first paragraph of this post so much.
Thank you 🥰
It might be nice to see how errors are returned in ActivityPub, such as an unrecognized user—is it a 404? A 200 with a JSON encoded error message?
This is wonderful! I mean the writing - but also the joy of PHP.
This is a great example of Literate programming [1]
[1] https://en.wikipedia.org/wiki/Literate_programming
Well-commented code is not the same thing as literate programming.
Knuth-style literate programming is two things:
Knuth was using Pascal which lacks a module system and requires programs to follow a very rigid order of presentation. His tangle/weave tooling allowed him to split his code into chapters and present it in order of theme or functionality.
If your programming language allows you to write code with a nice order of presentation, that doesn’t mean you are doing literate programming, it just means that one of the reasons for literate programming no longer exists.
I was incorporating in my thinking, the text of the web page as ‘informative’ context associated with code.
My take on literate programming ‘evolved’ so to speak, perhaps beyond (or tangenial) of its original intent. So perhaps my comment that this was a great example of LP, was a bit of oversimplification.
I view literate programming as a practice that involves:
a) Synchronizing descriptive text with the code.
b) Tooling navigate between code and text (and ASCII diagrams, when available)
c) Ensuring that the text includes intent, description of options and why the particular approach was taken, potential gotchas and things to avoid (beyond what can be done via compile-time-constraints), reference to Requirements/stories (if Agile SDLC process was used, or a reference to documented requirements/technical specs).
Now I need a shared PHP hosting! Any deals for lobste.rs?!
I’ve not used them for ages but Nearly Free Speech is still around and had a great reputation for scaling costs down to almost nothing for low-traffic sites.