Live data from Hacker News

I’ve banned query strings

chrismorgan.info

201–210 of 317 posts

Re: I’ve banned query strings

#201

> You could argue that I’m abusing 414 URI Too Long. I respond that it’s funnier this way. Other options I considered were: Another option to consider is "418 I'm a teapot": teapots usually also don't support query strings

But I’m not a teapot. I despise tea.

You would be a very sad teapot then. :(

Re: I’ve banned query strings

#202

Earlier quoted context omitted.

> other parts of the stack As a web developer, you’re the like the guy standing with a clipboard outside a fancy club checking if people requesting entry are allowed or not. Basically, level 1 security. If someone is not on the list, your job is to default to declining them access, not granting them access assuming level 2 security will handle them at a deeper layer. It’s possible that the teams you work with expect…

>It’s possible that the teams you work with expect fuzzy behaviour from the website but that’s a choice, not a practice. This is how the vast majority of websites work. The practical reason is obvious: when we model the behaviour our code depends on, we want to create the simplest possible model that allows our code to work as expected. Placing requirements on it that our code doesn't actually depend on is useless, u…

> there is no security benefit to filtering out unneeded url parameters.

What about passing extra data to fill the server memory with either extra known junk or a script / executable to use with a zero day in an internal component or something.

To misuse the nightclub analogy: it’s like checking for bags not being larger than A4 and disallow knives and other weapons.

Re: I’ve banned query strings

#203
post #151
post #126

Earlier quoted context omitted.

Every object in git (commit, tree, revision of a single file) has a hash that is guaranteed unique within a repository (otherwise many more things than a web UI would break) and likely also globally. I can understand wanting to isolate repositories to prevent hash collisions from causing problems, but within a repo everything has a universally unique ID. edit: for instance, that specific VERBS.md is represented by th…

that's not what i meant. i was trying to suggest that the string "blob" does not fit. why is it there? why is it needed? https://github.com/gritzko/beagle/a7e17290a39250092055fcda5ae7015868dabdb4/VERBS.md this should be sufficient to represent the file. "blob" is like a descriptor of the value that follows. it would be like doing this: https://github.com/user/gritzko/project/beagle/blob/a7e17290a39250092055fcda5ae701…

> this should be sufficient to represent the file.

Except it's not, because the oid can be a short hash (https://github.com/gritzko/beagle/blob/a7e172/VERBS.md) and that means you're at risk of colliding with every other top-level entry in the repository, so you're restricting the naming of those toplevel entries, for no reason.

So namespacing git object lookups is perfectly sensible, and doing so with the type you're looking for (rather than e.g. `git` to indicate traversal of the git db) probably simplifies routing, and to the extent that it is any use makes the destination clearer for people reading the link.

Re: I’ve banned query strings

#204
post #160
post #151

Earlier quoted context omitted.

that's not what i meant. i was trying to suggest that the string "blob" does not fit. why is it there? why is it needed? https://github.com/gritzko/beagle/a7e17290a39250092055fcda5ae7015868dabdb4/VERBS.md this should be sufficient to represent the file. "blob" is like a descriptor of the value that follows. it would be like doing this: https://github.com/user/gritzko/project/beagle/blob/a7e17290a39250092055fcda5ae701…

They are following the /key/value/key/value pattern, but the first two pairs in a GitHub URL are fixed to user and project, which lets them omit the key names. I could see them not being willing to hardcode the third pair to blob. Back when GitHub URLs were kind of cool, github.com/user/gritzko/project/beagle would have been much less cool than just github.com/gritzko/beagle.

> They are following the /key/value/key/value pattern

They are not. There's just a routing layer below the repository.

Re: I’ve banned query strings

#205

> curl, for example, seems to illegitimately strip a trailing question mark (could be only for the command line, didn’t test library usage). umm what? I don't know what they're actually sending where they think this, but if you think curl is broken you should re-think that maybe you're the one doing something wrong. Here are some examples showing curl not stripping question marks (obviously), I am very curious what t…

$ curl -s 'https://httpbingo.org/get?' | jq .url "https://httpbingo.org/get" This may require further investigation.

From Debian 13.2 (Trixie) + Bash + curl 8.14.1:

  $ curl -s 'https://httpbingo.org/get?' | jq .url
  "https://httpbingo.org/get"
But on macOS + Bash/Zsh + curl 8.7.1:

  $ curl -s 'https://httpbingo.org/get?' | jq .url
  "https://httpbingo.org/get?"
I see some related changes here: https://github.com/curl/curl/commit/3eac21d

Re: I’ve banned query strings

#206
post #185

Earlier quoted context omitted.

$ curl -s 'https://httpbingo.org/get?' | jq .url "https://httpbingo.org/get" This may require further investigation.

Might be shell expansion? zsh uses `?` for filename expansion, others might as well: https://zsh.sourceforge.io/Doc/Release/Expansion.html#Filena... Though I forget if any shell does stuff like that in quotes. Or printing oddities.

No, it’s definitely curl that’s doing it.

  $ echo 'https://httpbingo.org/get?'
  https://httpbingo.org/get?
  $ python
  >>> import json
  >>> import subprocess
  >>> json.loads(subprocess.run(['curl', '-s', 'https://httpbingo.org/get?'], stdout=subprocess.PIPE).stdout)['url']
  'https://httpbingo.org/get'
I’m using curl 8.20.0-3, Arch Linux, x86_64.

  $ curl --version
  curl 8.20.0 (x86_64-pc-linux-gnu) libcurl/8.20.0 OpenSSL/3.6.2 zlib/1.3.2 brotli/1.2.0 zstd/1.5.7 libidn2/2.3.8 libpsl/0.21.5 libssh2/1.11.1 nghttp2/1.69.0 ngtcp2/1.22.1 nghttp3/1.15.0 mit-krb5/1.21.3
  Release-Date: 2026-04-29
  Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns mqtt mqtts pop3 pop3s rtsp scp sftp smtp smtps telnet tftp ws wss
  Features: alt-svc brotli GSS-API HSTS HTTP2 HTTP3 HTTPS-proxy IDN IPv6 Kerberos Largefile libz PSL SPNEGO SSL threadsafe TLS-SRP UnixSockets zstd

Re: I’ve banned query strings

#207

Earlier quoted context omitted.

Yeah, URLs really don’t have much in the way of semantics. Path is clearly intended for hierarchical data and query for non-hierarchical data, and there are strong customs, some commonly supported or even enforced by libraries, but no actual rules. Ultimately, it’s just a string that the server can decide what to do with. The really funny thing about this is that, when I was worrying about possible side effects if I…

Wikipedia web server treats anything after /wiki/ literally as the name of the article. So en.wikipedia.org/wiki/// is the article about C++ style comments

Oh, magnificent. Lovely high-profile example to add about empty path segments being meaningful.

Re: I’ve banned query strings

#208

Earlier quoted context omitted.

If you're routing like it's 1999, sure, 404. On the other hand, if it's a CRUD app and you're filtering a list of entities by various field values? Returning that no items matched your selection (or an empty list, if an API) makes more sense than a 404, which would more appropriate for an attempt to pull up a nonexistent entity URI.

There is no reason you can return that "no items matched your selection" with a 404 HTTP response code instead of a 200.

You can return whatever HTTP response code you want, but if you care about knowing whether your site is working being about to look at the logs and see "That user requested a page that doesn't exist" being different to "That user requested a page that exists but had no results" is quite useful. In coding terms it's the difference between a null and an empty array.

Re: I’ve banned query strings

#209

Earlier quoted context omitted.

A response code of 204 seems more appropriate but the problem is you're not allowed to send further information, which would make that descriptive response... not descriptive enough.

I think of it like this: /users/ returns a 404 in an API means that this resource does not exist. As in, this is not a part of the API. /users/123 returns a 404 means this user record does not exist. Yes this means that a 404 is context dependent but in a way that makes it easier for a human to think of and reason about.

Yes, and this is obvious if /users/ exists and returns a 400 if the ID is required. That way you can tell the difference between /users/ being there and expecting and ID, and it not being there.
Post reply on HN