send.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. // Copyright 2016 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package gensupport
  5. import (
  6. "net/http"
  7. "golang.org/x/net/context"
  8. "golang.org/x/net/context/ctxhttp"
  9. )
  10. // Hook is the type of a function that is called once before each HTTP request
  11. // that is sent by a generated API. It returns a function that is called after
  12. // the request returns.
  13. // Hooks are not called if the context is nil.
  14. type Hook func(ctx context.Context, req *http.Request) func(resp *http.Response)
  15. var hooks []Hook
  16. // RegisterHook registers a Hook to be called before each HTTP request by a
  17. // generated API. Hooks are called in the order they are registered. Each
  18. // hook can return a function; if it is non-nil, it is called after the HTTP
  19. // request returns. These functions are called in the reverse order.
  20. // RegisterHook should not be called concurrently with itself or SendRequest.
  21. func RegisterHook(h Hook) {
  22. hooks = append(hooks, h)
  23. }
  24. // SendRequest sends a single HTTP request using the given client.
  25. // If ctx is non-nil, it calls all hooks, then sends the request with
  26. // ctxhttp.Do, then calls any functions returned by the hooks in reverse order.
  27. func SendRequest(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) {
  28. if ctx == nil {
  29. return client.Do(req)
  30. }
  31. // Call hooks in order of registration, store returned funcs.
  32. post := make([]func(resp *http.Response), len(hooks))
  33. for i, h := range hooks {
  34. fn := h(ctx, req)
  35. post[i] = fn
  36. }
  37. // Send request.
  38. resp, err := ctxhttp.Do(ctx, client, req)
  39. // Call returned funcs in reverse order.
  40. for i := len(post) - 1; i >= 0; i-- {
  41. if fn := post[i]; fn != nil {
  42. fn(resp)
  43. }
  44. }
  45. return resp, err
  46. }