Tim Perry

Creator of HTTP Toolkit: powerful tools to debug, test & build with HTTP(S).

Passionate tech speaker, open-source contributor, and maintainer of Loglevel, Git‑Confirm and notes.

Through the Next Generation Internet (NGI) initiative, HTTP Toolkit has been selected for funding from the EU's Horizon research & innovation program, to expand beyond HTTP and offer the same interception, debugging & testing functionality for applications built on top of the decentralized web.

This is going to be a huge opportunity to in...

Pac-Resolver, a widely used NPM dependency, had a high-severity RCE (Remote Code Execution) vulnerability that could allow network administrators or other malicious actors on your local network to remotely run arbitrary code inside your Node.js process whenever you tried to send an HTTP request.

This is bad!

This package is used for PAC file suppor...

Today Node.js announced and released a security fix for CVE-2021-22939, along with two other high severity issues. They've rated this vulnerability as 'low severity', but I think it's worth a closer look, as (imo) this really understates the risk here, and the potentially widespread impact.

In practice, this poses a risk to anybody making TLS conne...

There's been a lot of discussion recently about how "Safari is the new IE" (1, 2, 3, 4, 5).

I don't want to rehash the basics of that, but I have seen some interesting rebuttals, most commonly: Safari is actually protecting the web, by resisting adding unnecessary and experimental features that create security/privacy/bloat problems.

That is worth ...

Once upon a time, loading common scripts & styles from a public CDN like cdnjs or Google's Hosted Libraries was a 'best practice' - a great way to instantly speed up your page loads, optimize caching, and reduce costs.

Nowadays, it's become a recipe for security, privacy & stability problems, with near-zero benefit. Just last week, a secu...

Some Android apps go to astounding lengths to ensure that even the owner of a device can never see the content of the app's HTTPS requests.

This is problematic for security research, privacy analysis and debugging, and for control over your own device in general. It's not a purely theoretical problem either - protections like this attempt to direct...

HTTP content encoding is an incredibly powerful tool that can save you huge amounts of bandwidth and make your web or mobile application faster, basically for free.

Unfortunately, it's poorly understood by most developers. There's a lot of power here, but few people are aware of the options or what "content encoding" really means, so it's mostly le...

HTTP(S) is the glue that binds together modern architectures, passing requests between microservices and connecting web & mobile apps alike to the APIs they depend on.

What if you could embed scripts directly into that glue?

By doing so, you could:

  • Inject errors, timeouts and unusual responses to test system reliability.
  • Record & report ...

Traditionally, a TCP port has a single server listening for incoming connections, and that server expects you to send messages in the right protocol for that port. For HTTP, it's normally a web server that'll send you a response directly, or some kind of proxy that will pass all requests through to another server, and then pass the responses back.


Nothing is ever finished or perfect, and HTTP is no exception.

HTTP SEARCH is a new HTTP method, for safe requests that include a request body. It's still early & evolving, but it was recently adopted as an IETF draft standard, and it's going to add some great new tools for HTTP development everywhere.

What does that mean, why do we need a new...

CORS can be complicated. If you're struggling with it, you might discover the concept of a 'CORS proxy' that promises to solve this, like cors-anywhere or one of the many 'free CORS proxy' hosted services.

CORS proxies let you bypass the security restrictions that CORS applies, with just a tiny change of URL.

That feels convenient, but turning off ...

HTTP is used by almost all Android apps to request data, load content, and send changes to backend servers. If you can see and edit these requests & responses then you can understand, debug, and change how any app works, but Android makes this hard to do.

By default, almost all apps will use HTTPS but won't trust user-installed certificates. T...

Java and the JVM more generally are widely used for services everywhere, but often challenging to debug and manually test, particularly in complicated microservice architectures.

HTTP requests and responses are the core of interactions between these services, and with their external APIs, but they're also often invisible and inaccessible. It's hard...


HTTP is fundamental to modern development, from frontend to backend to mobile. But like any widespread mature standard, it's got some funky skeletons in the closet.

Some of these skeletons are little-known but genuinely useful features, some of them are legacy oddities relied on by billions of connections daily, and some of them really shouldn't ex...

HTTP Toolkit is in this week's @consoledotdev newsletter! (Not quite accurate though - it's not "Core features op… https://twitter.com/i/web/status/1441019538749935618
What's the right chat platform for an open-source project in 2021? https://twitter.com/HttpToolkit/status/1440649806423085061
Fallback to dns.lookup for IPv4 & IPv6 separately
Big news! HTTP Toolkit is now being funded by the EU's @HorizonEU fund (via @NgiPointer) to develop beyond HTTP by… https://twitter.com/i/web/status/1438105225009762305
Holy shit this is bad. Hope all the OSS projects successfully migrated away from Travis when they started changing… https://twitter.com/i/web/status/1437708059267276804
https://pixelfed.org/ is very exciting - Instagram, but in the Fediverse (so you can follow Pixelfed accounts fro… https://twitter.com/i/web/status/1437699071997841409
Update dns2 to match v2.0 and add UDP & TCP server types
That's even better! Thanks @Philippe, I've updated the answer
Yes - that's not the right criterion. I'm only interested in whether /dev/tty is available (and it is by default when you run any bash script in an interactive terminal, with or without -i).
I've done some testing and this seems to work pretty well! I've upvoted but I'm going to use my own slightly simpler answer below that just uses printf & bash instead, just because I'm slightly worried that complex ps commands like this might work slightly differently on Mac and other weird environments (see apple.stackexchange....
I tested this, and it works in some cases, but not all cases. When running bash ./test.sh in an interactive terminal for example [ -t 255 ] is incorrectly false.

After testing lots of promising but not quite perfect suggestions (see the other answers), I think I've found my own solution that does exactly fit my needs:

if bash -c ": >/dev/tty" >/dev/null 2>/dev/null; then # /dev/tty is available and usable else # /dev/tty is not available fi 

To explain:

: >/dev/tty does nothing (using ...

Good suggestion, but this doesn't seem to work reliably unfortunately... In my testing, when running a saved script in bash (v5) then $PS1 is unset, even if it's set in the terminal itself & /dev/tty is working (also: this actually needs to be ${PS1+x} to handle the case where it's set but empty).
FD 255 is an option, that might work. It would be better to have an option to test /dev/tty itself though, without being dependent on bash internal implementation details. I'd really prefer to check the state of the tty device I want to use directly, rather than patch in another workaround.
@Philippe to launch $EDITOR connected to the TTY, from inside a pipeline of other commands (so no direct access to stdin/stdout). When /dev/tty is available that works great, and when it's not I can provide an OK fallback, but I need to be able to detect that.
How? Can you give an example? This script is run as part of a pipeline, so it never has any access to the TTY via stdin or any FD, so I can't "keep" it.
No idea why, but $- contains "hBH" in my bash, not i, so that example doesn't work.
In my case, stdin & stdout are pipes to other processes, so -t 0 & -t 1 are false, and this won't work. I still want to communicate with the controlling TTY when one is available though, by using /dev/tty directly. When /dev/tty is available this works fine! But not in completely TTY-less environments.

I have a bash script from which I want to access /dev/tty, but only when it's available.

When it's not available (in my case: when running my script in GitHub Actions) then when I try to access it I get /dev/tty: No such device or address, and I'm trying to detect that in advance to avoid the error and provide fallback behaviour instead.

To do so I...

Add allowHalfOpen to Node's Duplex stream
Allow Node TLS's 'alpnProtocol' to be false
First flight back home to the UK since December 2019 😮 https://t.co/Av3Gqh5yCO
Uh oh (from my article just 2 weeks ago: https://httptoolkit.tech/blog/safari-is-killing-the-web/) https://t.co/kVAJe8edX0