« Back to Index

[Golang http.Request.Context]

View original Gist on GitHub

Tags: #go #golang #http #request #context

Golang http.Request.Context.go

// https://goplay.tools/snippet/YB3_8gerQ-U
package main

import (
	"context"
	"fmt"
	"net/http"
)

const beepboop = "whatever"

type User struct {
	Name string
}

func main() {
	fmt.Printf("beepboop: %#v\n\n", beepboop)
	r := new(http.Request)
	fmt.Printf("r: %#v\n\n", r)
	c := r.Context()
	fmt.Printf("c: %#v\n\n", c)
	nc := context.WithValue(c, "foo", "bar")
	fmt.Printf("nc: %#v\n\n", nc)
	if v := nc.Value("foo"); v != nil {
		fmt.Printf("found value in nc context: %#v (%T)\n\n", v, v)
	}
	nc2 := context.WithValue(nc, beepboop, 123)
	fmt.Printf("nc2: %#v\n\n", nc2)
	if v := nc2.Value(beepboop); v != nil {
		fmt.Printf("found value in nc2 context: %#v (%T)\n\n", v, v)
	}
	u := User{Name: "integralist"}
	nc3 := context.WithValue(nc2, "some_other_key", &u)
	fmt.Printf("nc3: %#v\n\n", nc3)
	if v := nc3.Value("some_other_key"); v != nil {
		fmt.Printf("found value in nc3 context: %#v (%T)\n\n", v, v)
        // IMPORTANT: Although Printf looks to show the type it's not concrete.
        // We're actually dealing with any empty interface{}/any type.
        // So we have to coerce it. There's no type saftey.
		u, ok := v.(*User)
		if ok {
			fmt.Println(u.Name)
		}
	}
}

/*
beepboop: "whatever"

r: &http.Request{Method:"", URL:(*url.URL)(nil), Proto:"", ProtoMajor:0, ProtoMinor:0, Header:http.Header(nil), Body:io.ReadCloser(nil), GetBody:(func() (io.ReadCloser, error))(nil), ContentLength:0, TransferEncoding:[]string(nil), Close:false, Host:"", Form:url.Values(nil), PostForm:url.Values(nil), MultipartForm:(*multipart.Form)(nil), Trailer:http.Header(nil), RemoteAddr:"", RequestURI:"", TLS:(*tls.ConnectionState)(nil), Cancel:(<-chan struct {})(nil), Response:(*http.Response)(nil), Pattern:"", ctx:context.Context(nil), pat:(*http.pattern)(nil), matches:[]string(nil), otherValues:map[string]string(nil)}

c: context.backgroundCtx{emptyCtx:context.emptyCtx{}}

nc: &context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"foo", val:"bar"}

found value in nc context: "bar" (string)

nc2: &context.valueCtx{Context:(*context.valueCtx)(0xc00011a840), key:"whatever", val:123}

found value in nc2 context: 123 (int)

nc3: &context.valueCtx{Context:(*context.valueCtx)(0xc00011a8a0), key:"some_other_key", val:(*main.User)(0xc000106100)}

found value in nc3 context: &main.User{Name:"integralist"} (*main.User)

integralist
*/