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.

Certificate infrastructure is built on trust. If you trust the wrong thing, it all falls down. Unfortunately we do it all the time anyway.

Hey Jim YT Chen, have you tried http://httptoolkit.tech/view/ruby/ as an alternative to HttpLog? It covers a very similar use case (capturing & viewing sent Ruby HTTP), but it’s got a proper UI & tools and doesn’t require any of those code changes at all. Let me know what you think :-)

Debug all HTTP(S) sent by git, npm, apt-get, or anything else

The command line is powerful, but can be hard to understand, and extremely hard to debug. Ever run a command, see it fail with a cryptic error, and have no idea why?

Better tools can help you understand what’s really going on. They can let you see inside the command you’re running to understand how it’s communicating, see what data it’s working with, and debug it in depth.

Excitingly I’ve just shipped one-click terminal interception to do exactly this with HTTP Toolkit, for HTTP and HTTPS, to show you everything your CLI is sending and ...

HTTP View is a beautiful, free & open-source HTTP inspector. This is the first release of HTTP Toolkit, and lets you intercept HTTP or HTTPS traffic with one click, explore & examine that traffic up close, and discover exactly what your code (or anybody else’s) is sending.

Want to dive right in? Download it now.

HTTP Toolkit is a project that I’ve been working on for a while, to build an open-source suite of tools for HTTP development. The goal is to intercept & examine HTTP, edit it live, analyse flows of HTTP requests to audit performance and security, and rapidly prototype HTTP cl...

Modern easy IoT with JS, Docker & Resin.io at DEVit
New repo: httptoolkit/async-invariants
Just found a new #NodeJS trick: you can use async_hooks in Node to check global invariants that must hold between e… https://twitter.com/i/web/status/1290569456310259712
Just had my first PR merged into Node itself! A quick update to the docs to explicitly cover connection events and… https://twitter.com/i/web/status/1290227309765566465

I think you want something like this:

export enum SortValueType { String = 'string', Number = 'number', Date = 'date', } type SortDirection = string; export interface SortConfig<T extends SortValueType> { key: string; direction: SortDirection; type: T; options: T extends SortValueType.Date ? { sortBy: 'year' | 'day'; } : { sortBy?: undefined }; } // OK: let dateConfig: SortConfig<SortValueType.Date> = { key: "key", direction: "left", type: SortValueType.Date, options: { sortBy: 'year' } } // Not OK: let numberConfig: SortConfig<SortValueType.Number> = { ke...
doc: document the connection event for HTTP2 & TLS servers
GitHub have published an official OpenAPI spec for their v3 API: https://github.blog/2020-07-27-introducing-githubs-openapi-description/

You need to use the standard TypeScript import & export syntax, rather than using platform-specific features like module.exports. In this case, you want this in secret.ts:

export const getWorkDayCredentials = async (region, secretName) => { // ... }; 

You'll also need a similar change in index.ts:

export const lambdaHandler = async (event, context) => { // ... }; 

I'd suggest looking through the Modules section of the TypeScript guidebook for more details and examples.

For TypeScript specifically, there's no convenient standard solution to this. You need some kind of linter or extra tool to enforce such checks.

One option that you might find interesting is git-confirm (full disclosure: I wrote this). It's a git hook, which asks you to confirm before committing anything that matches a configurable set of patterns. It's not typescript specific, it'll work for any content at all where you're using git, and it can match whatever patterns you like.

For example, you can write your messages prefixed with TODO:, and if you try to commit any changes that add a line l...

You can do this by looking at the user-agent HTTP header, which will be included in every request from a browser. The Chrome 81 user agent for example might look like this:

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36 

Note the Chrome/81.

The specific format can vary significantly, and includes a lot of cruft near the start, mainly for backward compatibility reasons. It's generally a bad idea to try to automatically analyse this, but it should be enough for manual inspection.

Take a look at https://developers.whatismybrowse...

You can't require a PEM file - that's only used for JS & JSON files. The error is a complaint that the PEM file is not valid JS syntax.

To read raw data from other files, including PEM, you can use the fs module: https://nodejs.org/api/fs.html.

For example:

const fs = require('fs'); fs.readFile("./secretkey.pem", "ascii", function (pemContents) { // do whatever you want here }); 

You can do this by looping to repeatedly walk through previousElementSibling's, until you find one that's not hidden. For example:

const active = document.querySelector('.active'); // Get the previous sibling let result = active.previousElementSibling; // If it's hidden, continue back further, until a sibling isn't hidden while (result && result.hidden == true) { result = result.previousElementSibling; } if (result) { // You got a non-hidden sibling! console.log(result); } else { // There is no previous sibling that's not hidden } 

There's many possibilities here, but one option would be something like this:

const abvDepartments = departments.map(equip => { return { 'service': 'Svc', 'help': 'HLP', 'contracts': 'Con' }[equip] || ''; }); 

If you'd like, and you're not doing anything else in the map, you can shorten that even further:

const abvDepartments = departments.map(equip => ({ 'service': 'Svc', 'help': 'HLP', 'contracts': 'Con' }[equip] || '')); 

To tunnel HTTP/2 through a proxy that doesn't understand it, you need to use HTTP/1.1 for the initial connection, and then use HTTP/2 only in the tunnel. Your code uses HTTP/2 right from the start, which isn't going to work.

To actually make that tunnel, you first send an HTTP CONNECT request for the target host, and receive a 200 response, and then everything else on the connection in future is forwarded back and forth between you and the target host.

Once you have that tunnel working, you can send HTTP/2 (or anything else the target server understands) and it'll go straight to your target.


Avoid crashing node due to post-setup connection errors
https://tauri.studio/ looks super interesting - a serious Electron alternative that uses your OS browser engine (… https://twitter.com/i/web/status/1281641008258854913
New repo: httptoolkit/stream-socket

The problem here is that key is inferred as string rather than keyof typeof translatableRoutes, which would be correct in this case.

There's various complex reasons why that isn't always safe to infer, but the end result is that TypeScript can't give key the right type for you automatically.

In addition, type annotations for for-in loops aren't allowed, so you can't manually fix it inline.

Fortunately though, you can provide a type annotation separately. Replace your for-in loop with:

let key: keyof typeof translatableRoutes; for (key in translatableRoutes) { if (translatableRoutes[key][findLa...
Emit connection errors as server sessionError
Ok, it's time: HTTP/2 interception & rewriting is coming to @HttpToolkit! Foolishly, I'm going to try & live tweet… https://twitter.com/i/web/status/1280132796951007233
Every week or so, Avast pings an internal API used by the @HttpToolkit desktop app & website. Always from 195.74.7… https://twitter.com/i/web/status/1280090246168948736

There are many ways to do this, but whatever happens, you need to change your types, as they're not correct at the moment, and you need to manually transform your result object.

The types currently say that Axios.get will return a model with Id and Name keys, which is definitely wrong (it will return a model with id and name keys). You can transform this result, but can't easily change the first return value there, so you need to correct that.

Once that's correct, you need to transform the JSON response to the model you want. One option is to use lodash, which makes this fairly easy.

A full ex...

What you're trying to do isn't possible purely in types I'm afraid. The problem is here:

new Test<A, 'id'>().create(123); // Want to get { id: 123 } 

That compiles to this JavaScript:

new Test().create(123); 

You can see it's impossible to return an object with the right key here, because your type parameter ('id') doesn't exist in the compiled code. Type information is not present at runtime.

To fix this, you need to change that design, and pass 'id' as a string parameter to either create or Test(). For example:

class Test<T extends object, TId extends keyof T = keyof T> { constru...
Avoid crashing node due to post-setup connection errors

Your best bet is to make your conditional type return true or false, and then try to assign true to the result. Like so:

type A = 1 | 2 // Must be different from B type B_OK = 3 type B_FAIL = 2 | 3 type AssertTrue<T extends true> = T; type IsDifferent<X,Y> = Extract<X,Y> extends never ? true : false type result1 = AssertTrue<IsDifferent<A, B_OK>>; // OK type result2 = AssertTrue<IsDifferent<A, B_FAIL>>; // Error 

You can use the new @ts-expect-error comments feature in version 3.9 on the second line to enforce that the error always throws.

Open-source product development is magic: https://twitter.com/HttpToolkit/status/1278341653795930118