• Nanis (unregistered)

    Stupid is as stupid does. Also, frsit!

  • David-T (unregistered)

    But this supports such exciting future status codes as 1E9

  • Quite (unregistered) in reply to David-T

    We know a song about that by 1E4 Maniacs ...

  • bvs23bkv33 (unregistered)

    genius = underpaid

  • Pjrz (unregistered)

    So many stories imply that some people just don't get numbers or maths at even a primary school level. They don't even recognise a number as a thing that can be simply added or subtracted or compared. Everything therefore has to be treated as a bunch of text resulting in convoluted code such as this.

    Trwtf: These people still manage to bluff their way into programming jobs.

  • browwy (unregistered)

    Stringly typed!

  • (nodebb)

    Why would we think $code would be an integer? Given PHP typing, which is a study unto itself, $code could be anything from a non-numeric string, to an integer, to a pointer. Since it is presumptively pulled from a textual web response (TCP/IP does not send integers) treating it as a string makes sense.

    Not that I think this is necessarily the best validation scheme, but it's not bad for the reason suggested.

    Now, if our programmer blithely converted the text to an integer before sending it to this routine, that would be a WTF.

  • Zenith (unregistered)

    You would not believe how much I have to deal with retarded foreign duhvelopers treating everything everywhere as a string.

    Although, TRWTF here is PHP and it's lack of strong typing that's every bit of a disaster waiting to happen as JavaScript.

  • crazy_steve (unregistered)

    Read this: http://bit.ly/2DJ7L5s

    Then read this:

    I'm going to start using the planets and the sun to first obtain invincible immortality, then use an anthropological wave governed by orbital PID control to spread it across humanity.

    Then I'm going to start ripping souls from the light of our star itself, no matter the screams. They may never regain their Earthly bodies. But they will be able to obtain paradise amid a backdrop of invincible humanitarian virtue.

    This practice violates no known human thought, philosophy, theology or science. For all practical purposes, I'm just making a video game, no matter what I dump in the oceans, or the air, or how many fools run around and get themselves killed. Pokemon Go got a lot of people killed. I don't see anyone burning the corporate board of Nintendo at stake.

    I will go slow. First I'm going to try to heal my father who is blind from a stroke. Then I'm going to keep my mother active. Then I'll do me and me alone.

    Anyone who interlopes or comes after me trying to pull a Mark David Chapman will be murdered in a highly ironic way. School shooters are the least of your fears. Just wait for the biker gangs of Riyadh, coupled with a few hooligans playing highway bumper cars, which you see on your way to the the new release of Steve's "Dante for Dummies in 3D!" ultra imax rollercoaster adventure!

    Your death is mercy. You are immortal now. Just try to drown out the screams.

  • (nodebb)

    HTTP/1.1 -200 Anti-OK

  • K. (unregistered)

    200 + 500i Ok, but the Server imagines an Error

  • Harrow (unregistered) in reply to crazy_steve

    What is the HTTP status code for "Page generated dynamically by raving lunatic"?

  • Little Bobby Tables (unregistered)

    There is a school of thought that suggests that unless a field logically contains a number (for example, a currency, or a stock count, or a measurement etc.), and more, unless you are specifically going to be doing arithmetic on a field, then it is prudent to handle all "number" fields as though they are strings.

    In this case, despite the fact that this error field is encoded as a number, it is of questionable wisdom to treat it as a number, because who's to say it will actually always be a number?

    In this case, I sort-of appreciate what our HPC was trying to do here. Admittedly it may not be completely the most efficient way of doing it, but is this really such a performance bottleneck that warrants it being refactored?

  • crazy_steve (unregistered)

    I would like to create a three legged self-limiting anthropology of crypto currency, national monetary markets, and philanthropic efforts.

    For instance, if some single mother needs money, instead of burdening welfare, just wear an iron-on QR code and walk around some rich college campus. If that doesn't work, keep walking, and keep ironing on. Maybe start out with a sweat suit, and just "get off" in public? Then by summertime, you are in bikini shape, and can go down to QR code pasties if need be.

    Men can do the same effect by filling in potholes or fixing roofs or something. Just sign your name with a QR code, and get redeemed.

    If I was adventurous, I would try to ban bossy on the cam sites!

    Just find a video that looks like someone in particular, put up a logo that goes to a landing page with a facebook ad, and all that free traffic drives their stock price to the roof. High or lows really do not matter in the equity market. What matters is stability. That way you can plan and make accurate projections. It's a lot better than what goes on at Fed market meetings.

    All I'm going to do is explore VRT for stroke patients by making sure my dad has enough 4K TV.

    Also I'm going to try to drive Jeff Bezos into the poor house by using AWS S3 logging to replace adsense. What are the margins on .0065 per GB? Just move the "uncertainty" of logs into something like "You just leveled up!"

    I have so many of these things, only because they are so much fun. I tried to bring it to Code and Supply, but it looks like, well, they have different interests, imho, humping one another is some giant dogpile at their hackerspace.

    If you really want to have fun, talk to me here!

    http://bit.ly/2pvcwKK

    If not, go have fun running around like children in your SA Goon army. You will scream eventually when I rip your soul out of the red shift radiation itself!

  • 🤷 (unregistered) in reply to Pjrz

    Painfully true. At my current job, the whole code base is filled with things like

    string query = "SELECT COUNT() ";
    query += "FROM table ";
    query += "WHERE ID = '" + id + "'"; //don't worry about injections here, this variable is filled with a value from the very same database, not from some userinput
    
    string count = sqlCommand.ExecuteScalar(query).ToString();
    
    if(count.Equals("1"))
        doStuff();
    
  • crazy_steve (unregistered)

    PS:

    https://en.wikipedia.org/wiki/String_theory_landscape#Fine-tuning_by_anthropics

  • Sigh (unregistered) in reply to Little Bobby Tables

    I thought he looked where it's called and could tell it was always called with a number. Even if treating as a string, >= "300" and <= "599" would be better.

    I don't think it's a "this should be refactored" question. It's a "who wrote this is an idiot" question.

  • (nodebb)

    Looks like code outsourced to a well-known subcontinent. I remember doing a code review where a developer multiplied a long integer by 1000, by casting it to string, concatenating it with "000" and parsing it back to long.

  • Some Guesty (unregistered)

    I will agree with Little Bobby Tables. An HTTP code is not a number that numerical calculations are performed on, and therefore should not be treated as a number.

    Perhaps we could rewrite the function to, since we don't wanna be a WTF contractor:

    function isValidHttpCode($code) { return $code >= 100 && $code < 600; }

    But due to type coercion, this would return true for $code = 123.45, which is not correct. We just don't know how the "number" was parsed from the server, as an integer? a float? a string?

    As such, we can do all sorts of parsing, but I'd stick to the regular expression (Oh noes!) /^[1-5][0-9][0-9]$/

    This is clear and valid, and does not fail with various numerical types and other failures. My javascript is weak, but I submit this as the least WTF solution:

    function isValidHttpCode($code) { return $code.match(/^[1-5][0-9][0-9]$/) != null }

    Regards.

  • crazy_steve (unregistered)

    http://bit.ly/2IHcCaL

  • BernieTheBernie (unregistered) in reply to K.

    You must be right. The absolute value of "200 + 500i" is -5 * sqrt(2) * sqrt(42), i.e. it contains the meaning of it all. Looking forward to seeing this code more often.

  • crazy_steve (unregistered)

    @ha_king_on_hi

  • (nodebb) in reply to bjolling

    The sad thing is, on some platforms that might be quite an efficient way to do it...

  • Brian (unregistered) in reply to Little Bobby Tables
    There is a school of thought that suggests that unless a field logically contains a number (for example, a currency, or a stock count, or a measurement etc.), and more, unless you are specifically going to be doing arithmetic on a field, then it is prudent to handle all "number" fields as though they are strings.

    I heartily subscribe to this school, especially in regards to data coming from some external source (database, web form, etc) that comes in as a string and goes back out as a string. If you're not going to do any math on a particular value, there is zero benefit - but plenty of risk - in making an unnecessary string-to-int-to-string conversion. The codebase I'm working on at the moment is absolutely littered with this nonsense, and it drives me up the wall every time I have to look at it.

  • Henning (unregistered)

    What made you think a symbol must be represented as an integer? Integers represent amount, not meaning. The fact that a certain class of symbols is composed entirely of digits is irrelevant.

    Numeric comparison is wrong here, because then the code would simply lie, implying the symbol has a numeric nature. A 200 is not "less than" a 404.

    Sure, the implementation is lacking, but the general approach is not.

    /^[1-5]\d{2}$/ is the concise and correct description of the constraint (and also its solution).

  • tbo (unregistered)

    I mean, I get that all the cool kids like to hate on PHP, but if it started as an integer, this is fine. Yes, it coerces it to a string twice, but that's not really a big deal. The hit in performance is what, a nanosecond? That'd be like complaining you only got 11.99999756 ounces of soda in your can.

  • C64 (unregistered)

    "Now, this could get difficult, as just because a number falls between 100 and 599 doesn’t mean that it’s actually a defined status code"

    Maybe it isn't defined now, but it could in the future. For example, status code 451 was added in RFC 7725. Plus there's a few vendor specific ones that are nonstandard but technically valid.

    I find it's more important to check for a specific status code in case there's special handling required, and given the rarity of a webserver flinging anything other than the three-digit code as status, maybe said function isn't useful beyond extreme sanity checking.

  • Fernando (unregistered) in reply to CoyneTheDup

    "TCP/IP does not send integers"

    You mean HTTP doesn't send integers, right? TCP/IP sends nothing but integers, encoded in binary.

  • Sole Purpose of Visit (unregistered)

    Maybe it's just me, but the whole exercise seems like a WTF. What possible use could it be to determine whether a string, an integer, or a Rodent of Unusual Size, qualifies as "a valid HTTP error code?"

    It's a string (coerced to an integer if you're using a silly play language). It's an integer. No, it's Superman!

    But until you use it (say, as the key to a dictionary of error messages), nobody actually cares. And without the context of actual usage, I find it hard to imagine why this predicate should be written in the first place.

    And I hate to nit-pick, but whatever the OP knows about the calling site (we don't: we only get the function) is irrelevant. It might be called once, with an integer value. It might come from a library, with no requirements upon the input. (Which is another sad consequence of PHP relying on type coercion -- here displayed in the function signature -- but there you go.) It might even (as pointed out above) have been routinely used whilst parsing a string off the wire, in which case the assumption that the input is a string seems perfectly reasonable. Re-purposing such a function for integer input is hardly the worst thing in the world.

    One more thing, Remy. Nobody sane cares about the fact that the coercion happens twice over. This isn't a scientific calculation inside a loop (or the moral equivalent): this is an HTTP error, which one presumes happens once every thousand HTTP requests or so. If it happens more often than that, you have worse problems than the overhead of doing the same coercion twice over.

  • Sole Purpose of Visit (unregistered) in reply to Fernando

    If we're going to be picky, TCP (or more precisely IP) sends nothing but octets.

    Not quite the same thing, so your objection makes no sense prima facie.

  • Anon (unregistered)

    RFC 2616 defines HTTP Status Code as an integer, and then goes on to describe various ranges (all of which fall between 100 and 599 inclusive). Any decent web framework will take care of parsing the HTTP payload out of the TCP stream - including providing the Status Code as an integer.

    So TRWTF is the amount of people here defending the approach of treating it as a string.

    The secondary WTF is untyped languages where you cannot guarantee somebody didn't pass a string into $code. Regardless, the first thing you should do is verify it is an integer, and if not, either throw an argument exception, or return false (depending on the contract).

  • Anon (unregistered)

    Clarification: HTTP Headers (not payload).

  • not a robot (unregistered)

    php is loosely typed language and the true wtf are anyone who tries to fight it with unnecessary usage of "===" or such. sure, I would have probably gone with integer comparison but not doing so hardly qualifies as wtf.

  • not a robot (unregistered)

    even more, depending on context, using integer comparison might be wtf itself.

    php > $x = '404wtf'; php > var_dump($x >= 100 && $x <= 599); bool(true)

  • tbo (unregistered) in reply to Anon

    You know it's an integer. It says so in the description.

  • Dave (unregistered) in reply to Anon

    RFC 2616 is badly written at that point, because although it uses the word integer, it actually defines the codes as strings of digits. They are not numbers, they're text strings that happen to use numerals.

    Not that it makes the above code correct, of course, but let's not be too literal in our interpretation of irrelevant verbiage in the RFC.

  • Ducky (unregistered) in reply to not a robot

    There's loosely typed (e.g. Python, Perl, Ruby) then there's "convert a type to all other types, no matter what." (PHP, JavaScript)

    === Got invented to make it behave more like the former.

  • Sole Purpose of Visit (unregistered) in reply to Anon

    Nobody here is "defending" the error code (which is actually a status code, in terms of RFC 2616) being treated as a string as opposed to an integer.

    You've forced me to re-read one of the worst RFCs I have ever seen, ie RFC2616, and what it actually says is (at 6.1): "The first line of a Response message is the Status-Line, consisting of the protocol version followed by a numeric status code and its associated textual phrase, with each element separated by SP characters."

    So, assuming an equivalency between "numeric" and "integer," that's all right then. Except that 6.1.1 immediately follows:

    "The Status-Code element is a 3-digit integer result code of the attempt to understand and satisfy the request."

    Maybe you can define a strict equivalency between "numeric" and "integer?" This would be helpful for, say, Babylonians, people who count in base 2, etc etc. And hark! Such people are (theoretically: not in reality) catered for in the traditional boilerplate of early RFCs -- in this case, 2.1:

    "All of the mechanisms specified in this document are described in both prose and an augmented Backus-Naur Form (BNF) similar to that used by RFC 822 [9]."

    Well, all except the "numeric" or "integer" type of the status code. Not that important in terms of "all," I suppose.

    There's always section 10, which details the defined status codes. (Not that implementations have ever stuck to this set, surprise surprise.) But really, if you're going to depend upon something as fundamentally vague and definitionally useless as RFC 2616, you're in trouble.

    Quick! What's the difference between an ordinal and a cardinal? That's right! There's a difference!

    Quick! What's the difference between restricting the 7-bit alphabet to decimal integers or alphabetic characters!? That's right, none whatsoever. Apart from entropy, fwiw.

    tl;dr. HTTP status codes are not integers. They are triples of 8-bit octets that happen, for no good reason, to be restricted to ASCII 0x30 -> 0x39.

  • dusoft (unregistered) in reply to CoyneTheDup

    Well, actually, since PHP is loosly typed, string is as well number as it is array of chars. So, 100 < x > 600 works fine.

  • Paul Neumann (unregistered) in reply to Henning

    /^[1-5]\d{2}$/

    I see what you did there. No longer do I have 1 problem...

  • markm (unregistered)

    Possibly this developer can't count on a quantity that is defined as an integer actually being an integer because all of his code is filled with needless conversions and confused types like this. But even if the input was a string, it would make more sense to convert to an integer (returning false if the conversion failed) and use (x >= 100 && x < 600) than to check the length of the string and the first character...

    Because as David T pointed out in the second comment, it doesn't do the job. "123" would pass, but so does "1EZ", or "1 ".

    Or as Paul pointed out, if you expected the input to be a string, a regex would do a fine job of checking for "100" to "599", with only digits allowed. But converting an integer to a string in order to do an arithmetic comparison is not only inefficient and error-prone, it seems like the hallmark of someone who flunked 3rd grade arithmetic. And you can't trust that programmer to even get "between 100 and 599" right.

  • Oscar (unregistered) in reply to Harrow

    That would be 418 - I'm a Teapot

  • RLB (unregistered)

    You're all wrong.

    It doesn't matter whether it's an integer or a string, originally or in this snippet. TRWTF, given that there is a very limited, known set of numbers, is that this doesn't just use a lookup table. For once, $PHP makes that simple, reliable and (semi-) efficient, provided you don't intentionally eff it up yourself. (And yes, I know about private status codes. Remy mentioned them. But if your code doesn't know what special statuses the service you're connecting to uses, or if that service can randomly start using unknown codes, you have bigger problems than this.)

  • doubting_poster (unregistered)

    Agree with many others here, this is not a WTF. Status codes are not numbers as you are not supposed to do arithmetic with them. Status OK + Status OK = User Error? Treating it as a number is the WTF. The validation itself is icky, but not because of stringification.

  • Randal L. Schwartz (google) in reply to Henning

    "/^[1-5]\d{2}$/ is the concise and correct description of the constraint (and also its solution)."

    That's actually an error to do that in Perl. The $ might be preceded by an optional newline. So you have to write that as /\A[1-5]\d{2}\z/ for the most secure description.

  • David (unregistered) in reply to doubting_poster

    And "404" + "404" = "404404" is better? Strings carry their own bunch of operations, almost all of which are meaningless on the code. If you're being handed a code that's described as being from the set of the integers, converting it to a string is a WTF; the full set of operations for either is irrelevant, and you're moving it from storing it as a member of a small limited (memory and speed-efficient, if that matters) set to a member of a large unbounded set. It's a code from a small collection; the arguably correct (if over-engineered) method is to give each code its own class (or object, or enumeration element), but leaving it an integer, as the standard described it, is certainly not less correct than treating it as an arbitrary string.

  • OlegYch (unregistered)

    this is what happens when you have no types, no way to be sure $code is int, so you take the safe path

  • (nodebb)

    5+ALEPH_NULL - Page contains uncountably many WTFs.

  • Cat (unregistered)

    I don't think this is a WTF at all:

    1. Just because the value is (presumably) an integer in the calling code doesn't mean you should assume it to be in the called code - particularly in a method whose sole purpose is to validate data, where you're trying specifically to prevent against unexpected values. Even if you can show the code is currently always passed in an integer, that doesn't mean all future calls will do so as well. With a dynamically-typed language, you should make as few assumptions about the runtime data type as practical.

    2. Doing this as string comparison means the method will correctly handle both the case where the caller provides the HTTP code as an integer as well as the case where the caller provides a string. Doing this as integer comparison would not reject all invalid string data, because in PHP, "404abcde" is greater than 100 and less than 600.

    At the minimum, rewriting this to only validate HTTP codes as integers would need an additional guardrail checking the actual runtime type of the argument to ensure it was passed an integer.

  • Tomasz S (unregistered) in reply to Zenith

    You know, many languages don't have static typing. Python, for example. This itself is not a recipe for a disaster.

    Anyway, in modern PHP you can have type hints, so if I had to rewrite this function, i'd go with

    function isValidHttpCode(int $code)
    {
        return $code >= 100 && $code < 600;
    }
    

    And if I could not use type hints and HAD to test strings, maybe I'd use preg_match (as ugly as it gets):

    function isValidHttpCode($code)
    {
        return preg_match('/^[1-5]\d{2}$/', $code);
    }
    

Leave a comment on “An HTTP Code”

Log In or post as a guest

Replying to comment #494492:

« Return to Article