Lars Wiegman

  • Home
  • Skills
  • Contact
  • Blog

Articles

posted on November 13, 2018 #

Shell history expansion

posted on November 13, 2018 #

Shells like Bash and Zsh support all kinds of expansions. One I use on a daily basis is the history expansion which expands to the last word of previous command in history. The next example would open my editor with ‘new.txt’ file.

% cp old.txt new.txt
% vim !$

Tags

posted on November 13, 2018 #

tech

posted on November 13, 2018 #

Deploy and serve assets from a zip archive

posted on August 4, 2015 #

When going through the sourcecode of the godoc.org service I came upon this gem called the zipfs package. From the docs:

Package zipfs file provides an implementation of the FileSystem interface based on the contents of a .zip file.

Combine this with the FileServer handler from the net/http package and you'll be able to serve your assets from a single zip archive.

I wouldn't recommend this strategy in production but it beats embedding your HTML templates, CSS files and your API docs in your Go code.

The following is an example of a HTTP service which serves the contents of the given archive from the /assets/ path:

package main

import (
    "archive/zip"
    "flag"
    "log"
    "net/http"

    "golang.org/x/tools/godoc/vfs/httpfs"
    "golang.org/x/tools/godoc/vfs/zipfs"
)

func main() {
    zipPath := flag.String("zip", "assets.zip", "zip file containing assets")
    httpAddr := flag.String("http", "localhost:6011", "http address")
    flag.Parse()

    r, err := zip.OpenReader(*zipPath)
    if err != nil {
        log.Fatal(err)
    }
    fs := zipfs.New(r, *zipPath)

    m := http.NewServeMux()
    m.Handle("/assets/", http.FileServer(httpfs.New(fs)))

    log.Print("Listening on ", *httpAddr)
    if err := http.ListenAndServe(*httpAddr, m); err != nil {
        log.Fatal("ListenAndServe:", err)
    }
}

Distributed systems ruining your computer

posted on May 13, 2014 #

Funniest definition of a distributed, still hold true today:

A distributed system is one in which the failure of a computer you didn't even know existed can render your own computer unusable.

By Leslie Lamport, father of the theory behind distributed systems.

Linkeds

posted on May 13, 2014 #

Random password generator

posted on March 18, 2014 #

I was updating a random password generator for a project, thought I'd share the resulting code. Also availabe as a gist.

Using a default length of 14 characters this should generate passwords with 84 bits of entropy.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os, string

def random_password(length=14):
    """
    Random password generator.

    Default generated password will have an entropy of 84 bits.

    For each character in the password, generate a random byte, reduce
    the integer value to modulo 64 and use the result as an index on
    the character pool.

    In a 64 character pool, each character will have an entropy of 6
    bits. With a lenght of 14 characters the total entropy is 84 bits:

        log2(64) * 14 = 84 bits

    The difference between 13 and 14 characters can be several years
    to brute force. """

    characters = string.ascii_letters + string.digits + '+/'

    l = list()
    for x in xrange(length):
        i = ord(os.urandom(1)) % len(characters)
        c = characters[i]
        l.append(c)
    return ''.join(l)

if __name__ == '__main__':
    print(random_password())

Generating passwords is easy, storing them safely seems to be more of a challenge.

Do more with the Caps lock key in OS X

posted on March 17, 2014 #

To most of us, the Caps Lock key is useless and even annoying; waiting to be accidentally turned on and litter your input with caps. Which is a pity because considering its location and size it's a convenient key to tap.

By disabling the Caps lock functionality in OS X and using a third party app, the Caps lock key can become quite useful.

For example, control tmux, on OS X version 10.9.

Disable the Caps lock key in OS X

  1. Launch the System Preferences app
  2. Navigate to the Keyboard panel, from the Keyboard tab click the “Modifier Keys…” button
  3. Choose the “No Action” option for the Caps Lock Key

Tapping the Caps lock key will now be ignored by OS X.

Remap the Caps lock key

Because the Caps lock key isn't a regular key, it can't be configured by applications or OS X, we'll need to remap it to a regular key, preferably one you rarely use, like F19. PCKeyboardHack allows us to do just that.

  1. Download and install PCKeyboardHack matching your OS X version

  2. After installing PCKeyboardHack you'll need to restart OS X or load the kext manually:

     $ sudo kextload /Applications/PCKeyboardHack.app/Contents/Library/PCKeyboardHack.10.9.signed.kext
    

    Note! Load the kext matching your OS X version.

  3. Launch the PCKeyboardHack app

  4. Change the keycode of the Caps Lock key to a key you don't regularly use, like F19 which has keycode 80.

Tapping the Caps lock key will now invoke the F19 keycode.

Configure tmux to use Caps lock

To use the remapped Caps lock key as a prefix for tmux, you'll need to bind the F19.

Add the following to your ~/.tmux.conf:

unbind C-b
set-option -g prefix F19

If tmux was already running, reload its configuration file:

$ tmux source-file ~/.tmux.conf

Tapping Caps lock will be less of a strain on your finger than tapping Ctrl-b.

Dennis the DNS menace

posted on March 7, 2014 #

Just pushed a new project to Github, it's just a small piece of a live project as I'm usually not at liberty to open-source production code.

The project is called Dennis. It's a nameserver which can serve customised DNS responses on a per user basis. It's written in the Go programming language and uses Redis as a fast datastore.

On its own Dennis isn't very useful but by adding a DNS recursor and a HTTP(S) proxy, Dennis can bypass geo-blocking for thousands of users. It works by identifying users by their IP address, and each user can setup an unlimited number of custom DNS responses.

For a more elaborate description see the project on Github, github.com/namsral/dennis.

Tag cached responses with uWSGI

posted on March 4, 2014 #

uWSGI is a powerful application server but the documentation can be light on some subjects like caching.

If you want distinguish cache hits from misses you can use the incache:key= condition. Using the following uWSGI configuration will add a X-Cache header to each response.

[uwsgi]

...

; Enable caching
mime-file = /etc/mime.types
cache2 = name=%n-cache,items=100
    
; Check if URI is cached
route-if = incache:key=${REQUEST_URI},name=%n-cache goto:cache_hit

; Cache MISS
route-label = cache_miss
route-run = addheader:X-Cache: MISS
route-run = cachestore:key=${REQUEST_URI},name=%n-cache,expires=172800
route-run = last:

; Cache HIT
route-label = cache_hit
route-run = addheader:X-Cache: HIT
route-run = cache:key=${REQUEST_URI},name=%n-cache,mime=1

Requesting the same URI twice in a row will tag the response accordingly and add an additional Expires header.

$ curl -I -X GET http://larsman.nl/
    HTTP/1.1 200 OK
    ...
    X-Cache: MISS

$ curl -I -X GET http://larsman.nl/
    HTTP/1.1 200 OK
    ...
    Expires: Thu, 06 Mar 2014 11:11:14 GMT
    X-Cache: HIT
  • Home
  • Skills
  • Blog
  • Contact
  • •
  • Archive
  • Feed
  • GitHub

Copyright © 2007-2024 Lars Wiegman