Post Mortem: A single whitespace character
eatabit.com
eatabit.com
The solution for this problem: Use SSL.
I mean: There are already many good reasons to use SSL, but whenever you need to send any kind of mission critical data over the mobile network, you practically must use SSL if you want any kind of guarantees that the data you send to the server is what actually reaches the server (and reverse).
Here's my war story from last year: http://pilif.github.io/2013/09/when-in-doubt-ssl/
On the subject of reliablity: a 8 bit uC running at 16MHz needs a long time to do the public key crypto required to set up the connection. This means you need a GSM data link to be continuously available for a longer period.
Edit: or you could get a Cortex-M0 with 32K RAM for $2.
Incidentally, this has leaked the users phone number because only that specific numer was being replaced with asterisks.
Welcome to the world of very crappy "security" (-theater) end-user products.
What's your price point for hardware?
You are sending people's orders around the web. I'd consider that "personal".
None-the-less, use SSL, there is little reason not to use it these days. And as others have pointed out, it's the only good and easy way to guarantee what you send to one of these printers is what it actually received (no carrier tampering of your packets, etc).
Just use SSL.
(I don't actually know how much work would be involved, but goleksiak says they would really like to use it, so I assume it's not trivial.)
http://stackoverflow.com/questions/15830333/arduino-due-http...
I know everyone will tell you not to roll your own cryptosystem, but rolling your own is superior to having no encryption or authentication, and so long as you're sane about it the result should be no worse than passing plaintext.
Your messages are small. Encrypt (or maybe just sign) them with RSA and call it a day. You don't really need to use port 80 and a HTTP preface at all, do you?
Not trying to be silly. But if the only goal is to prevent man-in-the-middle attacks such as someone mangling the data, why not "corrupt" the data such that the phone company in the middle can't read it?
You control both ends. You can make your own "security".
You're not explicitly worried about security. You're not worried about Evil Person reading your messages. You just want your carrier to stop f'ing with your data.
If the data is slightly corrupted so the carrier's crappy software can't recognize it as http headers then the carrier's software (hopefully) won't fck with it.
They might also use TLS with null cipher. That should be not-so-intensive, even on a tiny processor. And it could be enough to defeat some packet-modifiers (they may notice it's TLS and not analyze), while maintaining HTTPS compatibility.
It feels like you are kind of throwing the baby with the bath water. IMHO, badly configured transparent proxy does not mean the concept is bad, does it ?
Then you can hope that you are big enough to have priority with the carrier or you know somebody who knows somebody who can fix it.
Or you don't deal with any of this and just go SSL. A certificate will cost you $100 per year in the worst case. Thats about one hour of your time spent fixing proxy issues (not including customers and/or end users breathing down your neck because their software just stopped working for some as yet unknown reason)
To me, there are valid usecase for SSL, using it to work around proxies is not one. That said, I get your point, you prefer the possibly easier and safer way. But you still might run into another set of problems (https://news.ycombinator.com/item?id=8471877).
From RFC 2616 "The HTTP/1.1 protocol allows origin servers, caches, and clients to explicitly reduce transparency when necessary."
As I said, bad configurations dos not mean the principle is unsound.
Common meaning (from https://en.wikipedia.org/wiki/Proxy_server#Transparent_proxy): "Also known as an intercepting proxy, inline proxy, or forced proxy, a transparent proxy intercepts normal communication at the network layer"
RFC 2616 uses the term to describe a property of a normal, opt-in HTTP proxy: "A 'transparent proxy' is a proxy that does not modify the request or response"
In preceding discussion we were using the term in its common usage meaning.
Also, you misrepresent what RFC 2616 says about the its concept of transparency. The part you quoted continues:
"the protocol requires that transparency be relaxed
- only by an explicit protocol-level request when
relaxed by client or origin server
- only with an explicit warning to the end user when relaxed by
cache or client "And before that they decided to enforce a reverse DNS lookup so all the name based virtual servers with local DNS entries stopped working - I had my staging instances setup that way.
And not only all this happens without any prior information, it is next to impossible to climb through the support layers to finally find someone who even understands what are you talking about. They just want you to restart your modem to "resolve the problem".
Looking through the system, I see that you were sent two emails (in August and September) as several of your apps were migrated to the new routing stack (https://devcenter.heroku.com/articles/heroku-improved-router). As mentioned in the documentation, the new router follows stricter adherence to the RFC specification, including sensitivity to spaces.
...and sure enough, there is a line that says:
The request line expects single spaces to separate between the verb, the path, and the HTTP version.
So the lesson is: RTFM
-G
After all it would not be that hard to scan for which customers are going to be bitten by that particular change when it actually happens rather than using some fire-and-forget email.
For it to hold up, you need to provide the further argument that you frequently need to switch from liberal to strict.
Humans are strage: many will spot "foo||bar|zap" as an error, but not "foo bar zap" as an error as serious as the previous one.
The market (players) (can) manipulate it to create an (perceived) competitive advantage.
It's also a source where "evil" in IT comes from.
I think the fallacy is to assume that once stuff works in production, only your changes can trigger a bug. There's way too much software involved in a standard webserver stack to assume anything about it. Any patch, any update to software or devices not under your control has the potential to break your stack. The thing the OP did was the right thing: Monitor, monitor, monitor.
Well, that's the rub, right? How do you know how strict you're being if your tools accept things liberally? If anything, the lesson here is to test with the strictest possible tools.
> just as the Cowboy was not liberal in accepting
And this is hard too, because on what dimensions should you be liberal? How do you decide what the "real" set of inputs you're going to accept?
And that leads to my real issue with the principle: what should you, as the liberal accepter, do in those cases? Here it's easy enough to guess what the behavior should be with the extra space (just accept the damn request), but in general it's not -- you're creating implementation-specific behavior; what happens when you accept undefined or incorrect inputs will vary from implementation to implementation, creating a nightmare of uncertainty for people sending you stuff. Of course, you can always say, "they should send stricter stuff!" but then what's really the point of accepting inputs liberally?
So different software will necessarily do it differently. For all software to be doing it the same, there would realistically need to be some specified standard on how to do it, and then we're no longer talking about 'be liberal in what you accept', but just 'accept exactly what the standards say.'
Of course, in this case the client software was not being 'strict in what you issue' -- I am not challenging that part, of course you should _always_ issue exactly correct according to standard requests or other protocol communications. But there will inevitably be bugs, bugs happen.
"Be liberal in what you accept" makes it harder to find those bugs, and leaves them waiting to surprise you when the (non-standard) level of "liberalness" on the receiving end changes, which it inevitably will because it was not according to standard in the first place.
I think the HTML/JS/CSS web provides another good example of the dangers of 'be liberal in what you accept', very similarly -- you may think your web page is 'correct' because one or more browsers render it correctly while being 'liberal', and not realize it's in fact buggy and will not render correctly on on or more other past, present, or future browsers. This example has been commented upon by others, and I think has led to a move away from 'be liberal in what you accept' in web user agents. http://books.google.com/books?id=5WXp4j4eV4UC&pg=PA136&lpg=P...
Be strict in what you issue (duh!), be liberal in what you accept - but both emit strong warnings when the input isn't strict, and have a strict mode.
If everyone can be strict in what's sent, then the problem is solved. But since that won't happen, even on accident, the only solution is to be harsh on receiving input and hope things fail early in the dev cycle.
Also, text-based protocols are especially prone to this poor handling, A: because spec writers (like HTTP's) go moronically overboard, being all creative (line folding? comments in HTTP headers? FFS!) and B: because text is so easy, everyone just figures anything goes and pays less attention.
Consider a client that emits \n instead of \r\n. How do you handle it? Liberally? OK, treat 'em like CRLFs. Now you read \n\n. Everything after that is content, right?
Oops, you're now ignoring headers, potentially security-sensitive ones.
I've run into this exact bug in production, leading to a security problem. The client, proxy, and endpoints had different ways of handling CRLF. Some would treat \n\n as the end of headers, some not. Exploiting this, clients could route requests through the proxy and add special headers that only the proxy should have been able to add (like X-Client-IP).
Apart from this, the whole "robustness principle" just leads to a bunch of guessing and even more incompatible implementations. See HTML as another example mess.
The problem wasn't liberal acceptance, it was that liberal acceptance ended when Cowboy was added to the mix.
Strict acceptance would have shown the error earlier, but continued liberal acceptance would have allowed continued functionality.
I think I prefer just adhering to the standard in the first place.
I agree that the issuer should always be strict; and if accepters were strict too, then buggy issuers would be detected immediately and never make it into production. Instead they make it into production, where they will sometimes work and sometimes not, depending on the accepter stack in use at the time and context and how the accepter stack chooses to interpret 'liberal'.
"liberal" by definition here means _beyond the spec_, according to no spec. So different implementations may have different varieties or extents of 'liberalness,' and switching implemenentations will almost necessarily give you a different set of acceptable requests. If they were all the same, that'd be adhering to some spec, not being liberal in your acceptence of it.
"Liberal acceptance" may or may not have ended -- we don't really know if Cowboy accepts only exactly what is legal according to spec or not -- but the bounds of what is liberally accepted defintely changed. As it neccesarily will any time you switch implementations, since 'liberal' is by definition not according to any spec.
Maybe for a server with massive resources (I am talking about megabytes of RAM compared to kilobytes I work with) being liberal in what you accept works, but not when you are on a budget.
Postel's original formulation is not written in an essay, but an RFC, and does not elaborate on what he meant: https://tools.ietf.org/html/rfc761
Here's one discussion that suggests this interpretation, without precisely ascribing it to Postel: http://cacm.acm.org/magazines/2011/8/114933-the-robustness-p...
Not being critical, just pointing out a common mistake.
http://blog.oxforddictionaries.com/2011/08/principle-or-prin...
Principal: Main, most important
Principle: A rule, a system of belief
It is a common mistake I see all the time here on HN (along with "your" vs. "you're" vs. "you are"). Why is it that is offensive to the point of deserving a down-vote? Please help me understand.
People downvote corrections because they're usually noise. When someone makes a typo - and homophones are usually slips equivalent to typos - it's noise to point it out.
This comment needed to be left alone. No down vote, perhaps an up-vote by the comment writer if s/he found it helpful and that's it.
One of the things that continues to disturb me the most about HN is how thin skinned the community seems to be. It is impossible to consistently offer a contrasting point of view here without down-vote attacks that make your point of view virtually disappear. Mind you, this particular post isn't that. It just reminds me that HN is really weird.
I get down voted a lot despite the fact that I am a successful entrepreneur since age 15 who has built several companies and continues to do so. My perspective, however, seems seldom welcome here (based on how often I am down-voted) because I don't tow the line of the 20-somethings that are the bulk of this audience. Instead of learning they choose to pound what they don't like out of existence. Weird.
> A post such as mine would not have to appear too frequently
Which is it? All the time or not too frequently?
And while you might only make rare posts some people would point out every error and mistake and difference in style. People downvote your post to dissuade those other posts.
About your downvotes: I'm guessing they're for your incredible arrogance.
https://news.ycombinator.com/item?id=8443553
https://news.ycombinator.com/item?id=8440762
https://news.ycombinator.com/item?id=8440847
People see that level of arrogance as ugly. You might want to either change your posting style or stop complaining about the downvotes.
HN only does well with well defined technical discussion. On everything else it has degraded to almost what happened to every USENET list in the past. USENET did not have any voting mechanism to make opposing views disappear. In that case those who wanted command of the list and felt ownership of it simply resorted to brutal flaming attacks. Some lists were really horrible places for anyone to say "I disagree".
HN can be like that, in a different way, if you are not a 20-something drinking from the same koolaid bowl. To the point of someone taking the time to take something out of context and then using it to call someone arrogant.
So, come to HN to agree with the herd or risk being called arrogant for presenting a different point of view. Brilliant.
Notice that your correction is in the black, but these complaints are in the grey.
Unpopular opinions do have a lot of trouble on HN, but I think that dang's efforts with algorithms and intervention have improved the situation, and at least show good intent.
I attract downvotes like honey attracts flies, but I deserve them. I really disagree, and am happy to repeat myself. I double-down on my most downvoted comments; people may not know quite how much they disagree with me unless I expand on what I said.
>risk being called arrogant
Not very high risk then? Sounds like a very safe place.
The huge difference I see on HN between someone like me and the HN "crowd" boils down to: life and business experience. I too was an idealist at 22 years of age. And I too thought and said a ton of dumb things for most of my twenties.
I was VERY lucky in that my first job in technology had me working within a team of engineers that were at least 10 years older than me. I was 19 years old when I got hired as a junior engineer. I hadn't finished college yet but I was able to convince the VP of Engineering that I had what it took. And I did. Not being arrogant at all. By 19 I had already designed and built (from raw chips) at least two computers and had presented a paper at an ACM conference.
Anyhow, the education I got from the "elders" was priceless. I am not talking about technology. Yes that was invaluable. No, I am talking about how to be a man rather than a child. How to think instead of reacting. How to question what amounted to indoctrination being dished out by some of the professors at school. How not to come of as a 20-something ignorant moron.
We often had pretty deep discussions about business, politics, ethics and all manner of subjects. I stayed at that job for ten years. It was an education I didn't know I needed. Over the ten years I was there I noticed how my mental process was growing apart from that of my friends. They were growing through their 20's without the benefit of a team of "elders" applying corrections and providing advice on a daily basis. I was in an environment where I had to behave like an adult and think like an adult in a serious organization. To this day I run into circumstances where some of those lessons come back to the forefront.
Surveys set the bulk of the HN audience somewhere in the mid 20's in terms of age. It has been my experience through hiring dozens of engineers and engineering students that kids today are not benefiting from the same level of interaction with adults. Yes, a 20-something man is still a kid. Women tend to grow up a lot faster than we do. Unless the kids have a strong family social group to guide them they can get to their mid twenties and still be complete juvenile morons. I've seen it in more than one occasion.
Culturally the US presents a case where kids are "kicked out of the house" at 18 or thereabouts and go off into the wild to become men and women. In other cultures the family unit stays far more connected and provides a regulating mechanism. For example, the drunken orgies around Spring Break are a uniquely American phenomenon. In other parts of the world no 20-something would even think of behaving like that and then have to answer to their family for the failed moral choices made during that time.
Kids who behave like that have no common sense or manners yet if you spoke to them at any other time (or here on HN) they'd probably tell you that they are perfectly sensible people. Kids like that go to school on their own and suck in all the crap dished out by an educational system permeated with far left extremists in some cases. It isn't my intent to turn this into a political discussion. It is a well known fact that some of our universities have, perhaps by accident, turned themselves into left wing indoctrination centers. And the kids take this shit and make it their own belief system without even making an attempt to question any of it because, well, "lord of the flies" is their environment, self regulation is hard at that age.
Long way to say that if you are an older engineer with more life and business experience posting on HN it is almost assured that the kids are going to pummel you with down votes because, well, they think they know better and are not open to considering any other ideas. On matters of technology they do well because it is often very clear cut. On matters involving life or business experience they just don't have a clue yet they think they do. Instead of taking the opportunity to learn they engage in confirming each other's biases and push back hard on anyone who is not drinking from their koolaid.
"hey" should be capitalized, it's at the beginning of a complete sentence. Also, a comma should be before the quotation.
> No down vote, perhaps an up-vote
down-vote and up-vote should at least be hyphenated consistently.
> One of the things that continues to disturb me the most about HN is how thin skinned the community seems to be. It is impossible to consistently offer a contrasting point of view here without down-vote attacks that make your point of view virtually disappear. Mind you, this particular post isn't that. It just reminds me that HN is really weird.
Likewise, down-vote should be hyphenated consistently with the previous use.
> I get down voted a lot despite the fact that I am a successful entrepreneur since age 15 who has built several companies and continues to do so. My perspective, however, seems seldom welcome here (based on how often I am down-voted) because I don't tow the line of the 20-somethings that are the bulk of this audience. Instead of learning they choose to pound what they don't like out of existence. Weird.
I don't get what kind of prank you're trying to pull here. Is it "down voted" or "down-voted"???
Just being helpful!!
The difference, in case you did not understand that. Is that my earlier comment was purely constructive in nature.
Your comment was a juvenile "I'll show him. I'll rip his writing apart and put him to shame".
One is an adult constructive post. The other is what I would not allow from my eight year old kid.
Because I communicate in multiple languages and auto-correction/completion makes it very difficult. Switching the keyboard back and forth doesn't help either because it isn't uncommon to use more than one language within a single email or comment (in other words, mixing languages).
My little post was about pointing out a mistake in usage that isn't a spelling problem but rather using the wrong words altogether. I see this A LOT in technical websites, writing, job posts and resume's.
Look around and see how many job positions are asking for a "Principle Engineer" instead of a "Principal Engineer". The first is some kind of a moral cop position within the company, I guess, the second is an engineer in charge of a project or department.
But, yes, you are right. If I know that someone is a native English speaker and they have bad typos, misspellings and generally can't communicate well in written form it does reflect poorly. If they are not native it is a matter of their position. I would expect someone with a university degree to not confuse "principle" with "principal" or "your" with "you're" (and other such examples).
Btw that is why I use the somewhat pretentious sounding "Written on my tablet" or "Written on my phone" in email signatures on devices like that in hopes that people will re-attribute typos that might otherwise reflect poorly. But it is still a good idea to proof read written communication of any significant value...
I never had to worry about this when I had a Blackberry with a physical keyboard. In fact, to this day I have never understood why Blackberry didn't create a campaign of really funny TV ads with people sending hilarious or out-of-place text messages because of the issues with screen based typing. The ad would end with some kind of a catch phrase pointing out that this won't happen to your on a Blackberry.
Ditto for other smart phones. The easiest way to compete with the iPhone is to offer what I will call a "true business smart phone" with an fold-out keyboard for accurate text entry. You could drive that point with ads until everyone is blue in the face. Typing on a touch screen is a horrible experience.
They even suggest that code should infer the meaning of messages. So I suppose you need some sort of AI to really handle things well.
Binary protocols would be a better choice. Or, a well-defined text format. JSON, XML, anything, really, would eliminate this class of bugs.
This same reasoning is why mail and other messages have the Header: Value format - you can compose in plain text. This is documented at least as far back as RFC 561, in 1973. Again, that's a good excuse: Users must compose by hand. Also, the RFC is just codifying what people were already doing.
HTTP, SIP, and others do not have these excuses. HTTP headers are essentially never written by hand, and the extremely few times they are, we don't need conveniences such as comments, line folding, lenient grammar, etc. (Proof: People write XML and JSON by hand far more often, without major ordeals.)
I'm a strong proponent of "do not manipulate strings". Having library writers be the only one doing that would greatly reduce the attack surface/bug potential.
https://github.com/ninenines/cowboy/blob/master/src/cowboy_p...
I'm guessing around here would be interesting to add a test case to handle.
As far as whose server this is? I'd guess Heroku or AWS, though it's plenty possible T-Mobile could have devised some proxy to inspect traffic, but seems unlikely they would do so with Cowboy?
$ cat <<EOF | nc example.herokuapp.com 80
GET /test HTTP/1.1
EOF
----
HTTP/1.1 505 HTTP Version Not SupportedRequest
printf 'GET / HTTP/1.1\r\nHost: example.herokuapp.com\r\n\r\n' | nc example.herokuapp.com 80
Response HTTP/1.1 200 OK
Connection: keep-alive
Server: SimpleHTTP/0.6 Python/2.7.6
Request printf 'GET / HTTP/1.1\r\nHost: example.herokuapp.com\r\n\r\n' | nc example.herokuapp.com 80
Response HTTP/1.1 505 HTTP Version Not Supported
Connection: close
Server: Cowboy strcpy( ( char * ) commsOrderBuffer, "GET /v1/printer/");
strcat( ( char * ) commsOrderBuffer, ( char * ) settings.getIMEI());
strcat( ( char * ) commsOrderBuffer, "/orders.txt HTTP/1.1\r\n");
strcat( ( char * ) commsOrderBuffer, "HOST: ");
strcat( ( char * ) commsOrderBuffer, SERVER_NAME);
strcat( ( char * ) commsOrderBuffer, "\r\n");
strcat( ( char * ) commsOrderBuffer, "Authorization: Basic ");
What the.... O(n) string concatenations, unnecessary pointer casts, no bounds checking... I think extra whitespace in an HTTP request is not their only problem.(Or since they are already using std::string in other places, maybe just do that everywhere, I'm sure it makes better choices than they did here.)
The pointer cast thing is glaring. Why not simply declare the buffer as a char array and be done with it, instead of casting at every use? IMO over-use of pointer casts is a clear sign someone is lost in the language, your goal should be to reduce them.
char *a = "Hello " "world!";
Works just fine.Edit to add: You can really see the difference in code between someone coming to C/C++ from a high level language and someone who learned assembly first, where a list of literals is a common idiom. The original style is not functionally wrong, but it does look like Java :-)
Also: DON'T post your potentially insecure string handling code on the Internet; are you crazy?
Yes, I'm saying that I'm ok with the code above assuming that there are no user inputs that can exceed the bounds (though casting away the const is strange, I assume the stdlib is not correctly consted?)
According to the new HTTP/1.1 RFC 7230, it should be a single space - the previous RFC didn't specify this clearly in the wording, although it is implied by the grammar (SP and not 1 * SP).
https://tools.ietf.org/html/rfc7230#section-3.1.1
"A request-line begins with a method token, followed by a single space (SP), the request-target, another single space (SP), the protocol version, and ends with CRLF."
I'm surprised there doesn't seem to be any widely-used and easily available HTTP conformance checker - unlike the well-known HTML validators.
This is also why monospace fonts are ideal for seeing small but significant differences like this.
> Simply being more explicit about what is valid HTTP means that most of the security attacks that worked on Apache were rejected outright when tried on Mongrel.
Which I guess is a qualified "sounds like it, maybe?"
There is one called Co-Advisor [1] that can be used to test web proxies. It is commercial and pretty expensive, but the online version might be free for open source projects. Squid and Apache Traffic Server are tested with it [2][3]. There was a USENIX talk that showed some Co-Advisor results [4]
1. http://coad.measurement-factory.com/details.html
2. http://wiki.squid-cache.org/Features/HTTP11
3. http://trafficserver.apache.org/acknowledgements
4. https://www.usenix.org/conference/lisa12/rolling-d2o-choosin... (at 31:16 in to the video).
When you build stacks on top of system for which you have no direct control, you must be able to adapt your system. This means you can't statically deploy code without an upgrade path in one way or the other.
Yes, if you let other people run your infrastructure, you are beholden to their operations decisions and schedules.
It is not impossible to design around that (new) problem, but it is sometimes expensive.
The trick is to know what external dependencies you have, and that is almost impossible to fully quantify in the XaaS and cloud model.
Cowboy apparently shot yor no-good dirty sidewinding web requests in the face.
Request-Line = Method SP Request-URI SP HTTP-Version CRLF
Source: http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1
I ran into this a few years ago with Coyote Point load balancers. It turns out that if you send HTTP headers to a Coyote Point load balancer, and the last header field is "User-agent", and that field ends with "m" but does not otherwise contain "m", the connection does not go through the load balancer.
Complaining to Coyote Point produced typical clueless responses such as "Upgrade your software". (The problem wasn't at my end, but at sites with Coyote Point devices. Fortunately, I knew someone who had a Coyote Point unit, and we were able to force the situation there.) I had our system ("Sitetruth.com site rating system", note the "m") put an unnecessary "Accept" header field at the end of the header to work around the problem.
Coyote Point's filtering software is regular-expression based, and I suspect that somewhere, there is a rule with a "\m" instead of "\n".
A current issue: there are some sites where, if you make three HTTP requests for the same URL from the same IP address in a short period, further requests are ignored for about 15 seconds. You can make this happen with three "wget" requests. Try "wget http://bitcointalk.org" three times in quick succession. Amusingly, this limiter only applies for HTTP sessions, not HTTPS.
http://www.joelonsoftware.com/articles/fog0000000319.html
The design of strcat() itself is partially to blame for this - the return value could've been more useful, like the number of characters in the resulting string or a pointer to the end of the appended string so it could be used to chain concatenations, but instead they chose to return the exact same pointer that was passed in as the source.
This is what I see in Chrome on OSX.
body.blog .blog-post p { overflow: scroll; }
We had a similar bug reported at work recently, and it turned out that Windows browsers will always show scrollbars but the ones running on OS X/iOS will hide them until you start scrolling.
To turn them on in OS X, go to System Preferences > General and set Show scroll bars to "Always".
This incidentally led to the bug that they're blogging about too.
p { overflow: scroll; }
Pizza drivers are often the victims of crime. Not only for the small amounts of cash that they carry, but sometimes just for the pizzas.
edit: I should say that my comment here was a kneejerk reaction to "it's just pizza", and has nothing to do with how eatabit.com deals with this kind of harassment. i agree with other commenters that blog posts like these are a great way to promote the company.
We're not (all) in the "think-of-things-to-do-with-stolen-information" business like so many others are; but many of us are we're in the "encrypt-all-the-things-so-that-information-isn't-stolen" business.
I remember one case where the coefficient table for a polyphase FIR filter we implemented in an FPGA caused huge instability problems in a design. The coefficient table, if I remember correctly, was 32 wide (32 multipliers) and 128 phases long. That's 4096 numbers. The design had about 40 of these tables that would be loaded from firmware into FPGA registers in real time as needed. We built a tool in Excel to be able to compute these tables of FIR coefficients.
We got word from a customer that things were not behaving correctly under certain circumstances. We were able to reproduce the problem in the lab but could not find anything wrong with the FPGA, microcontroller or Excel code after about three weeks of work by three engineers. This quickly became a nightmare as it threatened several lucrative contracts and failed to service our existing customer base adequately.
I had to put our other two hardware engineers back to work on their existing projects so I took on the debugging process. This was the most intense debugging I've had to do in thirty years of software and hardware development. Lots at stake. The very reputation and financial well being of my business was at stake. Enter 18 hour days, 7 days a week.
FOUR MONTHS LATER, at 2:00 AM on a fine Sunday morning without having slept for three days looking at code the bug jumped out at me. We've all had that moment but his one was well "one of those". The problem? We used "ROUND()" in instead of "ROUNDUP()" in calculation that had nothing to do with the FIR filter coefficients but rather affected the programming of counters related to them. This caused timing errors in a state machine that drove the FIR filters. If this were software this would be exactly like having the wrong count in a loop counter. Yup.
I re-calculated after making the change and everything worked as advertised. That was the best Monday I've had in years. And I took a long vacation after that.
Over four months to find a bug.
That's why sometimes it is impossible and even unreasonable to create budgets for software development. One little bug can set you back weeks, if not months.
I know this is not a popular opinion among the HN crowd, mainly due to the entire web's love of linking to some other site's js/css to offload cost from their own site. But this makes no sense; you're not really reducing costs, you're just delaying them.
People talk about how 3rd parties speed up development or (potentially) reduce costs. But if the success of your business depends on providing a service all the time that has to be reliable, the reliability of your product is directly proportional to the reliability of the 3rd party. And each 3rd party adds additional points of failure. If you don't control whatever service or product the 3rd party is giving you, you will be unable to even attempt to isolate and fix it yourself.
Typically the answer to this problem is 'buy a better service contract'. But if the 3rd party doesn't provide 24/7 365 support along with multiple contact methods and harsh penalties for failing to supply you with timely service, you're wasting your money. You don't want to be the guy who has to tell the CIO "Sorry, I can't get a hold of our service provider or they aren't giving me timely updates, so I do not know when our product will be up again."
This attitude has many a startup reinventing and supporting commodity infrastructure instead of focusing on developing unique products and value for their customers.
I fired up wireshark and saw that everything looked fine... except that all of my line terminators were shift-in-formfeed instead of carriage-return-newline. It turns out that OCaml uses decimal character escapes instead of octal. (This was back when I was under the impression that portable code avoided use of \n in string literals because someone who misunderstood text mode file handles had told me that Microsoft compilers expanded \n to \015\012.)
Apparently someone at Yahoo had experienced enough terribly terribly written web clients that they wrote their HTTP server to accept any two non-space whitespace characters as a line ending.
Am I the only one who read this as a system using 3D printing to print food? Disappointed to discover it's not that kind of cellular.
There were a few people using this utility with no problems until one day a particular POP3 server no longer tolerated my utility's malformed requests.
But when I put nginx in front as a proxy, it denied all requests.
This is treated as an invalid request:
http://example.com//robots.txtYou can have an empty segment in the path. The BNF for a segment is:
segment = *pchar
Which according to RFC2234 section 3.6 means zero or more repetitions.In fact, it would not be a smart move to just treat double slashes the same as single ones, because of relative URLs: a ".." segment only removes one slash, so the hierarchy levels would get messed up. thttpd is doing the smart thing here.
As one of my teachers at university would say: the empty segment is also a segment.
(The problem in my case was just stupid spiders that were crawling my sites.)
Objectively, you need to write more tests. At the minimum, this bug should have a regression test so that it can never accidentally happen again (say when a dev merges an old branch in for whatever reason).
I'm far from a TDD purist, but it's clearly true that they're not sufficiently validating their code. If they had been, this would not have happened. I'm not saying this as an attack on their skills as programmers, but as caution to others reading the story: you have to - have to - test your stuff.
It's one thing to lean on third-party libraries and expect them to mostly Do The Right Thing, especially if they're popular and come from a culture of valuing test coverage. If you're writing a Rails app, for instance, you might be forgiven for not writing your own independent validations of the Ruby methods you call. But writing string-building code to implement RFC-defined network protocols? You should have some confidence that your program is generating the output that the other party will be expected. Especially with something as commonly proxied as unencrypted HTTP; you just have to assume that your data will be traversing and analyzed by systems 100% outside of your control.
That is precisely the opposite of objective. Personal thoughts, feelings and opinions are subjective by definition. 2+2=4 is objective. "You need to put more cheese on that pizza" is subjective.
It's the Erlang VM you love, but with the Ruby syntax we all enjoy!