Live data from Hacker News

I’ve banned query strings

chrismorgan.info

251–260 of 317 posts

Re: I’ve banned query strings

#251
post #73

Earlier quoted context omitted.

Query strings existed before CGI did, and the way they're defined to be filled in from web forms is quite useful; I wouldn't want to need Javascript to fit that into path format. There's nothing wrong about having things decided by the server; I don't get that part of your argument at all.

Maybe dumb question: how does the server “decide” anything other than what file to serve? Today we have many choices but back in the day CGI was the first standard way to do it. So yes query parameters existed before CGI but to use them you had to hack your server to do something with them (iirc NCSA web servers had some magic hacks for queries). CGI drove standardization.

TCP has been around a long time. Listen, read, send, you're good to go. It's just software so you can make it do anything.

But you're asking about the relationship between popular primarily file serving servers like Apache and their relationship to high level code to create custom responses? Yeah, CGI was the first big standard there that I remember, though it was a bit before my time. But that's only one possible architecture.

These days, most web apps have the web server built in, and so the custom code you're writing works with the full request directly. There may be a lightweight web server in front (or multiple), like nginx, to manage connections, but they will largely just proxy the whole thing through.

Re: I’ve banned query strings

#253

Earlier quoted context omitted.

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.

You can do that with filtering, which should be a feature of every single logging tools.

Anyway, I agree that when you filter via queries, an empty list is more valid response than 404. That HTTP status should be returned IMHO when the requested (for example by id) item is not found (and of course with wrong paths, etc).

Re: I’ve banned query strings

#254

Earlier quoted context omitted.

Doh! The part past the # does not go to the sever, so that wasn't a longer URL. How about: https://chrismorgan.info/%6e%6f-%71%75%65%72%79-%73%74%72%69...

Indeed, that's not a query string! The #, and following text, is a fragment , is client-side only, and isn't the subject of the blogpost. Neither is percent encoding, which is just another way to send the exact same path from your browser to the server. Note that it has nothing to do with the length of the URL. That's just the error message he's chosen to use, because "4xx stop pissing about with my URLs" doesn't exi…

> percent encoding, which is just another way to send the exact same path

This is not true for all characters. Some can only be expressed by percent-encoding, and decoding them will either break things completely (e.g. %20) or change the meaning of the URL (e.g. %2F, %3F in paths).

Yes, you can encode x as %78 and it should work identically, and you can decode %78 to x and it should work identically—though in both cases, I reckon there’s a strong case for blocking the request as suspicious, and I will probably start doing that soon.

But take these examples of improperly decoding:

• /foo%2Fbar/baz.html has path «"foo/bar", "baz.html"».

• /foo/bar/baz.html has segments «"foo", "bar", "baz.html"».

• /foo%3Fbar/baz?quux has path «"foo?bar", "baz"» and query "quux".

• /foo?bar/baz?quux has path «"foo"» and query "bar/baz?quux".

Re: I’ve banned query strings

#255

Earlier quoted context omitted.

That's Go.

Which runs on what computer in 1995?

I'm not sure what point you're trying to make. Here it is in C, so you can run it on you computer in 1995? Because servers could make decisions in 1995.

int main() { int s = socket(AF_INET, SOCK_STREAM, 0); setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int));

    struct sockaddr_in addr = { AF_INET, htons(8080), .sin_addr.s_addr = INADDR_ANY };
    bind(s, (struct sockaddr*)&addr, sizeof(addr));
    listen(s, 10);
    printf("Listening on :8080\n");

    while (1) {
        int c = accept(s, NULL, NULL);

        char req[1024] = {0};
        read(c, req, sizeof(req) - 1);

        time_t now = time(NULL);
        int tuesday = localtime(&now)->tm_wday == 2;

        const char *status = tuesday ? "404 Not Found" : "200 OK";
        const char *body   = tuesday ? "Not Found (it's Tuesday)" : "Hello from 1995!";

        char resp[256];
        snprintf(resp, sizeof(resp),
            "HTTP/1.1 %s\r\n"
            "Content-Length: %zu\r\n"
            "Connection: close\r\n\r\n%s",
            status, strlen(body), body);

        write(c, resp, strlen(resp));
        close(c);
    }
}

Re: I’ve banned query strings

#256
post #68

Earlier quoted context omitted.

What's interesting is that none of these sites have a "search" feature. Which is an important accessibility feature and a clear and legitimate use case for a query string.

My website has search without a query string: https://www.jeremykun.com/

Nice blog, but that's user hostile for a lot of products with search features. People share links pretty regularly.

Re: I’ve banned query strings

#257
post #172

Earlier quoted context omitted.

It's marketing for the origin site. The line of thought is that the author sees significant traffic from xyz.com in the ref query string, and considers advertising or partnering with the origin site. Honestly, it is quite useful for niche/startup sites. I have been on both ends of conversations that began from seeing these in web analytics (as someone that saw incoming traffic from a site and reached out, and as some…

> sees significant traffic from xyz.com in the ref query string, and considers advertising Why? Already getting traffic for free.

You never ran a website for profit, have you? Knowing who is sending you traffic lets you decide whether your marketing is working, where you should write your blog posts to get more views, etc. This has been the way the web works for decades.

Re: I’ve banned query strings

#258

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.

Of course it is technically possible, but doing so would violate the spec.

> The 404 (Not Found) status code indicates that the origin server did not find a current representation for the target resource or is not willing to disclose that one exists.

In the above case, the server _is_ returning a representation.

https://datatracker.ietf.org/doc/html/rfc9110#name-404-not-f...

Re: I’ve banned query strings

#259

You know I was actually really curious about this so I went back to the HTML and URL W3C standards and surprisingly they don't actually have any definitions of format other than being percent encoded. One might conflate query strings with "form-urlencoded"[0] query strings, which is one potential interoperability format, but in general a queries string is just any percent encoded string following a "?" in a url[1], a…

Back in the day it was reasonably common for CMSs and forums to only have an index.php, and routing entirely by query string (in form-urlencoded form, people were not savages). So you would have index.php?p=home and index.php?p=shop. Or index.php?action=showthread&forum=42&thread=17976. It should be immediately obvious that in that scheme 404 is indeed the correct answer to unknown query parameters In fact lots of si…

It's funny to read this like it's archaic knowledge, this is my base mental map of how nicer looking URLs work :)

Re: I’ve banned query strings

#260
post #228

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.

204 No Content for nothing found is both not an error (because 2xx code) but also indicates there was nothing found to match the request. If it's an API, a 200 with an empty JSON object or array in the body is legitimate as well, but a 204 is explicit.

This too is not spec compliant. 204 means the request was successful but no body is being returned in the response.
Post reply on HN