redirect.go 1.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. package cluster
  2. import (
  3. "errors"
  4. "io"
  5. "net/http"
  6. )
  7. // RedirectRequest redirects the request to the specified node
  8. func (c *Cluster) RedirectRequest(
  9. node_id string, request *http.Request,
  10. ) (int, http.Header, io.ReadCloser, error) {
  11. node, ok := c.nodes.Load(node_id)
  12. if !ok {
  13. return 0, nil, nil, errors.New("node not found")
  14. }
  15. ips := c.SortIps(node)
  16. if len(ips) == 0 {
  17. return 0, nil, nil, errors.New("no available ip found")
  18. }
  19. ip := ips[0]
  20. url := "http://" + ip.fullAddress() + request.URL.Path
  21. if request.URL.RawQuery != "" {
  22. url += "?" + request.URL.RawQuery
  23. }
  24. // create a new request
  25. redirectedRequest, err := http.NewRequest(
  26. request.Method,
  27. url,
  28. request.Body,
  29. )
  30. if err != nil {
  31. return 0, nil, nil, err
  32. }
  33. // copy headers
  34. for key, values := range request.Header {
  35. for _, value := range values {
  36. redirectedRequest.Header.Add(key, value)
  37. }
  38. }
  39. client := http.DefaultClient
  40. resp, err := client.Do(redirectedRequest)
  41. if err != nil {
  42. return 0, nil, nil, err
  43. }
  44. return resp.StatusCode, resp.Header, resp.Body, nil
  45. }