Chris Morgan is a developer who writes about Rust, HTTP, and web server quirks, and runs a personal site with unusual experiments.
Commenters enjoy his sassy server that rejects query strings, and point to his Rust ownership explainer as a useful companion to the official docs.
Pretty much all of it. For example, let's take http://chrismorgan.info/blog/teepee-design-header-representation.html
impl<'a> AnyRefExt<'a> for &'a Header {
#[inline]
fn as_ref<T: 'static>(self) -> Option<&'a T> {
trait UncheckedAnyRefExt<'a> {
unsafe fn as_ref_unchecked<T: 'static>(self) -> &'a T;
}
//I am guessing the second line is special because Rust can't deduce "to" should be a TraitObject type?
let raw = require_single_field!(raw);
let to: TraitObject = transmute_copy(&self);
//is this adding header and 'static together?
pub trait HeaderMarker<OutputType: Header + 'static> {
//I have zero clue what this is doing
//I can't even fathom a guess
match *self {
Past => write!(f.buf, "0"),
ExpiresDate(ref tm) => tm.fmt_header(f),
}
//so _raw is a reference to a vector of bytes inside [] and it might possibly return whatever a box is of headers?
fn parse_header(_raw: &[Vec<u8>]) -> Option<Box<Header>> {
//is there really a language keyword called macro_rules! ?
macro_rules! impl_header_from_fromstr {
//what in the world is ($ty:ty)?
($ty:ty) => (impl Header for $ty {
fn parse_header(raw: &[Vec<u8>]) -> Option<$ty> {
//who thought "h.is::<H>()" was a good way to test a type? Why not "h.is(H)?" Why the => ?
//what is this even returning? a tuple of false and None?
Typed(ref h) if h.is::<H>() => {
(false, None)
…
I'll start with the clarification that the moderators have changed the URL of the original post from <https://susam.net/no-query-strings.html> to <https://chrismorgan.info/no-query-strings>. Hopefully, this will prevent any confusion about why we are discussing random walks in a post about query strings. Now let me answer your question.
> Is it not a random walk? Might sound pedantic but if there is graph structure I am interested.
The network is a directed graph. Every Wander Console declares some other consoles as its neighbours. So if we call the network graph X, then the set of vertices is:
V(X) = the set of all URLs that point to Wander Consoles
and the set of edges is:
E(X) = {(u, v) in V(X) : u declares v as its neighbour}
The traversal between consoles is not strictly a random walk. If I had to give it a name, I would call it randomised graph exploration with frontier expansion. On each click of the 'Wander' button, the tool picks one console at random from the set of discovered consoles and visits that console. It then fetches the neighbours declared by that console and adds any newly discovered consoles to the set.
The difference from a random walk is that the next console is not chosen from the neighbours of the last visited console. It is chosen from the whole set of consoles discovered so far. In other words, each click expands the known part of the graph, but the console used for that expansion is selected randomly from all discovered…
It's good to see new web-focused projects in Rust, I think it can be a really great language for this kind of thing. But to be honest, I'm looking forward to seeing what will be considered the go-to approach for Rust web applications _in a year_ or so.
There is much experimentation going on right now, with cool little innovations here and there, but I have yet to see an approach that looks really new and Rust-y to me.
For example: Rust's type system certainly has some nice properties to track dependencies between middlewares[^1] but I'm not convinced middlewares are even the best approach possible here. Also, it will be interesting how a framework based on async IO will look and what tricks/syntactic sugar/macros will be employed to keep boilerplate code down.
This is a pretty big order, of course: While I enjoy using small libraries, a well designed web framework requires a lot of organisational effort for all the small pieces to fit together nicely. I think most of the 'small pieces' are already there or at least well under way, by the way. For example: The async (mio) branch of hyper looks pretty solid for HTTP1/2, the Diesel ORM is fantastic (and will, according to creator Sean Griffin, soon hit 1.0), and handling JSON will only get better with future versions of serde.
[^1]: As recently discussed in https://chrismorgan.info/blog/tween.html and some other posts concerning the use of sessions types in Rust.
> And possibly the autodiscovery needs tweaking too, as I observe it not finding the feed on my site https://chrismorgan.info/, which is properly specified; my first guess is that it’s not coping with the type=application/atom+xml attribute.
I fixed that: https://mergefeed.net/Untitled?urls=https://chrismorgan.info/
> In related news, MergeFeed is currently vulnerable to injection attacks because it mishandles Atom titles that are specified as text. If you specify a title as HTML or XHTML, it filters out a <script> element properly (good! and while retaining inline formatting too!), but if you specify a title as text, it doesn’t escape the HTML (which is what it should do) or filter it (which would have been wrong but would at least have closed the security vulnerability). Proof of concept: https://mergefeed.net/-?urls=https://temp.chrismorgan.info/xss.atom
I fixed that too. But for now I wasn't able to fix it without also removing formatting. I might be able to figure out how to keep formatting without allowing XSS attacks later, but I'm not sure that's even a good idea. It's kind of a link aggregator and link aggregators generally don't allow formatting. You don't want people to try to gain attention that way, leading to an arms race.
"You could argue that I’m abusing 414 URI Too Long. I respond that it’s funnier this way. Other options I considered were:
400 Bad Request, the generic client error code, which is correct but boring;
402 Payment Required, and honestly if you want to pay me to make a particular URL with query string work, I’m open to it;
404 Not Found, but it’s too likely to have side effects, and it doesn’t convey the idea that the request was malformed, which is what I’m going for; and
303 See Other with no Location header, which is extremely uncommon these days but legitimate. Or at least it was in RFC 2616 (“The different URI SHOULD be given by the Location field in the response”), but it was reworded in 7231 and 9110 in a way that assumes the presence of a Location header (“… as indicated by a URI in the Location header field”), while 301, 302, 307 and 308 say “the server SHOULD generate a Location header field”. Well, I reckon See Other with no Location header is fair enough. But URI Too Long was funnier."
https://chrismorgan.info/no-query-strings?foo
How it works and how it should be used are different.
Say “no” to import side‐effects in Python:
https://news.ycombinator.com/item?id=7536246
https://chrismorgan.info/blog/say-no-to-import-side-effects-in-python
>I must be able to import your module— any module— at any time without anything breaking.
Or even the beneficial side effect of some other module running 10% faster. ;)
What side-effects, if any, are okay when importing a python module?
https://softwareengineering.stackexchange.com/questions/454069/what-side-effects-if-any-are-okay-when-importing-a-python-module
>Q: Is this a better design pattern or does it just kick the issue down the road?
>A: Kicking the issue down the road is the basic idea of the "functional core, imperative shell" design pattern.
Functional Core, Imperative Shell (2012):
https://news.ycombinator.com/item?id=34860164
https://www.destroyallsoftware.com/screencasts/catalog/functional-core-imperative-shell