I’m working on a long Fogknife post about Webmention, a technology of deep personal interest, and one in serious want of introductory documentation. I had planned to turn my attention to neglected interests like these during the spring and summer, before the COVID-19 pandemic gripped the world — and, at the moment I write this, has sunk its terrible soft teeth into New York City deeper than any place else in America. My last article acknowledged the global condition as context, but it feels strange to hard-bounce from there into a long explainer about excitingly obscure website-communication protocols.
I still plan to finish and share that article soon — but in the interest of softening the transition into it, let me describe my life here in New York right now: my view out the window, so to speak, as I work on projects like this. (And if you want to read about Webmention in the meantime, Chris Aldrich coincidentally posted a link-rich thread on the topic this past week.)
First of all, I’m okay. We’re okay, my little family, my wife Amy and our cats and I, in our two-bedroom apartment in a big upper-Manhattan apartment tower. For the time being, I often forget that I live in a city so profoundly battered by the coronavirus, and with the worst still to come, that the whole world’s eyes have turned to New York with a sense of guttering hope against mounting dread. Over the past week, old acquaintances and elderly relatives I haven’t spoken to in years have texted and phoned me to check in and ask about our health and safety, and I every time I need to remind myself: Oh, right. I’m in danger.
So on that note, I must acknowledge how my family faces this challenge on Easy Mode: we are two healthy mid-life adults (and two healthy mid-life cats) with no dependents, strong social and financial resources, and livelihoods that we can carry on from a home office. (I normally work this way; Amy has had to adapt.) We absolutely feel the pressure of this bottle ordeal even so, and my heart bruises with empathy when I imagine the deeper challenges faced by those without such a multiply-layered and unstrained support setup. For example: anyone with young children, a group that includes many of my closest friends. When I think of the countless people who lost their jobs to the disease and can’t seek new ones, or who are forced to stay inside with dysfunctional families, my soul shrinks.
In the prelude to the lockdown, when New York still looked and felt like its usual self but perhaps with the volume tuned down a couple of notches, I posted a tweet (an amplification of an observation by Los Angeles Times correspondent Matt Pierce) that earned a certain degree of traction among people seeking a comforting message:
I’ve been thinking more about this and it’s worth repeating.— Jason McIntosh (@JmacDotOrg) March 13, 2020
“The virus” isn’t shutting down all of these services. People are volunteering to shoulder the burden of closure for a while specifically so that the virus spreads more slowly, so that hospitals don’t get overwhelmed. https://t.co/v4KOnfYZMV
Two weeks later, this remains true at core, but the voluntary community spirit I described has become muted in the ensuing day-by-day increase of municipally ordered social distancing and self-isolation. I do not fault the local authorities for applying more pressure every day: the situation is plainly grim. But already the thesis of my bright-side post from only one week ago, assuring my readership as well as myself that walks remain free and legal, seems tenuous. I hear of mass-quarantine conditions elsewhere in the world, and I wonder if they will arrive in my country. If they do, I have every reason to expect they’ll visit New York first.
But, yes, I’m still walking, and I want to tell you about a walk I took on Friday morning in particular.
I woke up on Friday determined to go out for my morning coffee. I had not gone to the local hole-in-the-wall Dunkin Donuts in several days; my last visit had shaken me. The staff, which normally has my online order waiting for me well before I arrive, had their hands full trying to disperse the career day-drinkers quietly clumped up as usual in the small shop’s corners. They did eventually shuffle out, looking hurt and betrayed, and then I was handed my coffee. I returned home feeling quite disturbed. For the first time, I saw what looked like cracks in my daily routine, even allowing for all those voluntary changes I’d tweeted about.
But by Friday enough time had passed that my desire for familiar comfort overrode my misgivings, so I fired up the Dunkin app on my phone. It showed me an adjusted version of the usual tiny map where you pick a store: the pin representing my usual Dunkin’s had faded from its normal Day-Glo orange to a dull gray. So had many other pins on the map, with only a few orange holdouts here and there. Tapping a gray pin suggested that the store was closed, at least to online orders.
The round, cheerful graphics delivering this information brought to mind the board game Pandemic Legacy, where one uses colorful stickers to track the destructive spread of a disease across a world map, noting which cities are infected, and which have collapsed into anarchy from the plague. I did not enjoy seeing any of this. At the same time, I saw an orange pin a twenty-minute walk up Broadway, more or less along one of my usual Riverside strolling routes. I asked it for a large coffee instead and then got moving, accepting my earlier-than-usual daily walk.
After picking up the coffee without incident from a shop empty of other customers, I looked around the unfamiliar intersection. This, too, felt like something from a game, this time an immersive 3D simulation which has removed all the people but left behind interesting “environmental storytelling” artifacts to suggest where they went. Some cafes and bars had chalk signs or tacked-up flyers insisting that they were open for take-out, but midmorning I saw no sign of life in any. I turned back to the park and home.
As I approached a dog run, I saw a man having a public temper tantrum. You can’t tell me where my dog can shit! he shouted to another park visitor, who held their hands up in an appeal for calm, backing up a step every time the man advanced, careful to stay six feet away. Other dog-walkers also tried to calm him down, also keeping their distance. By the time I passed he had already vented most of his steam. I don’t need this, he said, to nobody in particular. The dogs at everyones’ feet scampered and played together.
Then I sat on a line of empty benches and sipped my coffee and ate my cold egg sandwich while a city worker silently emptied out a public trash bin, putting a fresh lining in. I thought about the man at the dog park, and how I had blown up at my oldest brother two months ago in the middle of downtown Bangor. Our nerves were both frayed from our brother Pete’s death just days before, and some small slight made me explode at him. It must have looked just like that other guy.
Getting up to leave, I crumpled up my wrapper and put it in my pocket to dispose of at home. I found that I didn’t want to open the bin with my bare hands.
My neighborhood along the Hudson seems to be keeping it together, and so does my apartment building. I have hundreds of neighbors in this complex, and I like to think we look out for each other, staying aware and careful. If anything, we have become a little nicer to each other lately, exchanging small greetings and health-wishes as we share elevators or pass in hallways not designed for social distancing, hugging opposite walls.
And so far, I find it pretty easy to forget how I live in a dangerous place during a dangerous time. I’m okay and I probably will remain okay. But I can’t predict even broadly what will happen over the coming weeks. More cracks appear, small and large. My New York Times delivery simply didn’t show up today. If it had, I might have read about the New York subway train that burned, perhaps due to arson, killing its operator and injuring seventeen others. A horror that would have attracted national attention in normal times, but which today didn’t even merit the front page of the local paper’s online edition.
Learning this news yesterday calcified some of this miasmic dread into active fear, at last. I canceled a non-emergency doctor’s appointment that I normally would have ridden the subway to attend; it can wait a few months. None of us need any of this, and we all know it. I don’t know what I can do about it other than paying attention, and doing my best to be a good neighbor, and looking to the future.
And so I want to publish a long article about web technology next, or at least soon, because that’s me applying some control to a chaotic future: I can write that article and share it, and that therefore becomes a preciously rare event I can predict. The article itself looks ahead to a time when more people might have the free time and resources to think about growing the open web, and that helps me too.
During this strange time, I encourage you to consider the ways you can define your own future, however it best suits you and yours, and to move in that direction as best you can.
This article was also posted to the “coronavirus” section of Indieweb.xyz.
We live in a confused slice of history that Chuck Wendig has called “the ghost of normalcy”, a placental state that one day very soon will rip away and push us ready-or-not into a far weirder time of uncertain duration, followed by an unknowable permanence. Whether this tribulation lasts weeks or months or longer, it will transform society, and we don’t know how yet. We do know that, like any forced change, it will hurt and bring hardships. Seeing ourselves through to the other side will require mindfully rationing energy on maintaining both interpersonal connections and individual fortitude.
And in that vein, I want to encourage everyone to walk. (Or, if you can’t walk, to perform your best analogous locomotion in the open air.) Even with full-lockdown rules in effect — such as those now active in New York, the disease’s new epicenter, from which I now write to you — taking a walk remains legal. Without any federal leadership, the list of allowed activities shifts daily and unevenly, but I expect that it will have to allow walkers if only because everyone understands that people have dogs, and dogs gotta pee. Less frequently acknowledged, though: humans need to stretch their legs too, and cycle out their lungs with fresh air, and generally unrattle their cooped-up brains and bodies through the rhythm and flow of a brisk walk.
Last summer — a subjective lifetime ago, yes — I read and enjoyed this Guardian profile of the neuroscientist Shane O’Mara and his research into the brain-benefits of simply talking a walk. One paragraph that resonates strongly with me (written from article author Amy Fleming’s point of view):
I witnessed the brain-healing effects of walking when my partner was recovering from an acute brain injury. His mind was often unsettled, but during our evening strolls through east London, things started to make more sense and conversation flowed easily. O’Mara nods knowingly. “You’re walking rhythmically together,” he says, “and there are all sorts of rhythms happening in the brain as a result of engaging in that kind of activity, and they’re absent when you’re sitting. One of the great overlooked superpowers we have is that, when we get up and walk, our senses are sharpened. Rhythms that would previously be quiet suddenly come to life, and the way our brain interacts with our body changes.”
We can accept as grim blessings how this pandemic strikes the western world just as spring weather arrives, and that the germ does not transmit itself through open air. Take that walk, and breathe freely, and let your mind wander and flow, uncramping itself alongside your muscles. Stillness has its place, certainly, but the unusual surfeit of solitude we must all endure for the next howeverlong invites visits from the demons of anxiety as the mind, demanding motion, circles agitated in the skull.
When I feel that scratching from within masquerading as a dreadful pressure from without, I put my shoes on and grab my housekeys. It always works. The lullaby of locomotion lets those claws slip from my mind’s control panel, and I return home as master of myself once more.
For the time being, I can’t visit any friends on my walk, and I can’t go sit at a favorite coffee shop. Though the trains still run, I can’t in good conscience board a subway and walk around on a different part of Manhattan. But I can stroll the familiar parks and bridges near my home, along the river, and I can phone a friend while I do so, or check in with a distant family member. I can also get a coffee and a snack to go, and enjoy it on a park bench. Or, as I’ve pushed myself to do more often, lately, I can walk “without purpose” — which is to say with the mere sole purpose of enjoying the superpower benefits that O’Mara describes.
It is very important to me that we all walk, that we add this kind of for-its-own-sake walking — yes, practicing social distancing the whole time — to our daily routine. Bring your dogs with you, bring your children and partners; it benefits all of you. Purposefully purposeless walking trades a little time for a manifold payout of mental and physical gain — and that lightens the burden put upon health-care professionals during this critical time when we, the relatively healthy, need to give them as little extra work as possible.
Please join me in hitting the parks and pavement every day, if you can. It helps everyone.
The first time I saw Root played at a tabletop game conference, I felt immediately drawn to its pairing of Cole Wehrle’s crunchy wargame mechanics with Kyle Ferrin’s Nickelodeon-ready aesthetic of scribbly little forest animals dressed like deranged, dagger-wielding hobbits. In the two years since its debut I’d learned its reputation as a very good but deceptively heavy and hard-to-learn game, so I made playing Root my goal while attending Granite Game Summit last weekend. Along with Amy and our pal Jess, I did get a game in, and I wound up quite delighted with the experience, far moreso than I had expected. I must now gush about this game for a while.
Root’s theme, expressed through its mechanics, runs satisfyingly deeper than its surface layer of cute cartoon animals engaged in bloody conflict (a concept that has fascinated me ever since my first traumatic encounter with Watership Down). While I’ve certainly played plenty of wargames where players have heterogenous starting positions or a mutually different mix of units, I have never before seen one so asymmetrical that each participant plays an essentially different game from every other, with a set of rules and a goal unique to that player’s faction. Conflict arises not due to the more typical wargame goal of victory through obliterating the opposing players’ forces, but because those forces lie in the way of each player’s victory-path, seeking the same scarce resources for their own ends. This leads to interactions more interesting and unpredictable than the usual rush to clash at the battle-line.
The four factions of the base set represent four competing interests in a tiny world at war. The intermeshing of their gameplay styles balance surprisingly well, with each having a strong narrative explanation that makes the game’s overall flow quite sensible. I found that once I understood what each side wants, and how they intend to go about it — in terms of both that faction’s unique rules and their “in-world” narrative justification — Root’s whole little box of violently clashing gears clicks together perfectly.
In the morally ambiguous world of Root, the Cats probably offer the closest thing to a villain, insofar as nobody likes an invading army. Conquering despoilers, the Cats begin the game already garrisoned all over the map, having stormed the land just before the game begins. The Cats seek to industrialize their freshly grabbed tracts through a network of sawmills, which beget more buildings, and they score points every time they construct something.
The Cats are organized and flexible, with the least complex ruleset. They simply choose any three of the game’s common actions (e.g. move, recruit, or build) to perform per turn, and do their best to expand and protect their interconnected assets. The Cats’ rapaciousness presents a weakness, as well; to keep scoring, they have to keep growing, and they’ll quickly find they can’t do that without a fight.
The Birds used to rule the world of Root — until the Cats caught them off-guard and forced them to retreat and contract until they controlled only a single clearing. Having just elected a strong new leader, the Birds are ready to explode back out in a show of might and fury, retaking the land they see as rightfully theirs. They want to wrest control of clearings across the map and establish bases there, and so they score points every turn depending upon the number of bases currently active.
The Birds are powerful but rigid, bound to a “decree” of forced moves that their player is obliged to make even longer with each passing turn. Inevitably, the decree will demand an impossible action — for example, a “move an army” action with no legal army-movements available — and the Birds crash into squabbling turmoil, deposing their leader, wiping out their decree, and losing a bunch of points.
I played the Birds faction during my first game, and I adored this mechanical simulation of a cocky warband with no sense of project management, alternatingly roaring ahead and succumbing to expensive infighting. And it provides a tidy explanation for how the Cats managed to get the drop on them, too!
The Woodland Alliance comprises the miscellany of forest critters without a warrior class fed up with seeing Cat and Bird armies run roughshod over their towns and fields, over and over. Though political organization and bands of brave militia, they seek to define a new world of Root ruled by common folk. They score points by spreading sympathy to their cause across the map, and by ejecting occupying forces — no matter what faction they belong to — from a newly emboldened region.
Nobody chose to play the Alliance during our three-handed game, so I can’t really describe its play style! Reading the Root rulebook suggests it has significantly less military force than the Birds or Cats, but can draw up reserves of strength from the land itself by the unique ability to gain territory non-militarily, and then subsequently foment revolt to destroy enemy units.
I can more confidently describe the Alliance’s opposite in the Vagabond, the real odd-one-out among Root factions. Where the Alliance rejects the chaos of war, the Vagabond thrives in it. Reminiscent of the title character from Yojimbo, the Vagabond player controls a lone wanderer who seeks to play all sides off each other while questing for fortune and glory.
The Vagabond is weak but resourceful and slippery, with the most divergent ruleset. An optimal game for them can involve establishing profitable alliances with every other faction and then letting them pound on each other while scoring points at leisure through side-quests. Other players can stunt the Vagabond’s progress by attacking them and smashing up their stuff, but during our game their progress instead acted as a sort of natural time-limit that all the nation-states paid attention to, because how embarrassing if some dork with a bindle took the trophy instead of anyone’s grande armée.
Root’s two published expansion sets introduce four more factions — Lizard cultists! Corvid gangsters! — but they clearly fall outside the finely balanced story told by the four in the core. And, yes, the core game is hard enough to learn as it is. The generous person at Granite Game Summit who came to our aid (answering the call of the Teacher Needed flag we had planted at our table, early Saturday morning) did their best, and succeeded insofar as, hey, we played the game! But having played once, I can’t help but think of how I’d have taught the game differently, and I look forward to getting my chance to do so.
I hypothesize maximum effectiveness in presenting the Cats’ game first, and then summarizing each other faction’s game as variants of the Cats’ rules. Root includes a separately printed two-turn “walkthrough” for a four-player game, and I would want to dive right into that. Rather than opening with a half-hour lecture on the common rules of movement and area control and so on before any player even knows their faction’s goal, let the players immediately get some wood on the board and dice on the table and explain why the walkthrough has them doing what it does. I would expect that most any reasonable player would find themselves engaged and eager by the start of the third turn.
Root has moved me more than any board game has in recent memory. I love it. I very much look forward to playing this game more, either in cardboard or via the digital adaptation set to appear later this year.
I read and enjoyed brian d foy’s Mojolicious Web Clients, a short and direct guide to writing command-line utilities using the open-source, Perl-based web toolkit called Mojo. (The title’s “Mojolicious” formally refers to a full-featured web framework built on Mojo, but I am told that the longer name now embraces both the toolkit and the framework, per the project’s official website.)
I’ve worked with Mojo for a couple of years now; my Webmention library relies upon its wonderful DOM parser, for example. But I didn’t really understand the project as a whole; while it does offer higher-level guides to complement its voluminous nuts-and-bolts reference material, it has always lacked the slower, fleshier explanatory power of a real book. As such, I hungrily purchased foy’s new e-book the moment I learned about it. Even though it covers just one aspect of Mojolicious — using its toolkit to request and extract interesting data from the web, whether via JSON-based APIs or human-intended HTML pages — it still provides very welcome long-form documentation coverage to a project that has long deserved it. I hope similar books follow.
Prior to reading this book, I felt quite foggy on the difference between the Mojo toolkit and the Mojolicious framework, vaguely understanding the latter as a followup to the venerable Catalyst framework, and knowing that CPAN hosted a variety of modules under the “Mojo” namespace but not seeing any particular pattern to them. Happily, foy’s book opens with a history of Perl-based web tools right up through the present, clearly explaining how Mojo has picked up the torch from the long-lived LWP library, and going on to demonstrate its commitment to modernization through an emphasis on fluid coding style and strategic wheel-reinvention.
Mojo, apparently, is one of those rare software projects that starts over from scratch and gets it right. According to its manual page, Mojolicious has only four library dependencies, and all of them already ship with Perl. A veteran Perl hacker recognizes this as absurd, especially for such a wide-ranging project. It often seems that a typical Perl-based project (any of mine included, certainly) wants to download half of CPAN before it will deign to try installing itself, and so Mojo represents a stunning lesson in dependency-austerity. And as such, of course, it brings both a gift and a challenge: use Mojo in your project, and see how little else you’ll need to get to your goal. You just might write better software for it, with far fewer dependencies outside of your control.
To a Perl fan like me, learning Mojo today feels like both a relief and a necessity. At a time when the lights threaten to shut off over Perl’s role as anything other than small-scale Unix-glue, Mojolicious represents a rare project keeping the party going with inventive and ongoing vitality. I was intrigued when colleagues first suggested the Mojo modules to me two years ago, delighted to find Mojolicious quietly starring in Emily Shea’s 2019 conference presentation about voice-driven programming, and now cheered by the arrival of even one fresh book on the topic. As Brian Wisti recently said, “Mojolicious is why I still have Perl installed in 2020”. I like Perl enough and respect its community, however small these days, that I feel obliged to adapt my own practices to better feed from — and, I hope, feed back into — this valuable source of forward-looking energy.
This article was also posted to the “books” section of Indieweb.xyz.
The Perl Foundation opens the floor to community grant proposals every two to three months. The latest round includes a pitch from me, wherein I propose to revise a couple of Perl’s core documentation pages for completeness and clarity. It reads, in part:
The manual page for one of Perl’s most central functions —
open— has problems. While nobody doubts the page’s technical accuracy, head Perl maintainer Sawyer X nonetheless holds it up as an example of documentation in sore need of reorganization and revision. Towards the end of his TPC 2019 talk “Perl 5: The Past, The Present, and One Possible Future”, Sawyer described the
openpage as an example of Perl core documentation that fails to put its most useful information in front — making it less likely to be read at all, especially by a newcomer to Perl. “It’s kind of like a Google result,” he said. “You go through the first page, and that’s it, you know?”
In a separate but related issue, the
openpage links early on to
perlopentutas a “gentler introduction” to its concepts. However, that page has problems of its own — most obviously, the fact that it ends with three sections containing only the text “To be announced” (and in one case adding “Or deleted”). Perl’s public distributions have included this page, in its current form, since 2013. This marks it as another case of a core manual page that could greatly and obviously benefit from a fresh look.
I — a writer and long-time Perl programmer — propose to address these issues by taking a focused, critical look at these two manual pages, and then revising them for clarity, completeness, and friendliness to Perl newcomers.
As with all grant proposals it publishes, TPF will keep this one open for a few days for public comment prior to internal deliberation and decision about whether or not to approve it. Please do feel free to review and respond at TPF’s website by March 1, 2020.
It surprises me that The Perl Foundation does not receive more grant proposals, especially given its pattern of holding a half-dozen or so CFPs every year. Sometimes a bimonthly CFP will pass in silence, with no proposals submitted at all; more often it will hold just one proposal, like the current one. I know that Perl’s tarnished star has long since fallen from its apex, but it remains a technology with a sizable and talented community able to keep it maintained and improved, and a nonprofit organization willing to fund such projects. I’d love to see it have a broader choice of proposals to spend its money on!
I do encourage folks who use Perl to consider proposals they could add to one of TPF’s frequent funding rounds. (The site doesn’t make it super-clear, but you can pitch a project even outside of a CFP, and TPF will queue it up for the next one. This is, in fact, how I submitted this proposal.) TPF even provides a pageful of grantworthy project ideas for those itching to pitch. Note that projects don’t necessarily involve any coding, per se; my own proposed project would affect only documentation, for example.
This isn’t my first time at this particular rodeo, by the way. In mid 2015, I submitted a proposal to fund Plerd. While TPF declined to fund it, it did so with admirable transparency, and seeing this sample of a technology-supporting nonprofit as work fascinated and inspired me. This, among other factors, led directly to my proposing the creation of IFTF to a group of colleagues, that very same summer.
A housekeeping note: I have quietly ended the experiment to entice charitable giving among Fogknife’s readership with the promise of free stickers. Six months after launching the program, I have received exactly zero responses.
And, honestly, this is just fine. This blog’s regular readership is quite modest; according to my own measurements, between 150 and 200 individuals regularly read Fogknife (either through manual visits or via RSS), amongst a larger cloud of one-time or occasional visitors. These numbers have held stable in the two years since I started tracking them. That’s enough to help keep me writing, but clearly not enough to launch any kind of reader-participation activities more complex than the occasional conversation.
In the meantime, I still have this sheet of little vinyl Fogknife stickers sitting in my desk drawer. So: if you’d like one or two, please email me your mailing address, and I’ll slide a couple in your direction. (As my memory often fails me, please also note in your email that you’d like a Fogknife sticker.) In the perhaps unlikely event that I run out of stickers — which will occur only if a dozen readers take me up on this offer — I’ll update this post appropriately.
Thanks, as always, for reading.
Today I learned a practical lesson on how, when investigating software bugs, simplifying the problem space as much as possible matters — and so does thoroughly exploring every angle offered by that simplified space, no matter how unlikely it seems.
A client wished to test a new version of a certain system that another system of theirs, one under my control, regularly contacts through a simple, HTTP-based API. We found a strange problem: it rejected all attempts at communication from the system I oversee — let’s call it “MySystem” — always sending back HTTP 403 responses, signifying an access-permission failure of some kind. However, it was happy to talk to every other computer on the internet. It would even greet manual pokes sent through a web browser. From my point of view, the test system was pleased to receive messages from everyone in the world except for MySystem, the one system that my client required it to listen to.
Step one of investigating any mystery like this often means writing a program that replicates the problem as simply as possible. And so, I knit up a stand-alone script that invoked the same code libraries and techniques that MySystem uses to make web requests. Even though they came from my own computer, the remote system helpfully rejected these requests as well. Progress, of a sort!
As coincidence would have it, I had recently begun reading brian d foy’s new book Mojolicious Web Clients, which opens with several simple examples of tiny command-line web-requesters that print the full text of their work to the terminal as they go. Out of curiosity, I aimed one of these little ready-to-go programs at the target, from the very same computer — and the remote server welcomed the request, sending back the correct response.
At this point I had two simple test programs. One used the thoroughly modern web toolkit for the Perl programming language called Mojolicious (“Mojo” for short); the other used the decades-old LWP, which the similarly venerable MySystem employs. The former could make requests of the target with no problem, and the latter had all its requests summarily rejected instead. The requests came from the same machine, and asked for the same URL, using the same HTTP method. What was going on?
I had no access to the server’s logs, so I didn’t know what complaint it might have had with the LWP-based requests. Nothing to do, then, but dig into this problem myself, seeing what difference existed between the requests the two toolkits sent to the remote server. Time for another simple script that tried the trick with both libraries, printing out the full text of the request made, and the HTTP code of the response. The result looked like this (if you’ll pardon my obvious obfuscation of the client’s URL):
Trying with Mojo: GET /some/path HTTP/1.1 User-Agent: Mojolicious (Perl) Host: api.jmacs-client.com Content-Length: 0 Accept-Encoding: gzip Result with Mojo: 200 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Trying with LWP: GET https://api.jmacs-client.com/some/path User-Agent: libwww-perl/6.43 Result with LWP: 403
(Note that an HTTP 200 code means a successful request.)
All right, some obvious differences between the two requests, then. Mojo seems to attach several more headers to outbound HTTP requests, by default, than LWP does; my program specified no headers in either case. I saw that Mojo also split its reported target URL into a
Host header and a path, compared to LWP’s simpler-looking GET of the full URL, and didn’t know offhand what any of that meant. And, of course, the
User-Agent headers are different, with the two toolkits taking the opportunity to identify themselves by their full names.
Mojo’s additional headers were easy enough to try with LWP, so I started my experimentation there, adding the three extra headers —
Accept-Encoding — to the LWP request and running the program again. Same result, other than seeing those new headers printed out. This made the different ways that Mojo and LWP phrased the
GET line more suspicious, and I frowned; that would be harder to experiment with, requiring research into the reasons for the dissimiliar displays.
But before moving on to that deeper layer, and just to satisfy myself that I really had made the headers of the two requests as similar as I could, I tried the program again with the LWP request claiming a
Mojolicious (Perl). In my experience*, the value of the
User-Agent header never has any mechanical effect on server behavior; it exists merely as a way for particular clients to leave a “calling card” in server logs, if they wish — just a bit of information that might prove useful, from time to time, when reviewing logs by hand. So I expected no change; I just wanted to tidy up and make both sets of headers truly identical, for aesthetic reasons as much as any other, before continuing the investigation.
And, as you have no doubt already predicted, this change made both requests succeed.
Quite surprised and confused, I experimented with different values of
User-Agent. Within a few minutes, I’d deduced that the remote server rejected all requests whose
User-Agent value contained, anywhere within it, the substring
libwww-perl. Removing or modifying that substring let the request succeed. This accounted for the success of the Mojo request — and the failure of the MySystem system’s requests, which used a lightly edited version of LWP’s default value for this header.
It seemed, at this point, that the customer’s web server intentionally rejected with prejudice any request made by a program using the LWP toolkit — at least, those that didn’t bother to change outgoing
User-Agent values to something other than the default. Since at this point I had enough information to formulate a short question, I presented the problem to the sages at the #perl channel on Freenode. And as they often do, the denizens answered accurately within moments: some corners of the cybersecurity world have recommended blocking all requests from agents identifying as
libwww-perl, and some servers duly accept this advice. This stance sees this substring as a flag flown by a filthy bot, one that didn’t even bother to set a non-default name for itself. Not exactly flying the Jolly Roger, but not troubling to provide a nation (or project URL) of origin, either — and therefore deserving of suspicion to the point of summary dismissal.
A most unexpected outcome! In my whole career as a web programmer, I’d never imagined the
User-Agent header employed by automated scripts for any purposes other than curiosity (when reviewing my own server logs) or amusement (when writing a program that would go mark up some other server’s log). As a younger hacker I took pleasure in always setting the agent string to something unique to my project, imagining the calling cards my software left in server logs around the world; more recently, I have seldom bothered. What a surprise, then, to at last encounter a good reason to change the value to something other than the default.
Or, you know, to just carry on with my plans to retire LWP from all my Perl-based projects going forward and just use Mojo instead, since that apparently works just as well…
See also: A little jaunt through the bitwise.
* As several readers have pointed out to me, this speaks to my particular experience as one who has never needed to care much about website appearances during the start of the smartphone era, or the waning years of MSIE 6 — both times when serving different content depending upon user agent were de rigueur.
I feel compelled to write a short post just to acknowledge my support last year for impeaching President Trump. I have just now reread that post, as well as the Yoni Applebaum feature in the Atlantic that persuaded me at the time.
It feels far too early to start wailing in despair that the whole thing was a mistake and we were all wrong. Applebaum’s article used the impeachment and acquittal of Andrew Johnson as its augur, and by this measure he predicted a period of celebration and a flare of support for Trump after his own acquittal — as obvious an outcome in January of last year as it was last month.
And lo: Trump has, as I write this, begun to celebrate in his favorite way, going beyond obvious gloating (though there’s plenty of that too) and immediately delighting in the retaliation of all who wronged him through either political opposition or mere disloyalty. Not just individuals, mind you, but also their families, their constituents, and the very lands they call home.
Applebaum’s stated hopes that the act of impeachment would corrode the president’s support in the Senate, of course, proved entirely unfounded. Instead, senate Republicans just shrug, either too cowardly to protest or openly supportive of the executive’s rampant and overt abuses of power. Certainly, they do nothing at all to temper my own earlier assessment that the modern Republican party stands against human progress, or even its long-term survival.
So we all look ahead to November, once again. I do not, at this time, consider any candidate, the president included, a lock-in; I expect that Trump’s steady unpopularity balances both his incumbent advantage and his eagerness to fight dirty, including using the powers of his office to harass his political opponents. It seems currently that if the president’s impeachment carries any effect on the looming election, then it will take the form of citizens’ reaction to his unsubtly vindictive rampages upon his preordained acquittal. Now that he has little left to fear, we witness this president at his most unmasked.
We should forgive those who voted for Trump in 2016. I know my parents would have done it, were they still alive. Hillary Clinton was the second-least popular presidential candidate since such things have been tracked — losing that mantle only to her opponent — and countless people beyond die-hard Republican supporters had no love for her. I have sympathy for those who thought, not entirely unreasonably, that a jokey novelty president would shake things up and give us a few years of amusing pro-wrestling kayfabe from the White House while conducting business more or less as usual behind the scenes.
I feel plenty of reason to hope that enough of these people recognize their error and have no taste for repeating it, and will quietly make amends in the privacy of the voting booth this fall. Even if that happens, it will be impossible to say how much impact the impeachment-and-acquittal dance had. And I have to acknowledge how frustrating and sad this rare scrap of foreknowledge feels, at a time when the world needs sure-footed leadership more than ever.
In December I started using Fraidycat, a new, free and open-source feedreader by Kicks Condor. While I last summer voiced anticipation for its impending release, I did not expect how immediately and wholeheartedly I would appreciate and enjoy it once I began to use it. Fraidycat, just-born warts and all, quickly became my favorite feedreader program, entirely supplanting my use of ReadKit — and even giving my favorite Twitter client a run for its money, in some use-cases.
Fraidycat’s novel philosophies about fetching and displaying new content from disparate web-based sources respect one’s attention more, I do believe, than the long-prevailing single-stream news feed model. I have felt no qualms about leaving it running all day long for the past several weeks, where it serves with equal utility as an at-a-glance summary of what’s new among all my favorite blogs and such, as well as a conduit for diving deeper into any single source’s recent articles.
The progam’s core differences from a typical feedreader:
It does not fetch or display any item’s content, instead retrieving only minimal metadata from each source. It grabs items’ titles, URLs, and last-updated timestamps, plus a little extra metadata about the source itself. To read an item, click its title in Fraidycat’s window, and your usual web browser will fetch and display it in that source’s home environment.
For display purposes, Fraidycat groups items by source, rather than the traditional strategy of pouring all received items into a single feed ordered by time-of-arrival. Furthermore, it flattens sources such that each one occupies only two rows of Fraidycat’s window: one for the source’s name and icon, the other a horizontal list of its most recent items’ titles, truncated to fit. (You can tap a button to temporarily see a single source’s items as a traditional vertical list.)
When Fraidycat receives a new item, it “bumps” its source’s display-row up to the top of the source-list. Due to its grouping and display rules, though, that source’s articles don’t take up any more total vertical space in the window than they did before the new items’ arrival.
Finally, Fraidycat only shows up to ten items from any source (I think?), and furthermore doesn’t track whether you’ve clicked on anything or not. Things just flow by, faster for chattier sources. When items become stale, they quietly vanish. Nothing anywhere tallies up how many unread items you have piled up, because there is no pile.
Combined, these rules remove the anxiety that a traditional news feed presents of always running behind. Instead of a vertical tower of articles growing faster than you can possibly read them, you have a tidy list of favored sources that never changes shape — it just re-orders itself from time to time, swapping out the “front-page headline” for the affected source-row as needed. You can dip into any with a click, but if you don’t, the quiet passage of unread older items into the past no longer feels like a personal failure; it brings no more heartbreak than seeing yesterday’s newspaper go into the bin . It is so refreshing.
Fraidycat also prides itself on its ability to let you tune how often it checks in with a given source. If a website proves so chatty with new and updated items that it stays affixed to the top of Fraidycat’s window, you can ask the program to check in with it less often — only daily, say, or weekly — in order to give other sources a chance to bob up to the fore now and again. You can also segregate items into tagged categories, so that e.g. Twitter-based sources get to race around in their own view, apart from slower blogs or online magazines. (Fraidycat does indeed support not just RSS-based sources but Twitter accounts, Instagram feeds, and a surprising array of other stuff I haven’t tried.)
This leads to my one significant critique with Fraidycat’s current design: I don’t think that sources set to have less frequent check-ins should necessarily get relegated to separate views. Currently, each tag-based Fraidycat tab has sub-views for “Daily”, “Weekly”, and so on, as well as the default “Real-time” view. When you set a source to anything other than “Real-time”, Fraidycat banishes its display to that sub-view.
I think this plays a little too much into the program’s shyness about mixing too many sources into one list. As it stands, I tend to forget that any of the “rate-limited” views even exist, within a given tag-view. I don’t mind clicking around in between the category-tags according to my mood, but further clicking around between checking-rates doesn’t feel the same. These rates don’t denote any difference in content or quality from its neighboring sources, after all; I just want to see them presented a little less prominently.
Update: I note with amusement that, according to the project’s rejected-features page, this does indeed describe how the first versions of Fraidycat used to work — but early testers hated it, it seems! Regardless, Fogknife stands by its assessment.
Even though Fraidycat’s interface remains a bit rough around the edges, I find it quite a pleasure to explore. After I imported my old RSS reader’s blog-list into it, I discovered some fascinating side effects from the way it sees websites not as cannons that fire out content continuously until they at last fall silent, but repositories that last for as long as their URLs resolve. I thus found several bittersweet signing-off announcements from blogs that had long since wrapped up their work, and which in every case had gotten buried in the flood of my combined RSS feed. Fraidycat will give one source’s year-old item equal billing to another’s hour-old one, if that’s its most recent update — while also making clear, at a glace, the relative age of each item. I like that a lot.
All told, I find Fraidycat a most interesting new way to keep up with the web without either the guilty futility associated with traditional feedreaders, or the anxious addiction that social-media monoliths encourage. I quite look forward to following this program’s ongoing development.
(I use Fraidycat’s stand-alone macOS edition, even though it seems primarily intended for use as a Firefox or Chrome plugin. Linux and Windows stand-alone editions are also available.)
This article was also posted to the “web” section of Indieweb.xyz.
The following ran in last Saturday’s edition of the Bangor Daily News.
Peter Stuart McIntosh, 61, died on January 22, 2020 in Bangor.
He was born in Framingham, Massachusetts on June 23, 1958 to Dorothy and Richard McIntosh. He grew up alongside his older brother Richard Jr., and helped raise younger brother Jason years later.
After graduating from American International College, Pete held roles ranging from hotel cook to night watchman before finding his true calling, assisting adults with severe autism. He worked at special-needs homes throughout Maine, where his deep and devoted caring touched many lives.
Pete was devoted also to his wife Janice, married in 2002, his companion in every aspect of life. She predeceased him after a long illness in 2014, with Pete willingly becoming her full-time caretaker in the end.
Pete continued life after this loss by joining the Bangor chapter of Clubhouse International, a nonprofit advocate for adults with mental illness, and he made many dear friends in this community.
For his whole life Pete loved paperback novels, superhero comics, and Boston sports teams. He instilled in Jason a love of reading, whether Spider-Man or Steven King.
Peter is survived by his brothers Richard and Jason and his cat Moxie.
In lieu of flowers, those who wish to honor Pete’s memory may make a donation to the American Stroke Association or to Clubhouse International.
This represents the third family obituary I have written in seven years. I suppose it benefits from this past experience, but it differs from the previous two in that I didn’t enter the month expecting to write it. I had to scramble to pull a first draft together before the paper’s weekend deadline while juggling every other sudden responsibility that fell to me upon my brother’s wholly unexpected death. My first try proved far too lengthy, and with friends’ help I ground it down below the $300 mark (at the paper’s $1.25-a-word rate).
As such, much remains unstated here, including the cause of Pete’s death. A car struck him as he crossed the street while walking home after dark. Within hours surgeons had set to work repairing his many broken bones. They could see brain injuries as well, but imperiled brains often surprise doctors with their resilience, so we waited for days to see if he’d regain consciousness. He did not, and the long sleep plus the nature of the injury meant that he almost certainly never would. His family agreed to let his body slip away, joining the personality that the car probably obliterated on impact.
This oblique stroke cut short an already tragic life. The obituary’s first draft contained no details of the accident or its aftermath, but it did put more words towards the complete and permanent devastation he had experienced six years before with the loss of his wife Janice six years ago. Her death tore him apart, and he never really came back together.
Pete triggered the previous time I had to race to Bangor in an emergency mode, which I detailed in a cotemporary post on my old LiveJournal. In short, after I rescued him from despair-driven homelessness, he proceeded to live an utterly enervated existence, defined primarily by mourning, for years to come. I can reveal now that “Hank” in my angry and self-loathing Gameshelf post about the Walking Dead video games was Pete. These articles from a half-decade ago accurately and frankly show the poisonous frustration I felt for my brother, my will to sympathize with his terrible loss balanced with my inability to understand why he couldn’t move on from it.
In time he came partway out of this state, largely thanks to Clubhouse International, whose Bangor chapter helped him out a great deal, and even set him up with a dishwashing job for a little while. But Janice’s ghost never, ever left his sight. No conversation with Pete could happen without mention of her, right up through the last time I spoke with him this month. If he laughed at a joke, he’d often catch himself, horrified, and explain that his laughter doesn’t mean that he’s forgotten Janice. When he got confused while paying for his groceries, he’d mumble apologies to the cashier about how he hasn’t thought straight since his wife died. Death made her larger, infinitely large, Pete’s whole universe, forever.
On Tuesday, having done everything I could in Bangor until the spring thaw — when I plan to lay Pete’s ashes to rest by his wife’s, in her northern Maine home town — I returned home by train. The landscape smearing past the window invited my mind to drift, for the first time in two weeks, to contemplate my own loss. I wondered if Pete had time to turn to face Janice in his final conscious moment, to send out a radar-pulse of love to her memory as he abruptly transitioned into memory himself. Without thinking too much I summoned up “The Commander Thinks Aloud” by The Long Winters on my phone, a deeply sad and beautiful song about the last thoughts of someone perishing in a sudden, violent accident. The lyrics reflect not pain or fear but longing, an ultimate unrequited longing. Can you feel it, we’re almost home sang its voice, as my tears ran freely, and Connecticut rumbled on past.
I carry the terrible ambiguity that in my final conversation with Pete, on the telephone a week before the hospital called me, he sounded quite upbeat. As the years went on, he never stopped living every moment for Janice, but he gradually got better at the living part. He made friends, he started attending church again, and he got back into reading. He also struggled — letting bills pile up, frequently losing his housekeys, and developing balance issues that forced him to stop driving, and then stop working. He sometimes called me in confusion or desperation, but that last time he felt calm and hopeful.
And underneath surged an impossible longing for his lost partner, a roaring river of it, wider and deeper than anything I’ve ever felt, maybe more than anything I am capable of feeling. I needed a song to unlock this revelation, and to glimpse the tragedy of so suddenly losing someone capable of feeling so much love, so much love that it may well have drowned him.
Previous post: Our Mathematical Universe and the eternal now