[Golang] Parse Accept-Language in HTTP Request Header


This post is the Go version of my previous post "[Python] Parse Accept-Language in HTTP Request Header" [1]. This Go example parses Accept-Language string in HTTP request header and output (languageTag, quality) pairs:

parse.go | repository | view raw
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// http://golang.org/pkg/strings/
// http://stackoverflow.com/questions/16551354/how-to-split-string-and-assign
// http://stackoverflow.com/questions/22688010/how-to-trim-leading-and-trailing-white-spaces-of-a-string-in-golang
package locale

import (
	"strconv"
	"strings"
)

type LangQ struct {
	Lang string
	Q    float64
}

func ParseAcceptLanguage(acptLang string) []LangQ {
	var lqs []LangQ

	langQStrs := strings.Split(acptLang, ",")
	for _, langQStr := range langQStrs {
		trimedLangQStr := strings.Trim(langQStr, " ")

		langQ := strings.Split(trimedLangQStr, ";")
		if len(langQ) == 1 {
			lq := LangQ{langQ[0], 1}
			lqs = append(lqs, lq)
		} else {
			qp := strings.Split(langQ[1], "=")
			q, err := strconv.ParseFloat(qp[1], 64)
			if err != nil {
				panic(err)
			}
			lq := LangQ{langQ[0], q}
			lqs = append(lqs, lq)
		}
	}
	return lqs
}

Test program for the above code:

parse_test.go | repository | view raw
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package locale

import "testing"

func TestParseAcceptLanguage(t *testing.T) {
	t.Log("da, en-gb;q=0.8, en;q=0.7")
	lqs := ParseAcceptLanguage("da, en-gb;q=0.8, en;q=0.7")
	if lqs[0].Lang != "da" {
		t.Error(lqs[0].Lang)
	}
	if lqs[0].Q != 1 {
		t.Error(lqs[0].Q)
	}
	if lqs[1].Lang != "en-gb" {
		t.Error(lqs[1].Lang)
	}
	if lqs[1].Q != 0.8 {
		t.Error(lqs[1].Q)
	}
	if lqs[2].Lang != "en" {
		t.Error(lqs[2].Lang)
	}
	if lqs[2].Q != 0.7 {
		t.Error(lqs[2].Q)
	}
	t.Log(lqs)

	t.Log("zh, en-us; q=0.8, en; q=0.6")
	lqs2 := ParseAcceptLanguage("zh, en-us; q=0.8, en; q=0.6")
	t.Log(lqs2)

	t.Log("es-mx, es, en")
	lqs3 := ParseAcceptLanguage("es-mx, es, en")
	t.Log(lqs3)

	t.Log("de; q=1.0, en; q=0.5")
	lqs4 := ParseAcceptLanguage("de; q=1.0, en; q=0.5")
	t.Log(lqs4)
}

Makefile for automating the development:

Makefile | repository | view raw
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# cannot use relative path in GOROOT, otherwise 6g not found. For example,
#   export GOROOT=../go  (=> 6g not found)
# it is also not allowed to use relative path in GOPATH
export GOROOT=$(realpath ../../../../go)
export GOPATH=$(realpath .)
export PATH := $(GOROOT)/bin:$(GOPATH)/bin:$(PATH)


test:
	@# -v means verbose, can see logs of t.Log
	@go test -v

fmt:
	go fmt *.go

help:
	go help

The output after run make:

=== RUN TestParseAcceptLanguage
--- PASS: TestParseAcceptLanguage (0.00s)
        parse_test.go:6: da, en-gb;q=0.8, en;q=0.7
        parse_test.go:14: [{da 1} {en-gb 0.8} {en 0.7}]
        parse_test.go:16: zh, en-us; q=0.8, en; q=0.6
        parse_test.go:18: [{zh 1} {en-us 0.8} {en 0.6}]
        parse_test.go:20: es-mx, es, en
        parse_test.go:22: [{es-mx 1} {es 1} {en 1}]
        parse_test.go:24: de; q=1.0, en; q=0.5
        parse_test.go:26: [{de 1} {en 0.5}]
PASS
ok      _/home/koan/dev/nstechdev/userpages/content/code/go-accept-language     0.003s

Tested on: Ubuntu Linux 14.10, Go 1.4.


References:

[1][Python] Parse Accept-Language in HTTP Request Header
[2]Detect User Language (Locale) on Google App Engine Python
[3]strings - The Go Programming Language
[4]go - How to split string and assign? - Stack Overflow
[5]go - How to trim leading and trailing white spaces of a string in golang? - Stack Overflow
[6]strconv - The Go Programming Language
[7]Adding elements to a slice - A Tour of Go
[8]testing - The Go Programming Language