redirect.go 1.2 KB

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