More from sibervepunk
I learned how to swim at the age of 26. Or rather, I'm still learning. In my last lesson, I managed to swim 50 meters without using any support (and I didn't drown, lol). In the lesson before that, I got dizzy, my leg cramped three times, and I had swallowed half the pool. (you could see water draining) So today, I can't quite say, "I know how to swim now." But I also can't say, "I don't know how to swim." I'm learning how to swim at 26. And I have a few observations about it. First of all, there are a lot of children at the pool. A lot. And they're incredibly good at swimming. The first thing that happens when you start learning to swim as an adult is that, while you're desperately struggling around trying not to drown and taking huge breaths that somehow end up with you swallowing the entire pool, tiny little kids are happily swimming right beside you. It's an incredibly humbling sight. It strips away the ego you've built up over the years and the confidence that comes from being able to handle most adult tasks with ease, and suddenly you realize you've taken on something you know absolutely nothing about. Something that even children are better at than you. Fortunately, dealing with that part wasn't very difficult for me. One of the best skills I've ever developed in life has been being able to say, "I don't know," and accepting that I don't know. So accepting my lack of knowledge & skill came quite easily. The next challenge was digesting all the fear I had accumulated over the years. In the very first lesson, I was supposed to swim about 25 meters using a kickboard and fins. Instead, the moment my feet left the ground, I started flailing, struggling, and trying not to drown even though my head was above the water the whole time. My first few lessons were spent simply trying to get into a horizontal position in the water. Up until that point, it was all just fear of the water. My instructor literally forced me to the bottom of the pool, and I saw that I could come back up. Once I realized, somehow, that nobody was going to let me drown in that pool, I started being a little less afraid. Even then, it took me getting three leg cramps just to make it 25 meters with a kickboard. I was tensing my body far more than necessary and pushing myself to an absurd degree. By the end of the first month, my only plan was to quit. To justify it, I had convinced myself of all sorts of reasons: that my instructor wasn't attentive enough, that I wouldn't have time for swimming lessons, that maybe swimming just wasn't for me. I kept going through that first month simply because I had already paid for it (while also looking for every possible excuse to conveniently skip lessons whenever I could), but watching the people who had started at the same time with me improve while I was still struggling so much made me feel awful. One day, about an hour before class, I was sitting on the floor of my bedroom thinking about why things were going this way, why I couldn't do it, why I would never be able to do it. My spouse came in and told me to get ready for the pool. I told him I couldn't go. He said, "I don't think you're afraid of the water. I think you're afraid of failing." I cried a lot that day. I didn't fully understand what I was feeling, but I was certain I wouldn't be able to get into the water. Ever since the beginning, every single day I had been trembling as I walked through the door, making self-deprecating jokes and coming up with excuses to turn back, but that day I couldn't even bring myself to leave the house. I wasn't confronting my fear of water anymore. I was confronting my fear of failure. After taking lessons, trying at least five or six times, I still felt like I was exactly where I had started. And I felt like I would never get past that point. The next day, before class, I went back and read some of my journal entries. I remembered how, during my first lessons, I couldn't even get into the water with a kickboard, and I remembered the cramps. At the same time, I realized something: every single day I chose to go swimming, I ended up swimming better than the version of me where I didn't go at all. That day, when I got into the water, my instructor happened to be busy with other students, so he left me alone for a while. Instead of following memorized instructions like a robot, I tried to understand how the water actually worked. I experimented to see what happens when I did different things, and by the end of that lesson I realized I could stay afloat on my own. At the end of class, I told my instructor that my learning style was to repeat something until I truly understood the dynamics behind it. I needed to discover every possible outcome of a movement through trial and error. I started feeling a little better. In the next lesson, I practiced not next to the wall but between two lanes. My instructor believed I could do it now. Even though I resisted a lot, he refused to change his mind, and I tried to stay afloat between the lanes, with no wall to hold onto. On my way to the lesson after that lane incident, I noticed my feet wanting to turn back again. I can analyze my own pattern now. Whenever there's a new challenge, an unfamiliar path, taking that first step doesn't come easily to me. When I had finally gotten used to swimming safely alongside the wall, knowing that the next lesson would be between the lanes scared me. Then I got used to swimming between the lanes, but now I had to let go of my kickboard. After swimming without the kickboard for the first time, I once again didn't want to go to the next lesson. Then I learned to let go of the kickboard. Next came getting rid of the fins. We had a lesson where I swam 50 meters without fins, without a kickboard, without any kind of support. And yet I still didn't want to go to the next lesson. Even though I had done it, even though I had concrete proof that I could do it, the idea of getting into the water without fins in the next lesson terrified me because I still wasn't confident in my abilities and I didn't know whether I would fail or not. Once again, I couldn't bring myself to go. That's where I am now. I convince myself to go to class (most of the time by telling myself not to waste the money I've already paid), and I'm incredibly happy whenever I manage to do something I couldn't do before. Just being in the water gives me enough courage to attempt something I've never done before, and I finish the lesson. Before the next lesson, I'm afraid again because I know I'll be facing something new. I skip lessons with all kinds of excuses until, the next day, I convince myself all over again and see that I was actually capable of doing the very thing I was afraid of. I have to remind myself of this pattern often. That many of the situations I feared so much, the ones that sent me into anxiety and fear spirals, eventually turned into skills I genuinely enjoy, and that I have more than one example of this happening. Before my next swimming lesson, I'll read this piece again. Every time I try something for the first time and don't become great at it within ten minutes, I'll remember what learning to swim felt like. There is nothing quite as satisfying as learning something new, especially something you're bad at, and watching yourself slowly become good at it. These are some of the moments that make you feel like you're truly living, like you're expanding your own limits with your own hands. I can't wait for swimming in the open sea and to exploring the open sea of possibilities by taking on new things I'm bad at. Thanks for reading. If you have any feedback or would like to discuss further, I would be happy to hear from you. twitter | [email protected]
Thanks for reading. If you have any feedback or would like to discuss further, I would be happy to hear from you. twitter | [email protected] Previous
Most of the audience reading this post think of some random new programming tool dropped recently when the word library comes up. Let’s leave our déformation professionnelle in the door and think about the libraries. Book ones. This post is an ode to them. I am not sure if libraries work the same way everywhere around the world but in my country they are completely free, you can sit for hours, borrow books, again, for free. The idea of borrowing something from an institution without owing them anything in this time we’re living in amazes me. I mean who gives you free stuff (except free pain)? This fact itself is enough for me to think libraries are amazing. I consider myself a decent book reader and it’s been a long long time since I had to pay for a book. But this isn’t the only think I like about my libraries. So the story begins with me, a remote working software developer getting married to a remote working software developer. My husband and I are a newly wed couple with all the fun and silliness but life (work) gets in the way naturally. Traditional couples see each other a few hours every day, and usually spend the weekends together to make up the lost time. We don’t have the lost time. We’re together, always. Working in the same room (our home office) resting in the same room etc. and god, we annoy each other. Love only goes so far, folks. Love is great for your daily life, for your home. But what if your home is also your work? And what if your work needs some limits on the PDA? You can (ideally) leave your work stress and burden when you leave company building. However, when remote working, you’re not leaving work at all and even if unintentionally, that mood rubs off on your partner, who has the same tension from work. I’ve spent all of my teen years and a couple of my twenties in student dormitories which I had to share my room with at least 4 other girls. That fact alone justifies that I love and need my personal space and time in my home. And my partner also needs that, even if he doesn’t say so, I know he needs. And we respect each other on this and try to leave the house for a couple hours every now and then. Again, any traditional couple may not need this kind of arrangement, one or both of them having to leave for work, but we’re not like the other couples. It’s not always related to your partner / roommates / family. Even if you’re having enough personal space, enough distance from others, home office still can be life sucking. I’ve spared the biggest and prettiest room of my house as the home office. I’m talking about wall-size windows, glittering sea in front of me, big sky and trees. There is a real view I can’t describe enough. (It’s a house that’s a few decades old, and we are just tenants so don’t think too much of me lol) And I’ve decorated the office pretty nice, spaced, refreshing. Even with that perks, being at home all day just consumes my soul. I can't focus after a couple of hours. Especially if I haven’t left the house all day, rolling out of bed straight to the desk, it becomes too draining. I need the concept of leaving home for work, and I need the feeling of “arriving home”. Getting cozy again after a long day, hiding from darkness of the outside world (work) Being at home while working AND while resting, my brain just can’t switch off between work and rest, drawing a line between bad and good. I’ve talked about my feelings, but no need to mention here, you’ve probably read all about health and psychological problems that remote work causes. With all these said, it’s almost mandatory for me to adapt a hybrid work approach. You may think, just go back to the office. No, no. This is not an option. First I don’t even live in the same city with my office building. Even if I did, it’s too late for me to adapt to office work. My work life started remote, even my internship was remote. I don't have office experience. I don’t know what am I going to do if I have to work in an office job in the future. Leaving your warm bed, rising before the sun in the morning (and I’m a morning person believe it or not), getting ready, commuting, traffic, thinking about what to eat in the office, commuting again, leaving you no time to live your life.. No. I don’t want to think about that possibility. It’s not for me. Also having a home office is not bad at all. Somedays you just don’t want to leave the house, maybe you’re a bit sick, or just not feel like it. It’s good to have the option to stay in bed while working. In other words, stay in bed and get paid. I just need a context switch for a couple days in a week. So what to do? Go to nearest coffee shop. You’re lucky if they don’t play tasteless trendy music. You’re lucky if a waiter doesn’t keep asking if you need anything, isn’t intrusive, and doesn’t subtly let you know when it’s time to leave by checking on you constantly . You’re lucky if no teenagers talking loudly about their-whatever-teens-talk-about-these-days. Oh, by the way, pay a lot of money to be here and to drink a nice cup of burnt coffe. Working in the coffee shop might feel cool just for one day, just for the vibes. Not maintainable. Then rent an office or subscribe to a co-working space? What? I get paid to work, not to pay for it. And here comes the raison d’être of our ode, libraries. Go to your local library. Set up your working tools. That’s it. No one will talk to you, if you’re in a relatively small one, chances are no one will be there. Just you, the nice vintage smell of the books surrounding all over, and a nice vibe. You’re tired, want to take a break, you’ll walk around book shelves and you’ll see there are very odd books on very specific topics. Take it, or laugh at the title, free amusement. Share it on twitter, free likes. Find some hard-cover, old, brown page books. Smell them, feel good. Free joy. Get back to working. Stay focused, finish your tasks without your bed luring you to itself. No distractions, no funny businesses. I use a technique that maybe we can call laptop-driven-development: working until my laptop does not feel like it anymore. I don’t plug my laptop so my work has a natural deadline for the day. I need to stay focused and get things done, or I’m gonna have to get back home with leftover tasks. Fall is on the way, maybe it’s raining outside. With big windows all around you, overthink your life while waiting for the rain to stop before heading back home.. This is my call to all the remote workers or students or any other people staying home too much: Go to your local library, enjoy it, support it. Cherish it. Not just for working. Use it for thinking, for reconnecting, writing or creating. The library is a sanctuary where your mind slows down, even though the world outside keeps running. Maybe you’ve been postponing to think, to reflect, to spend time by yourself, like I did before I discovered my local library. You’ll find some kind of joy and productivity in there. We don’t have so many pure-good organizations in our world. We should appreciate them while we still have them. I’ll admit that this post can be a little biased, because my local library isn’t exactly a popular spot. Most of the time, I’m the only one in a room, and there are only 3–4 people in the rest of the library. It’s just a 20-minute walk from my home, so I get to walk my daily steps in on the way there and back. And some of the rooms look like this: Yes, I’m lucky on that. Yes, this is where I write this blog post. This post has been discussed on Hacker News, you can join the conversation there. Thanks for reading. If you have any feedback or would like to discuss further, I would be happy to hear from you. twitter | [email protected] Previous
know thyself There is a new lifestyle imposed on almost the entire world, willingly or unwillingly, perhaps by powerful people or by many small people that want to be powerful, which somehow affects all ordinary people: a consumption-oriented life. Fast consumption, constant consumption, more consumption. I don't have much to say about the "shopping" side of this consumption craze because it's a topic that's been around for many years, born out of -ism movements and studied numerous times through -ology disciplines. It has been the subject of public service announcements, romantic comedies, and personal development books. The public has been constantly educated about it for years. Two guys known as The Minimalists and some "smart" people like Marie Kondo made a fortune out of this movement. Personally, I believe I am a conscious consumer, and the shopping craze doesn't affect me much, so I want to look at the other, often-discussed side of the issue. The consumption I will discuss is digital content, information, and emotion/thought consumption. I know there are social science studies that delve into the intersections and background connections of all these consumptions, but as an ordinary person, I want to talk about the effects on my own life, particularly my professional development. Although it has been on my mind for a long time, I haven't been able to read a comprehensive book based on these studies (the reason being the vicious cycle based on this topic), but I have consumed plenty of content... I've watched various TED talks, several indie YouTuber videos with a wholesome background, selling personal development under the hood on their newly launched channels, and of course, read tweets... I've also had plenty of opportunities to observe myself. At this point I am convinced that fast consumption is harmful to the brain, mind, and soul. The main reason I pursue this topic is that, aside from all the side effects in personal life, it also prevents me from being better at my profession as a brain-worker as Jules Payot puts it. In disciplines like software engineering, constantly improving oneself and being in a state of continuous learning is an inevitable process. Even if you don't put in extra effort and just try to do your job, you have to learn a new concept or technology. If you do put in the extra effort, you become someone who does their job better. Since graduating from undergraduate studies (which marks exactly one year as I write this post), putting in extra effort has been my top priority. Working more, reading more, knowing more. In addition to technical studies, I also read about and received advice on soft skills related to "software crafting." One of my first mistakes, I think, was taking every kind of advice from everyone. Even if I didn't implement them directly, these pieces of advice took up space in my mind, and thinking "what if that's better" prevented me from putting any of them into practice. The problem with online advice is that the person writing the blog post is doing so entirely from their own perspective and lifestyle. They have no idea about you, and you have no idea about them. There's no guarantee that what works for them will work for you. Moreover, you don't get a chance to question causality, you just read the advice, consume it, and move on. It takes up space in your mind and on your to-do list, but you don't get a chance to internalize or filter this topic. You don't even realize that you should actually do so. One of the pieces of advice I took without realizing it was to systematize the mentioned studies, work regularly, and similar. Once that idea put in my mind, things became complicated for me. While working full-time, I had to balance my personal life and stick to the plan. No matter how much your willpower sticks to the plan, your health, developments in your life, and your brain, which sometimes refuses to accept more information, don't always stick to the plan. When this happens, it becomes difficult to establish the system I mentioned, and you start looking for more advice, reading more blogs. You find yourself in a quest for productivity, feeling productive because of the quest, but not really doing any productive work. Advice also has the effect of reducing creativity and problem-solving skills. When I have a problem, technical or other, the first thing I do is research the solution. As a result, I don't get enough chance to think about my problem, let alone produce a solution, and I don't fully understand the problem. I've "consumed" what I should do and how I should do it many times from different people. With all this information occupying my brain, I no longer had the energy and resources to produce a tangible output. Because of my profession, I like learning different concepts from different fields. I am particularly curious about the low-level infrastructures and systems behind high-level tools, and I am aware of the contribution of knowing these to doing my job well. However, because of the constant rush and haste imposed by social media in my life, I can't devote enough time to these resources. Because I am so used to seeing information, quickly taking it in, and moving on to another topic. Because the short content I constantly consume, whether written or visual, has made me accustomed to this. I want to know everything, immediately, quickly. Since this is not humanly possible, I end up doing nothing. I can't think long-term; I can't stop myself from thinking that working on a book for 6 months, doing its projects, is a huge waste of time for me, and because I already feel late, I find myself, yet again, in a cycle. When I'm focused solely on consuming, my ability to produce naturally decreases. I include speaking, being able to express oneself, and having a good command of words in this context. After knowing myself as someone who has always been good with words for years, seeing that I can't choose the right word when speaking, or that I can't convey the message or information I want to give more clearly and simply when writing, naturally bothers me. Although it is said that software development is an antisocial job, you constantly need to communicate with people, either in writing or verbally, and you need to express what you have done and what you will do well. I am approaching the point of losing this skill by consuming instead of producing. While all this disrupts progress and confuses my mind, I also have to deal with the physical and mental side effects of fast consumption. Difficulty concentrating, lack of focus, inability to understand what I read, stress, anxiety. I see these kinds of complaints from many people lately, and in my opinion, our biggest common ground is digital content consumption. The relativity of time is a reality I feel to the core while doom scrolling. Besides the lost time, there's the confusion after realizing it and putting the phone down, trying to get my dazed mind back to normal. And then, not finding anything to do, not being able to putting yourself together, and reaching for the phone again. Everyone has seen the articles about the brain's approach to social media content, which offers a quick, easily accessible way that makes you happy or, even if it doesn't make you happy, offers an escape from the thing that makes you unhappy. When you put these into words or write them down, it bothers you a lot, but I think knowing yourself is the most important thing to do before changing yourself. I know what I'm doing wrong, and now it's documented in front of me. I also know what I need to work on. We are talking about the harms, but I have always been fascinated by the opportunities the internet offers. Being able to communicate and chat with someone from anywhere in the world within seconds is an invaluable blessing. It just takes a little effort to filter to see and reach the right people's content. Otherwise, I don't think completely withdrawing would be very beneficial in my industry and the era I live in. I won't go against what I mentioned so I won't end this problem-filled post with advice or plans. That's why I started with the quote "know thyself." I just tried to see and make the problem tangible. I will stop researching what I can do for a while. First, I plan to clear my mind of clutter, quit this fast and excessive consumption habit I have acquired without realizing it, and then learn how to consume slowly and gradually. I have enough raw information to discover how to do all this myself; I will now give myself the opportunity to process it. This post has been discussed on Hacker News, you can join the conversation there. Thanks for reading. If you have any feedback or would like to discuss further, I would be happy to hear from you. twitter | [email protected] Next
More in technology
Well, well, well, well, well, well, well, well, well, well, well, well, well, well, well. We're back. Sorry. We've been watching the onslaught of vulnerabilities flood the internet. Every man, dog, and their grandmas (apparently?) are now using LLMs to find and reproduce vulnerabilities - it’
You want less of them. That’s the reason. You may find that it’s too hard to stop people from doing the thing, literally blood, sweat, and tears trying to prosecute people, but that’s a different thing.
Solitaire Alone Together I made a new game. It's called Solitaire Alone Together. It's Windows 98 solitaire, but you can play with everyone else on the internet. Read the full post on my blog! Here's a raw link, if you need it: https://eieio.games/blog/solitaire-alone-together
This post is a living diary of all the times I messed up something with my website in a funny way. I value those who have the confidence to own their mistakes and share the learning with others, and so this is me doing just that! That Time I Accidentally Made a Tarpit That Time I Accidentally Made Really Large Headers That Time I Accidentally Made a Tarpit Back to Top A "tarpit" is an unofficial term used in computing to describe an intentionally slow response to a request. In these modern times many people are using tarpits as a way to combat the relentless theft of data by AI companies, although there's little to no evidence of that actually being in any way effective. I don't use tarpits, at least not intentionally, but there was that one time when I accidentally created a tarpit and trapped all visitors in it. As I've shared previously, I refuse connections from IP addresses that are blocked or belong to a blocked subnet, and I enforce this firewall during the TCP handshake. The logic here is straightforward: there's no reason to waste resources doing a TLS handshake, accepting an HTTP request, and then rejecting the connection if I already know I'm going to reject it at the earliest step. At the time, the code worked like this: the HTTP server would repeatedly call the Accept() function below expecting a new connection. I've added some comments to help explain the logic. func (l *firewallListener) Accept() (net.Conn, error) { // Accept the connection from the TCP listener. This blocks until there is a connection to accept or the listner was closed. conn, err := l.l.AcceptTCP() if err != nil { return conn, err } // Separate the IP address out from the remote address (which includes the port) ip := utils.SocketStringToIPAddress(conn.RemoteAddr().String()) if ip == nil { return nil, nil } // Check if it's blocked, if so close the connection and return a refuseError if IsBlocked(ip, true) { conn.Close() return nil, &refuseError{} } // Otherwise return the connection on to the HTTP server return conn, nil } If the incoming connection was from a blocked IP then I'd return a refuseError. I need to use a specific error interface because the HTTP server will halt if it encounters a non-temporary error from the call to Accept(), so I need to return an error that satisfies the definition of a temporary error. I defined refuseError like this: type refuseError struct{} func (e *refuseError) Error() string { return "." } func (e *refuseError) Timeout() bool { return true } func (e *refuseError) Temporary() bool { return true } func (e *refuseError) Is(err error) bool { return err == context.DeadlineExceeded } This did accomplish the goal of rejecting connections before the TLS handshake for blocked addresses, but it had one really unintended and difficult to track down side-effect. Accepting connections is done serially, after which servers typically then process that request on a dedicated thread (or in Go's case a goroutine). This means that any delays during the accept loop will block all incoming connection. What I had missed while reviewing the code for Go's HTTP server is that when it receives a temporary error from Accept() is that while it doesn't abort, it does sleep for up to a maximum of 1 second. This sleep blocks the entire server for all incoming connections. You can see a trimmed copy of the code that does this below, with some marks I've added which I will explain. // src/net/http/server.go // Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. for { // (1) rw, err := l.Accept() if err != nil { if s.shuttingDown() { return ErrServerClosed } // (2) if ne, ok := err.(net.Error); ok && ne.Temporary() { if tempDelay == 0 { tempDelay = 5 * time.Millisecond } else { tempDelay *= 2 } if max := 1 * time.Second; tempDelay > max { tempDelay = max } s.logf("http: Accept error: %v; retrying in %v", err, tempDelay) // (3) time.Sleep(tempDelay) continue } return err } connCtx := ctx if cc := s.ConnContext; cc != nil { connCtx = cc(connCtx, rw) if connCtx == nil { panic("ConnContext returned nil") } } tempDelay = 0 c := s.newConn(rw) c.setState(c.rwc, StateNew, runHooks) // before Serve can return // (4) go c.serve(connCtx) } At mark 1 the server calls the Accept() function, this is the exact function that I defined above where I might return a temporary error. At mark 2 it checks if an error was returned, and if so if that error is temporary. If there was a temporary error, at mark 3 it sleeps for an increasing amount of time up-to 1 second, otherwise, at mark 4 it processes the connection on a dedicated goroutine, which allows the server to accept the next connection. I'm not entirely sure why the Go developers added this sleep delay and the change when it was introduced doesn't provide any meaningful insight. Regardless, it caused significant latency connecting to my website when a flood of rejected requests was coming in. It just goes to show how important it is to write meaningful commit messages, because you never know when somebody might come back years later wondering "why was this done?". I sure home I don't come to eat those words later. Coincidentally, you can actually see this happening if you look carefully at one of the metric graphs I shared in my first post about my server's security model: Securing My Web Infrastructure. This is the graph I shared in that blog post and while I didn't know it at the time, the fact that these request spikes all cap-out at around 60 requests per minute was not a coincidence. These requests were not being made with a limit in mind, attackers rarely ever care about things like that, instead it the accidental tarpit I had created. The downside to this was that while the malicious requests were being rate-limited, all requests were being rate-limited, up to a point of taking so long they timed out. The Fix Fixing the issue was relatively straightforward enough. Instead of returning a temporary error to the HTTP server during the accept loop, just don't return anything at all and wait for the next valid connection. func (l *firewallListener) Accept() (net.Conn, error) { for { conn, err := l.l.AcceptTCP() if err != nil { return conn, err } ip := utils.SocketStringToIPAddress(conn.RemoteAddr().String()) if ip == nil { return nil, nil } if IsBlocked(ip, true) { conn.SetLinger(0) conn.Close() continue } return conn, nil } } Now, when the HTTP server calls Accept(), the only time it returns is with a connection from an IP that isn't blocked, or if there genuinely is an error. No more sleep delays, no more excessive timeouts. That Time I Accidentally Made Really Large Headers Back to Top For about 10 years now all major browsers have support for a security feature known as a Content Security Policy or CSP. A CSP is an HTTP header provided by the server that instructs the browser on where it can load assets from, this could be scripts, images, stylesheets, fonts, etc. The objective of using a CSP is to prevent against injected HTML that tries to load assets, such as a malicious Javascript file, from a remote source. With so much user-provided content being available online, it's very possible for this to happen without an attacker compromising the entire web server. CSP protects against that by saying "scripts can only be loaded from these domains". That's a really simplified way of looking at it, anyways. My web server supports injecting the CSP header automatically, but before I go on I need to explain a little bit about the structure of my web server. When an incoming HTTP request is accepted (having passed all firewall checks and assertions), we look at the destination host for the request. This can either be the value of the Host header or as specified during the TLS handshake. We then look at a map of hosts to apps. Apps are just an interface that accept a few methods: type App interface { Cleanup() ReloadConfig() ServeHTTP(rw http.ResponseWriter, r *http.Request) Setup(dataDir string) error Shutdown() } One of the apps is the Proxy app, which is a reverse proxy - it accepts the incoming HTTP request and then proxies it on to another host. This is a very common design, especially with increasingly complex TLS setups. Because each app is unique to a host, and different hosts have different requirements for CSP rules, the proxy app includes a CSP preset that we use to build the header value, or skip it entirely. When the proxy app was going to copy an HTTP request to the downstream host, it would build the CSP header, however there was a slight bug... func (a *App) ServeHTTP(rw http.ResponseWriter, inRequest *ht2.Request) { // --snip -- if a.CSP != nil { a.CSP.ConnectSrc += " " + inRequest.Origin } CopyHttpRequest(inRequest, outRequest, rw, CopyHttpRequestOptions{ Origin: inRequest.Origin, Csp: a.CSP, Cors: a.CORS, AddHeaders: !a.SkipHeaders, UseHTTP3: a.UseHTTP3, InsecureTLS: a.InsecureTLS, }) } I'm really unsure as to what I was doing with the line to append to the ConnectSrc, but the impact is that I'm appending to a variable that lives on the App, rather than a variable that is per-request. This meant that every time there was a request to the app, any request at all, the origin would be appended to the header value. This went on for quite a long time unnoticed and unresolved, largely because I am constantly tweaking and tinkering with my web server, after all, it's how I made having a website fun again. Each time I restarted the server process, the header value would be reset, but only for it to continue to grow and grow. Eventually, after a period of being busy with other matters, the server process stayed running for long enough that the header value grew too large and HTTP clients began to reject it. There is no defined maximum for an HTTP header value, however most HTTP clients use 100KiB, which is perfectly reasonable, and this header value would continue to grow well beyond that. Diagnosing this issue turned out to be difficult as tools like Curl would fail with errors relating to entities being too large, but stopped short of saying what specifically. I eventually used openssl s_client to send an HTTP request by hand and observed my terminal window being filled with a domain name repeated thousands of times. Looking at the commit history, it was really unclear why I added the culprit lines of code. The commit message just says "Improved CSP support". It just goes to show how important it is to write - hey look it's those words I'm now having to eat! The Fix The fix was to just delete those three lines of code. Yup, it really was that simple, and fixing this bug actually made a larger positive impact than I had expected, as it was immediately clear when I fixed the bug by looking at outbound network bytes: So much traffic was being wasted on excessive header sizes. You might look at these mistakes I've made and think "wow, Ian, these are some obvious mistakes, I never would have made them!" to which I say "good for you!" with the utmost sarcasm and disdain. I enjoy making and refining software, and making anything means making mistakes along the way. Each time I make mistakes such as the ones above, I improve my skills of investigation, diagnosing, and repair. Skills that, judging by my peers in the industry, seemingly everyone is quickly willing to throw away because a robot does it "better" than you. Header Image: "Car accident on the Ffestiniog to Bala road. Nobody was hurt" by Geoff Charles, CC BY-SA 4.0, via Wikimedia Commons.