How can I tell if net/http's ResponseWriter.Write() has been called? - http

Suppose I have a chain of net/http Handlers, and an early one responds with an HTTP error (http.StatusInternalServerError, for instance). How can I detect this in the following handlers, and avoid sending additional data to the client?
Or is this entirely the wrong approach to the problem?

http.ResponseWriter is an interface. So just compose a new instance of it:
type MyResponseWriter struct {
http.ResponseWriter
WroteHeader bool
}
func (w *MyResponseWriter) Write(b []byte) (int, error) {
w.WroteHeader = true
return w.ResponseWriter.Write(b)
}
func (w *MyResponseWriter) WriteHeader(code int) {
w.WroteHeader = true
w.ResponseWriter.WriteHeader(code)
}
And in your handlers:
//...
if w, ok := w.(*MyResponseWriter); ok && w.WroteHeader {
log.Println("Already wrote, skipping")
return
}
EDIT: Another thing to consider. Most of the time if you have a "chain" of handlers that means that a handler is called inside a handler. So if you have something like
type Handler1 struct { http.Handler }
type Handler2 struct { http.Handler }
type Handler3 struct { http.Handler }
var MyHandler http.Handler = Handler1{Handler2{Handler3{h}}}
as long as each of those call the inner handler as the last thing they do with w and r, you should be fine because then w and r won't even reach the inner handler. E.g.
func (h Handler2) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if somethingBadHappened() {
w.WriteHeader(http.StatusInternalServerError)
return
}
h.ServeHTTP(w, r) // Not called if somethingBadHappened().
}

First: a lighter-weight solution may exist.
However, if you cannot find one, consider using x/net/context to allow you to implement timeouts, deadlines, and of course, early termination of middleware chains.

Related

Interfaces and address operators

I have a problem to understand why the address operator can be used when the return type is an interface
func NewReader() IReader {
return &Reader{}
}
but (of course) not when a return type is a struct
func NewReader() Reader {
return &Reader{} // cannot use &Reader literal (type *Reader) as type Reader in return argument
}
The function signature later is func MyFuncReader(r IReader) but the reflect.TypeOf(r) is *main.Reader.
So the type IReader is hiding the fact that it is pointer?
The function signature func MyFuncReader(r IReader) doesn't tell me, that a pointer or a value was passed the func?
Samples
Full Sample with interface https://play.golang.org/p/1Db1Jybp0rP
Full Sample without interface https://play.golang.org/p/nPtu09yhe0C
If the return type of a function is an interface type, you may return any values that implement that interface. Spec: Return statements:
The return value or values may be explicitly listed in the "return" statement. Each expression must be single-valued and assignable to the corresponding element of the function's result type.
In your first example Reader has methods with pointer receiver, so only a pointer to Reader (that is *Reader) implements the IReader interface. So you have to return &Reader{}.
If your function has a return type of a concrete type, you have to return a value of that exact concrete type, you can't return a value of a pointer to that type.
When the return type is a Reader
func NewReader() Reader {
return &Reader{} // cannot use &Reader literal (type *Reader) as type Reader in return argument
}
you cannot use a pointer to a Reader type in place of a Reader type. The reason being they are just not of the same type.
When you use an interface like IReader as a return type as in
func NewReader() IReader {
return &Reader{}
}
it basically means that any type implementing the methods of the IReader interface will classify as a type implementing that interface and thus will be acceptable. Since the type *Reader implements the IReader type in your example, it is an acceptable return value of the NewReader function here. That means if I introduce a new type which implements this interface, such as,
type dummy int
func (d dummy) GetCount() int {
return d
}
func (d dummy) IncreaseCount() {
fmt.Println("Increased count: %d", d)
}
then I can do something like
func NewReader() IReader {
var d dummy
d = 5
return d
}
and it would still work. The underlying type of this returned value on checking using the reflect package will be dummy.

Golang custom handler for server

I want to use a custom method on http.ListenAndServe
Here is what I have
http.ListenAndServe(":8000", ErrorHandler)
func ErrorHandler(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
h.ServeHTTP(w, r)
})
}
Error
cannot use ErrorHandler (type func(http.Handler) http.Handler) as type http.Handler in argument to http.ListenAndServe:
func(http.Handler) http.Handler does not implement http.Handler (missing ServeHTTP method)
How can I add a custom method to ListenAndServe?
Your ErrorHandler(h http.Handler) http.Handler func is basically just "middleware" and not a real handler. It takes a handler h and returns a new handler. http.StripPrefix is an example of such "middleware".
If you don't want middleware, but just a handler then you need to define your function a little differently:
func ErrorHandler(w http.ResponseWriter, r *http.Request) {
// do stuff with r and w
}
Now you can pass your ErrorHandler to ListenAndServe although you still need to cast it to the proper http.Handler type like so:
http.ListenAndServe(":8000", http.HandlerFunc(ErrorHandler))
http.HandlerFunc is an adapter that turns a function, if it has the right signature, into an http.Handler.
Finally, if you don't like the casting, you'll need to define a type instead of a just a function and you'll need to define a method on that type that is required for it to satisfy the http.Handler interface type.
type ErrorHandler struct{}
func (h *ErrorHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// do stuff with r and w
}
http.ListenAndServe(":8080", &ErrorHandler{})
Read more about it here https://golang.org/pkg/net/http/#Handler

Interfaces stored as value; Methods unable to update struct fields

I have a tool that I'm writing that exposes some functions that pull information out of a static database to several scripting languages that I'm embedding into the tool.
I thought; "Hey sounds like a nice use case for interfaces". So I defined an interface like so in my package scripting
type ScriptingLang interface {
RunScript(filename string) error
RunString(s string) error
Interpreter() error
Init() error
IsInit() bool
}
Then I store a map of them so I can look them up by a string defined like so in a different package.
var ScriptingLangs = make(map[string]scripting.ScriptingLang)
and a function to register them. Also some little helper functions like
func RunString(lang, s string) error {
if v, ok := ScriptingLangs[lang]; ok {
if !v.IsInit() {
v.Init()
}
return v.RunString(s)
} else {
return NoSuchLangErr
}
return nil
}
The problem that I ran into is it seams that interfaces can't have methods with pointer receivers. As a result my Lua struct that implements ScriptingLang isn't able to save it's *state because it's stored in ScriptingLangs.
I've tried updating the value stored in the map at the end of functions that save state and it didn't update the value.
To my understanding you shouldn't use pointers of interfaces so what are my options here? I would like to really keep the interfaces so I can do some neat stuff with git submodules.
A minimal example of my problem:
package main
import (
"fmt"
)
type ScriptingLang interface {
DoString(s string) error
Init() error
}
type Lua struct {
state string
}
func (l Lua) DoString(s string) error {
fmt.Printf("Doing '%v' with state '%v'\n", s, l.state)
return nil
}
func (l Lua) Init() error {
l.state = "Inited"
return nil
}
var lang ScriptingLang
func main() {
lang = Lua{}
lang.Init()
lang.DoString("Stuff")
}
If you want to mutate state, you need a pointer receiver, and your Init method doesn't have one. The fact that you're storing the value inside an interface makes no difference.
In your minimal(-ish) example, change the Init method (and any method that updates state) to have a pointer receiver, and point a pointer inside the interface and everything works:
func (l *Lua) Init() error {
l.state = "Inited"
return nil
}
...
func main() {
lang = &Lua{}
lang.Init()
lang.DoString("Stuff")
}
This article might help: http://jordanorelli.com/post/32665860244/how-to-use-interfaces-in-go

Why a pointer needs to be returned when the return type is actually error?

I am reading the article Error handling and Go, and don't quite understand why a pointer (&errorString{text}) has to be returned when the return type is actually error?
My understanding is error is an interface, and errorString implements the interface, therefore, return errorString is also okay (but it is not the case).
// New returns an error that formats as the given text.
func New(text string) error {
return &errorString{text}
}
errorString implementation
// errorString is a trivial implementation of error.
type errorString struct {
s string
}
func (e *errorString) Error() string {
return e.s
}
Because error interface for errorString is implemented for a pointer (func (e *errorString) Error()), if it was implemented like below you would return the value directly:
func (e errorString) Error() string {
return e.s
}

map[Task]int64 where Task is an interface

Let's say I define the following interface in a Go library:
type Task interface {
Do() error
}
func Register(task Task) { ... }
func GetId(task Task) int64 { ... }
In Register(), the library associates a unique int64 with each task instance. GetId() must return the identifier for the given task.
My initial idea was to store the association as a map[Task]int64. This seems to work fine, but I was told that it would break if an object implementing Task was not equality-comparable (for example, a struct containing a map). I still need to check if this is true.
I was going to try and use a slice of struct { task Task; id int64 } instead and just iterate over it, but that would still require equality comparable Task instances. And AFAIU there is no identity comparison in Go.
How can I have a robust mapping from Task instances to their ID?
EDIT: Both solutions proposed so far work, but they have the disadvantage that every Task implementation has to include some repetitive code to handle the IDs. I could provide that code in a TaskBase struct that could be embedded, but ideally I would prefer a solution that doesn't require implementations to even know about the IDs (they are internal to the library and have no meaning outside of it).
A more complete example: http://play.golang.org/p/1RzDiw7F9t
package main
import (
"fmt"
"math/rand"
)
type Task interface {
Do() error
ID() int64
}
type XTask struct {
id int64
// other stuff
}
func NewXTask( /*task parameters...*/) *XTask {
t := &XTask{ /*initialize members*/}
t.id = Register(t)
// possibly more initialization...
return t
}
func (t *XTask) Do() error { return nil } // stub
func (t *XTask) ID() int64 { return t.id }
var taskRegistry = map[int64]Task{}
func Register(t Task) int64 {
var id int64
for {
id = rand.Int63()
if _, exists := taskRegistry[id]; !exists {
break
}
}
taskRegistry[id] = t
return id
}
func main() {
t1 := NewXTask()
t2 := NewXTask()
fmt.Printf("%x\n", t1.ID())
fmt.Printf("%x\n", t2.ID())
}
I used an ID method as Daniel suggested, and I turned the map backwards from the way you had it. This is because the Task objects know their own ID, so a map from Task to ID is not needed. A map from ID to task however, is useful for guaranteeing uniqueness. It might come in handy some other time if you find yourself with only an ID and you need the corresponding Task object.
Also note this example is not goroutine-safe. If you need that you will have to add synchronization.

Resources