“You saved my life!” (or: how my kids briefly thought I was a superhero)

This weekend, my friend Liz arranged for some other Abnibbers and I to gather, with our families, for a camping/glamping weekend East of Oxford.

Here’s a story of something that transpired there, presented in three parts:

  1. The fire
  2. The battery pack
  3. “You saved my life!”
Adults and children mill around a firepit, some of them holding marshmallows on skewers.
The campsite provided our large group with an entire field to ourselves, including spaces for socialising, a fire pit (at which the kids enjoyed toasting marshmallows), and a wood-fired hot tub.

The entire weekend would have surely been a memorable experience already, but one particular event will probably stick in the minds of everybody in attendance: the fire.

The fire

The UK’s in its unprecedented third heatwave of the year: the grass is all dying and everything is tinder dry. And so it was that, on Friday night as the kids and I slept in our glamping “dome”, I was woken by the distant beep-beep-beep of a domestic smoke alarm. A few seconds later, I heard a second such alarm with a different tone, and it became clear that this wasn’t just somebody’s toast on fire.

Not recorded: the sound of the occupant of this static caravan/cabin – having jumped through the window to safety as the front door was blocked by flames – on the phone to the fire brigade.

I went back into the dome to check on the children, which is when Penny knocked on my door to ensure I was aware of what was going on. The kids were sound asleep, so I ran out to the car park to move the car (which was parked in such a position that embers were raining down on it!) and to check on the situation.

A static caravan is engulfed in flames behind a dome tent, at night.
The fire intensity of the fire grew particularly intense as the sound of fire engine sirens began to be heard from the valley below. Photo copyright Rory Prior.

I returned to the dome and got the children dressed. We evacuated to a safer distance and watched as the firefighters arrived and began to tackle the blaze. Short of water, they had one pump dousing the flaming building while two others relayed water from the nearest fire hydrant, way down the hill.

Firefighters pull hoses from a fire engine towards the inferno of a flaming cabin.
There was a brief faux pas when one of the Abnib kids exclaimed “this is so cool“… without realising that he was standing right next to the people whose home was being destroyed in front of us.

Eventually the situation came under control and we were all able to return to bed.

The battery pack

I spoke to Mike, whose holiday home was the building that was destroyed. He’d managed to escape with some shorts and his mobile phone, but little else: in particular, his car keys remained inside and were probably destroyed, which rendered him unable to drive back to his regular home.

A group of adults and older children stand out in a field at night, while in the distance thick smoke is illuminated by flashing blue lights.
The firefighters worked quickly, but it still took over three hours before they were able to finish spreading out and drenching everything that had caught light. We watched from a distance, and sheltered all the children (including those of a non-Abnib family on-site) in one of our tents.

Mike had been turning his phone on only in bursts in order to conserve battery for all of the essential calls he’d have to make (e.g. his bank, to extract some money without his cards, and a locksmith, to get him back into his car). His phone charger – an awkward USB-B-Micro one – hadn’t survived the fire.

But conveniently… I happened to have such a cable in my bag. Plus a fully-charged battery pack. So I lent both to Mike, in the hope that it’d make it easier for him to do all of the necessary administration1.

A handful of metal frame struts stick out from an ash pile that was clearly once a static caravan.
It’s got to be a pretty-devastating thing to happen to your holiday home and everything in it. Mike was surprisingly chill about it when I spoke to him, taking soft-of an attitude of “well, there’s no point fretting about it after the fact!”

“You saved my life!”

Anyway: on Saturday night, shortly after the kids and I had turned-in, there was a knock on the door. It was Mike, come to return the battery pack I’d lent him.

The kids didn’t know who he was, so I explained: “This is Mike; he’s the fella who lived in the home that burned down last night.”

Mike handed over the battery pack and charging cable and, grateful for them, used a metaphor that. “Thanks,” he said, passing the hardware to me, “You saved my life!”

Several beds laid-out in a darkened glamping pod.
I hadn’t told Mike which glamping pod was ours, and just figured I’d see him around. Or else if I didn’t get my battery pack back, that’d be fine: it’ll have been more-useful to him than to me in the days to come! But there we were, in our pyjamas, when he appeared at our door.

He turned and left, and both kids sprung out of bed and exclaimed “You saved the life of the guy whose house burned down‽”

I’m sure they had in their minds the idea that, during the period between the fire starting and me waking and evacuating them, I’d singlehandedly dragged this dude out of a burning building. Y’know, instead of just lending him a phone charger after-the-fact.

I only let them hold the misapprehension for a few minutes, but for a moment it lightened the mood.

Footnotes

1 I was already using my phone to call our insurance company before our flood, earlier this year, had finished. I can only imagine how inconvenient it is to suffer a disaster and lose your communications lifeline at the same time!

× × × ×

Your ‘App’ Could Have Been a Webpage (so I fixed it for you…)

Why is this an “app”?

This summer, the kids’ performing arts school are singing and dancing in a show at Disneyland. We’re all very excited, but my excitement, at least, was muted a little when I was told to install the “Travelbound” app in order to get access to the itinerary, travel arrangements, and accommodation details.

Fuck that noise. This should have been a webpage. Why do you want me to install a(nother) shitty app just to tell me something that could have been a (smaller, faster, more universally-accessible) document?

Screenshot of an Android app showing a summary itinerary: times for a 'ferry crossing', 'check in at your hotel', 'coach driver accommodation', 'disney's hotel cheyenne', and 'welcome gala', each with an attractive but generic photo.
I’m not remotely exaggerating. This app is literally text, images, and links to PDF files, delivered via the Web.

There only seem to be two things that this “app” does, that a webpage might not have, and they’re both anti-features:

  1. It reports tracking data associated with your Google Account back to the developers.
  2. It shows you advertisements (which they call “inspirations”) for other trips organised by the same agency.

Fuck. Everything. About. That.

A webpage would have been so much better. Unlike this app, a webpage can be…1

  • Copy-pastable
  • Printable
  • Saveable
  • Bookmarkable
  • Searchable
  • Usable on virtually any device
  • (Potentially) more-accessible

I’m annoyed enough… that I’m going to “fix” this app. Hold my beer.

Intercepting app traffic

It’s been a while since the last time I reverse-engineered an Android app from its network traffic, so I had to brush-up on the best way. Here’s what I ended up doing.

  1. Created a new virtual device in Android Studio’s Virtual Device Manager.
  2. Tested adb shell was working and used rootAVD to root it: ./rootAVD.sh system-images/android-33/google_apis_playstore/x86_64/ramdisk.img.2
  3. Performed a cold boot, ran Magisk, and tweaked its settings to automatically grant su access to any app that asked.3
Screenshot showing the HTTP Toolkit application running on both MacOS and an emulated Android mobile, with User Trust and System Trust enabled.
All your traffic are belong to me. At this point, it’s just like running Wireshark or TCPdump.
  1. Ran HTTP Toolkit and told it to intercept AVD traffic. It installed a (fake) VPN provider, routing the phone’s traffic through the proxy.4
  2. Installed the Travelbound app from the Play Store.
  3. Configured HTTP Toolkit to proxy only the Travelbound app (more signal, less noise).

With only a couple of minutes experimentation I discovered that the app works by concatenating the username and password5 and using it in a URL of the form:

https://travelbound.api.vamoos.com/api/itineraries/{username}-{password}

This returns a pile of JSON which, with a little interpretation, can be seen to represent all of the content the app “shows”. E.g., there’s:

  • an array containing each leg of the itinerary,
  • an array containing all of the “inspirations” advertisements to show you,
  • a cross-referenced array containing all of the files (images etc.) that are referenced by the other sections, etc.
Firefox showing a JSON document, focussing on a section about 'Your Ferry Crossing' with some accompanying HTML.
They’re clearly producing HTML code anyway… so again, I ask: why isn’t this a webpage?

A little experimentation showed me that the S3 image URLs were being delivered with moderately-short expiration times, so the JSON needs re-fetching periodically even if the content hasn’t been changed.6

Turning it into something better

Now I had everything I needed to make something… better. I wrote a Ruby script that runs on a Cron schedule to pull the latest JSON and use it to build a HTML page.

I chose to have it completely skip over the “inspirations” (“overlayRows” in the data schema) and just list:

  1. the items from the itinerary and
  2. all of the files not referenced by the inspirations nor itinerary, (a lazy way to collate the PDF download links).

Then I hosted the page, protected by a password: the same one my tour group were given in the first place. I included the raw JSON it used in <details> elements so it can be checked if e.g. there are bits of the schema I didn’t see but that might appear later.

Screenshot of a simply-styled web page showing the same information about the ferry, along with a photo from its deck.
My web page isn’t as “pretty” as the app from which it “borrows” its information. But it’s a fraction of the size and gets all of the Web’s standard features for free.

Some people like an “app”, and that’s… fine, I guess. But some apps could have been a webpage. And especially where, like this one, the content they deliver is already written in HTML and delivered over HTTP… they should be a webpage, right?

I can’t understand how we got to this place with “app culture”! Software companies are happy to make their lives harder (and more expensive: deploying to the big app stores isn’t free!), in order to deliver HTML content to fewer people and with fewer features7 than if they just published directly to the Web in the first place!

There are (some) tasks for which an “app” is absolutely the right choice of medium. Travelbound is not one of them.

But at least I (and the rest of our group, whom I’ve shared it with) now get the choice about how we access this content. Either a 43MB app (ballooning to 124MB when it’s finished downloading extra content) with tracking and advertisements… or a 0.05MB web page (with an optional extra 35MB of images) that provides more features and works on more devices. I know which one I’ll be using!

Footnotes

1 And these are just the features that everybody can get behind. The webpage I ultimately ended up making to replace the app also has some user-friendly/developer-hostile features, like the fact that it removes the tracking code and doesn’t show advertisements.

2 You need to root the device in order to force applications that use Certificate Pinning to trust your man-in-the-middle proxy server. Without this, some applications – including the one I wanted to reverse-engineer – will recognise your self-signed TLS certificate as invalid and refuse to communicate.

3 Without changing this setting in Magisk, I found that HTTP Toolkit would request su access but not wait for the response, and go on to run in unprivileged mode before I had a chance to grant it!

4 Owing to Android security considerations I needed to manually install the root CA certificate it installed for me, but the instructions “just worked”.

5 The username and password is shared by an entire tour group. I’m guessing they don’t have a plan for if some credentials get leaked? Or possibly they consider all of the data they hold to be low-sensitivity enough that it doesn’t matter if it does… in which case I return to my original point: why the hell wasn’t it just a webpage in the first place?

6 Or else the images need caching locally, which seems to be what the app does, in the bloatiest possible way.

7 And, often, with worse accessibility. I’ve not audited the accessibility of this app, but there are things about it that suggest that it’d be harder to use using accessibility technologies than my plain, simple Web version.

× × × ×

Dan Q found GCBB3J9 Appleton Wharf

This checkin to GCBB3J9 Appleton Wharf reflects a geocaching.com log entry. See more of Dan's cache logs.

What a beautiful spot for a geocache, which the geopup and I quickly found in the second host we checked. Then, we enjoyed a delightful few minutes of peace, sitting on the riverbank, before continuing our morning’s adventure.

A white man with a blue ponytail and a goatee beard sits with a French bulldog alongside a wide, calm river.

TFTC, FP awarded for this amazing hidden gem.

×

Dan Q found GCBN167 Ivy Believe It’s Up There!

This checkin to GCBN167 Ivy Believe It's Up There! reflects a geocaching.com log entry. See more of Dan's cache logs.

This afternoon I’m acting as backup driver for my partner Ruth, who’s walking the length of the Thames Path by (very gradual) instalments. Having parked at Culham Lock I began to walk back towards Abingdon to meet the walking team coming the other way, when I noticed that a new cache had been published nearby and diverted to find it.

Dan hangs from a tree; a cache container is barely visible in the background.

A delightful tree climb later and I had this great cache container in hand. TFTC, FP awarded!

A geocache container, open, in a tree.

× ×

Dan Q found GCAABPG North Leigh Loop #7

This checkin to GCAABPG North Leigh Loop #7 reflects a geocaching.com log entry. See more of Dan's cache logs.

Completing our loop (minus a couple of DNFs, but plus a couple of nearby caches), this damp geopup and I were really happy to finish with this good-sized cache!

Dan crouches by his French Bulldog on a rural footpath.

TFTC, and for the series, if which this was our favourite and so earns the FP.

Now we’d better go get cleaned and dry!

×

Dan Q found GC1QYPN Back to Evergreen

This checkin to GC1QYPN Back to Evergreen reflects a geocaching.com log entry. See more of Dan's cache logs.

The geopup and I are out doing the North Leigh Loop from New Yatt, where we’re temporarily living while our house is dried and damage assessed by the insurance company following a catastrophic flood a few weeks ago.

Between Loop #3 and #4 we took a small diversion to find this cache, and I’m glad that we did! So nice to see a properly-sized (and tenured) cache still rocking it!

Lid was not properly attached by a recent finder, sadly, and the container spilled its contents as I picked it up. But once we’d reassembled it all we were able to sign the log and continue our loop.

TFTC to both the hiders and adopters. FP awarded for being the first decent-sized cache I’ve seen today.

The calm after the storm

This morning, from my Premier Inn window, the skies are clear. I could almost forget that, just 4 miles away, my house is full of water.

Today may well be a day of waders and damage assessment, conversations with insurance companies and of working out where we’ll be living for the near future.

Sun rising through hazy but clear skies.

But strangely, what’s thrown me first this morning was that I couldn’t make this post submit.

Turns out my crosspost-to-mastodon checkbox was checked. Because my Mastodon server… runs on my homelab. Which is currently unplugged and in one of the highest rooms of a house with no electricity or Internet access. (Or, probably, running water… although that matters less to a homelab.)

I think I moved it before it got wet, but yesterday is such a blur that I just don’t know. I remember we spent some time fighting back the water with sandbags and barricades. I remember the moments each room began to fail, one by one, and we started moving whatever we could carry to higher floors (max props to folks from Eynsham Fire Bridade for helping with the heavy stuff). But if you ask me what order we rescued things in, I just don’t know.

I guess we’ll find out when the waters recede, and it’s safe to go check.

Fucking hell.

×

Flood

My house is under water.

A flooded house.

Well, fuck.

×

Dan Q found GC9MCDM The Queen Of Mystery

This checkin to GC9MCDM The Queen Of Mystery reflects a geocaching.com log entry. See more of Dan's cache logs.

After solving the riddle yesterday, my partner Ruth and I came up from the seafront to find this cache today. What a delightful spot to hide the cache, and what a wonderful puzzle (and spot of local literary history) with which to bring us here.

Dan leans against a wall in a tropical park, writing on a log sheet.

SL, FP awarded. Greetings from Oxfordshire, UK. TFTC!

×

Dan Q found GC10N80 Wye Eye

This checkin to GC10N80 Wye Eye reflects a geocaching.com log entry. See more of Dan's cache logs.

I’m on a family holiday, staying over in Catbrook, and I have a holiday tradition of getting up early (before the kids are up!) to come out on geocaching jaunts.

I very nearly didn’t consider this at all. It’s fake location, nestled amongst challenge caches (which I have no interest in whatsoever), made me initially suspect it would be another of the same. It’s only a lucky coincidence I clicked on it at all!

(Maybe that’s why this cache had no finds in 2025? Such a shame!)

But I’m glad I did. I puzzled over the riddle for a little while before the “odd line out” made me think of something. So confident was I in the resulting coordinates that I didn’t even visit the special web page to double-check, which meant I missed out on the object hint until I was in the field and needed one! This, in turn, was pretty satisfying!

I saved this cache for my second morning’s outing: free one on which I didn’t bring the dog (for whose little legs this hike might have been too intense). This was the right choice. I had to ford a flooded and frozen path by moonlight near Cleddon before a visit to the waterfalls (and the associated cache) then pressed on up into the woods to uncover this cache, which has sat alone and undisturbed for, what… 20 months?

Sun rising over a hill beyond a broad valley full of frozen fields.
The view from near the GZ is fantastic.

It’s in fine condition and in an absolutely postcard-perfect spot. The sun was at long last creating the hills on the far side of the valley as I signed my name and returned the box to its hiding spot. I really regret that this cache doesn’t see more footfall, and I hope that this effusive log (and the accompanying Favourite Point) might go some way to helping rectify that situation!

TFTC. It’s one of the best I’ve ever found. If I could award it two FPs I would!

×

Dan Q found GC2EFAW The Cairn Cache

This checkin to GC2EFAW The Cairn Cache reflects a geocaching.com log entry. See more of Dan's cache logs.

Happy New Year! The geopup and I, on holiday from West Oxfordshire and staying nearby, came out for a morning walk in the ice and snow today.

Our little Frenchie’s tiny legs made the work of climbing the stiles on this path a little challenging, but with persistence we were treated to a wonderful view of the sun broaching the horizon over the valley at the North end of School Wood.

The sun peeks through clouds at the horizon beyond a wide valley full of fields.

Soon the cairn was in sight, and what a brilliant spot for a cache! Signed log, and dropped a travel bug that’s come all the way from Texas to continue its journey. FP awarded for bringing us out this way.

×