HTTP Request Body for Form Values

HTTP Request Header

HTTP clients and servers largely depend on the “Content-Type” header to determine how to parse the request/response body. Common values for the “Content-Type” header are

  • application/json
  • application/atom+xml
  • application/pdf
  • application/octet-stream
  • application/x-www-form-urlencoded

and request/response body should be processed as JSON, XML, PDF, Raw Stream, or Form Data respectively.

How is Form Data Sent?

99.99% of forms in your web applications will be url-encoded and sent in the request body instead of the request URL for obvious reasons.

Parse Form Data with ParseForm()

func (r *Request) ParseForm() error
For all requests, ParseForm parses the raw query from the URL and updates r.Form.

For POST, PUT, and PATCH requests, it also reads the request body, parses it as
a form, and puts the results into both r.PostForm and r.Form. Request body 
parameters take precedence over URL query string values in r.Form.

If the request Body's size has not already been limited by MaxBytesReader,
the size is capped at 10MB.

For other HTTP methods, or when the Content-Type is not 
application/x-www-form-urlencoded, the request Body is not read, and r.PostForm
is initialized to a non-nil, empty value.

URL query parameters are also read in the r.Form map object.

References

Written with StackEdit.

How to Check nil Interface in Golang?

Never check an interface for nil.

Try the following code:

type user interface{}
type staff struct{}

func compareNil() {
    var generic user

	generic = (*staff)(nil)

	fmt.Printf("value=%v type=%T (generic==nil)=%v\n", generic, generic, generic == nil)

	generic = (nil)

	fmt.Printf("value=%v type=%T (generic==nil)=%v\n", generic, generic, generic == nil)
}

go playground: https://play.golang.org/p/7J9DeIjgNia

Output
value=<nil> type=*main.staff (generic==nil)=false
value=<nil> type=<nil> (generic==nil)=true
Why interface check for nil is special

An interface is a tuple of [Value, Type]. The nil interface is a tuple [nil, nil]. However, the above code is an interface containing [nil, *main.staff] which is not nil.

We can check for nil as follows:

func isNil(i interface{}) bool {                        
    return i == nil || reflect.ValueOf(i).IsNil() 
}

Here i==nil means i has [nil, nil] or has a nil value in [nil, *main.staff].

But if the interface points to a type that has no Nil value:

s := "hello"
generic = s
fmt.Printf("value=%v type=%T type=%v\n", generic, generic, reflect.ValueOf(generic).IsNil())

The code panics:

panic: reflect: call of reflect.Value.IsNil on string Value

goroutine 1 [running]:
reflect.Value.IsNil(...)
        /Users/xxx/.goenv/versions/1.14.0/src/reflect/value.go:1063
main.compareNil()
        /Users/xxx/go/1.14.0/src/mygo/interfaces/interfaces.go:48 +0x3b1
main.main()
        /Users/xxx/go/1.14.0/src/mygo/interfaces/interfaces.go:29 +0x142
exit status 2

Conclusion

The safest way to compare nil interfaces is switch on various types the interface can assume. Never check as myinterface == nil.

References

Why HTTP Status in Response is always StatusOK?

Why the following code works as expected but the next one does not?

Response 1

resp.WriteHeader(http.StatusBadRequest)
_, _ = resp.Write([]byte(`status code is 400`))

But if we change the order and write the body first and header later:

Response 2

_, _ = resp.Write([]byte(`status code is not 400!!`))
resp.WriteHeader(http.StatusBadRequest)

The header is set to http.StatusOK in Response 2.

Why does the order matter?

from .goenv/versions/1.14.0/src/net/http/server.go

    // If WriteHeader has not yet been called, Write calls
	// WriteHeader(http.StatusOK) before writing the data. 
    // Changing the header map after a call to WriteHeader (or
	// Write) has no effect unless the modified headers are
	// trailers.

So be careful and always write the status first, body next.

References

Golang: Careful with Named Return Parameters in Function

package main

import (
	"fmt"
)

func riskyParams() (num int, flag bool) {
    if num == 0 {  // Named parameters have default values in the scope
        flag = true
    }
	return // Beware of such return. You might return something unintended  
}

func main() {
	num, flag := riskyParams()
	fmt.Printf("num=%d flag=%v\n", num, flag)
}

The example highlights unintended side-effects of named return parameters.

Written with StackEdit.

The Best Git Commands for Dev

The most common part is:

The basic cycle

git pull master to get up to date

git checkout -b myname-feature to get a branch of your own

git add <files> that you changed/created
git add . to add everything in the current directory
git add -u to add all existing files in the repo

git commit
git commit -m "multiline commits" -m "without text editors" -m "wow!"

git push -u origin myname-feature the first time, git push after that

git branch -D myname-feature when it gets merged into master and you don’t need it cluttering your autocomplete anymore

Also read on

  • cherry-pick
  • reset commit
  • reset a file

The complete info is available at:
https://stu2b50.dev/posts/things-you-wante9665

Redis Expire Key: How TTL behaves?

  • An operation that modifies a key’s value resets the TTL.
  • An operation that alters the key’s value leaves TTL untouched.

Create a list with TTL = 120

redis> rpush "mylist" "first"  
(integer) 1  
  
redis> rpush "mylist" "second"  
(integer) 2  
  
redis> expire "mylist" 120  
(integer) 1  

Add new elements to the list and verify TTL

redis> TTL mylist  
(integer) 99  

redis> rpush "mylist" "second"  
(integer) 3  
  
redis> TTL mylist  
(integer) 79  

However, a call to EXPIRE will refresh the TTL.

References

Liveness vs Readiness Health Checks in Application

The liveness check finds if the application is alive or not. The application defines the logic and the liveness check verifies the expected output.
A webserver liveness check could include an HTTP handler that returns a fixed response or checks application dependencies.

Sample Liveness check

  • send a pong response in the handler
  • combine health check of all dependencies and return true/false

The Readiness check is to know if an application can accept traffic after initialization. A use case is a wait to serve traffic until all dependencies are ready. Essentially both checks have similar config options.

Sample Readiness Check

  • combine health check of all dependencies and return true/false
  • A init wait of 5 secs

References

Written with StackEdit.

Why be careful with defer in Golang

When does defer function executes?

The standard answer is: defer runs a function before the enclosing function returns.

It is a wrong explanation. The defer executes as follows:

  1. The enclosing function has processed returned values and stored them in registers
  2. All defer functions run in a LIFO order of definition.
  3. If the return parameters are named, the defer function can alter the return values.

Short Examples on Vulnerabilities in defer Code

defer Modifying Named Return Parameters

package main

import (
	"fmt"
	"sync"
)

func test4(x int) (y int) {
	defer func() {
		y = 100
	}()

	if x == 123 {
		return x
	}

	defer func() {
		y = 200
	}()

	return x
}

func main() {
	fmt.Printf("Hello x=%v\n", test4(1234))
}

The above code returns value 123 referenced by y. Now, defer functions start executing. Mind it, the function test4() is yet to return to main().

  • The last defer function modifies the return value y to 200.
  • The first defer function modifies the return value y to 100.
  • test4() returns 100.

Deadlocked Program with Improper Understanding of defer

func test5(abort bool) {
	var mutex = &sync.Mutex{}

	defer func() {
		fmt.Printf("locking the mutex-first\n")
		mutex.Unlock()
	}()

	if abort {
		mutex.Lock()
		fmt.Println("critical section")
		mutex.Unlock()
		return
	}

	defer func() {
		fmt.Printf("locking the mutex-second\n")
		mutex.Lock()
	}()

}

func main() {
	test5(true)
}
go run deferDetails/main.go
critical section
locking the mutex-first
fatal error: sync: unlock of unlocked mutex

goroutine 1 [running]:
runtime.throw(0x10d2d55, 0x1e)
        /Users/ovo/.goenv/versions/1.14.0/src/runtime/panic.go:1112 +0x72 fp=0xc000078e38 sp=0xc000078e08 pc=0x102e542
sync.throw(0x10d2d55, 0x1e)
        /Users/ovo/.goenv/versions/1.14.0/src/runtime/panic.go:1098 +0x35 fp=0xc000078e58 sp=0xc000078e38 pc=0x102e4c5
sync.(*Mutex).unlockSlow(0xc00018c008, 0xc0ffffffff)
        /Users/ovo/.goenv/versions/1.14.0/src/sync/mutex.go:196 +0xd6 fp=0xc000078e80 sp=0xc000078e58 pc=0x106a746
sync.(*Mutex).Unlock(...)
        /Users/ovo/.goenv/versions/1.14.0/src/sync/mutex.go:190
main.test5.func1(0xc00018c008)
        /Users/ovo/go/1.14.0/src/mygo/deferDetails/main.go:13 +0x8b fp=0xc000078ee0 sp=0xc000078e80 pc=0x109ec7b
main.test5(0xc00006c001)
        /Users/ovo/go/1.14.0/src/mygo/deferDetails/main.go:20 +0x11a fp=0xc000078f70 sp=0xc000078ee0 pc=0x109eb1a
main.main()
        /Users/ovo/go/1.14.0/src/mygo/deferDetails/main.go:31 +0x26 fp=0xc000078f88 sp=0xc000078f70 pc=0x109ebd6
runtime.main()
Explanation

ha! the defer caused a panic in the program. I am not quite sure why it failed. If I remove the return, the code works.

package main

import (
	"fmt"
	"sync"
)

func test5(abort bool) {
	var mutex = &sync.Mutex{}

	defer func() {
		fmt.Printf("locking the mutex-first\n")
		mutex.Unlock()
	}()

	if abort {
		mutex.Lock()
		fmt.Println("critical section")
		mutex.Unlock()
	}

	defer func() {
		fmt.Printf("locking the mutex-second\n")
		mutex.Lock()
	}()

}

func main() {
	test5(true)
}
go run deferDetails/main.go
critical section
locking the mutex-second
locking the mutex-first

Conclusion

  1. Use defer very carefully, especially around named return parameter
  2. Multiple defer statements are executed in reverse order of appearance.
  3. Need to root cause why the code with return panic.

References

Written with StackEdit.

%d bloggers like this: