Skip to main content

My Proxy Rabbit Hole

While working on my React class, I was following an example that attempted to HTTP POST to a dummy REST API web site. It wasn’t working and I could see in the dev tools that I was getting errors on the console from the browser about a CORS problem.

CORS, which stands for Cross Origin Resource Sharing, is a security measure built into a browser that causes it to refuse to make calls to an API in a domain that is different from the domain that the web app making the call was loaded from. Thus, if you load an app from someapp.com (localhost, in my case) and try to call an API on someotherdomain.com (the dummy site, in my case) the browser will block it, unless someotherdomain exchanges certain headers with the browser that says it will accept such calls.

In my situation, the dummy site alleged they were providing the correct headers, so I suspected the issues getting them were caused by the site being proxied behind a DDOS protection gateway. That, or I wasn’t doing something correctly.

When I started reading up about the problem on the Web, I started to come across a variety of articles and posts that provided an alternative best practice for making HTTP calls from a web app. Their core idea is to send all calls back to the web app itself, which then proxies them out to other domains. That way, the app, not the browser, is making the calls and thus there are no CORS issues.

The standard way to proxy in a React app, I discovered, is to load and instantiate http-proxy-middleware, and then attach it to the Express app to be used in particular contexts – meaning, for particular URL routes. I was able to get this working up to a point, but then ran into additional problems with the gateway.

The problems were related to my using HTTPS from my app to the gateway and on to the dummy site. The gateway was using Server Name Indication (SNI) as part of the cert negotiation in their TLS handshake, but my proxy middleware was sending localhost, not the dummy site, as the target server name because localhost was the actual target of the original request. Though I searched high and low for an option on the middleware to change this, I couldn’t find anything similar to what the -servername option to the openssl s_client does.

Thus, I went the next deeper step and installed an nginx web server on my machine and got it to successfully reverse proxy GETS from my browser to the dummy site using config like:

location /datasource/ {
    proxy_pass https://example.com/endpoint/;
    proxy_ssl_server_name on;
}

I went back into my React app and removed the proxy middleware for the app and, instead, simply configured the package.json file to proxy all HTTP calls to the nginx server. The nginx server would then proxy those calls out to the gateway, which, in turn, would proxy to the dummy site. QED.

In the end, I decided I liked this approach better compared to the proxy middleware, because I could completely control the proxying and HTTP aspects of my app without needing to change code and rebuild and redeploy. Not to mention that nginx provides far more powerful control than the middleware ever could.

I think my next step to take this to production would be to dockerize my app and the nginx server and then try using docker-compose to bring everything up together.

Plugin DOM manipulation collisions

I have a number of browser plugins and many of them operate by manipulating the DOM for a page before rendering. This morning I noticed that one plugin had added its small, clickable icon right over the top of a different small clickable icon, right justified in a form input text box. The result was that there was no way (that I could figure out…) to get at the underlying icon. I’m not enough of a front end guy to know how difficult this layout glitch is to avoid, but it seems like someone didn’t anticipate there could be other elements in the text box, or they needed to take better care to position relative to any such elements.

Fictitious Data

While entering some dummy data into some code for testing, I got to thinking about the 555 fictitious phone number in the US and whether or not there is an equivalent value for email and domain names.

It turns out that IANA has reserved the domain example.com and the top level domain .example for fictitious purposes.

It also turns out that numbers beginning with 555 do actually exists in many cases. The only reserved range (within all US area codes) is 555-01xx. Also, in plenty of other places in the world, 555 is a perfectly working prefix. There really isn’t a single value you can use that is guaranteed.

Thus, for fictitious phone and email , the first value I’m going to use are 818-555-0123 and jdoe@example.com

Taking Notes

It’s not just scientists that need to take good notes in their lab notebooks. Every day as a software engineer you are figuring out code, determining processes, making decisions, and learning detailed concepts. How many of you are documenting all this, though, writing things down as you go so that others, and even your future self, can benefit from all this hard work?

I challenge you to approach things much more like a scientist or (real) engineer does and start keeping a lab notebook and also publishing your results. It can all be virtual, of course, and probably should be to be searchable and to maximize its visibility to others and across your devices.

Taking a course? Write down your notes. Figure out how to make something work? Write down your notes. Listening in on a meeting? Write down your notes. Working on a project? Write down your notes.

This might be one of the most important skills you can learn.

Your Product is More Than Your Service

As a software developer, it’s easy to forget you have customers. I mean, of course you know you have customers. But, without the personal interactions you get as, for example, a retail salesperson or a restaurant waiter, you may need to remind yourself that your seemingly abstract actions and choices have very real effects on people. Pay attention to times when you’re annoyed or disadvantaged by the choices of the software you rely upon, and resolve to avoid committing the same offenses against those that depend on you.

I was reminded of this advice this morning as I went to pull up the O’Reilly Media Learning site to continue my React class and all I saw was this…

On the one hand, fair enough. Live services occasionally need downtime and early on a Saturday morning is probably a reasonable time for it. But, notice there is no indication of when the service would likely be restored. They provide a hint that the downtime will be quick, but 2 hours later, with no updates provided, “…in a flash” seems simply disingenuous. This is clearly more than a simple platform restart. Speaking of updates, there are no warnings of upcoming maintenance, or even status messages of any kind, on O’Reilly’s social media feeds. I took their advice and tried pinging the support email, but you just get an impersonal robo-response and I doubt I’ll see anything further until the outage is over when I’ll get an equally impersonal “Thanks for your patience while we work hard to improve your experience. All services have now been restored.” response.

This is just crappy, lazy work from O’Reilly. It turns me from being mildly frustrated at, yet understanding of, the disruption of my plans to being actively irritated and thinking of ways to broadly share my negative experience.

Let’s take it to heart as a lesson in what not to do, and focus on how to be better developers. Make sure you build your muscles for communicating with your customers, using all the available mechanisms. Give them fair warning, multiple times and far enough in advance that they can act on it. Be transparent about what is going on, even if an outage is unscheduled or you don’t have a resolution ETA. Don’t suggest support channels if you’re not prepared to respond appropriately. Mostly, remember that your product is not simply the normal functioning of your service, but the small quality of life touches that go along with it and make the customer experience worth coming back to.