1
0
mirror of https://github.com/go-micro/go-micro.git synced 2025-01-05 10:20:53 +02:00
go-micro/api/handler/http/http.go

87 lines
1.6 KiB
Go
Raw Normal View History

2019-06-03 19:44:43 +02:00
// Package http is a http reverse proxy handler
package http
import (
"errors"
"fmt"
"net/http"
"net/http/httputil"
"net/url"
2024-06-04 22:40:43 +02:00
"go-micro.dev/v5/api/handler"
"go-micro.dev/v5/api/router"
"go-micro.dev/v5/selector"
2019-06-03 19:44:43 +02:00
)
const (
2022-10-01 10:50:11 +02:00
// Handler is the name of the handler.
2019-06-03 19:44:43 +02:00
Handler = "http"
)
type httpHandler struct {
options handler.Options
}
func (h *httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
service, err := h.getService(r)
if err != nil {
2022-10-01 10:50:11 +02:00
w.WriteHeader(http.StatusInternalServerError)
2019-06-03 19:44:43 +02:00
return
}
if len(service) == 0 {
2022-10-01 10:50:11 +02:00
w.WriteHeader(http.StatusNotFound)
2019-06-03 19:44:43 +02:00
return
}
rp, err := url.Parse(service)
if err != nil {
2022-10-01 10:50:11 +02:00
w.WriteHeader(http.StatusInternalServerError)
2019-06-03 19:44:43 +02:00
return
}
httputil.NewSingleHostReverseProxy(rp).ServeHTTP(w, r)
}
2022-09-30 16:27:07 +02:00
// getService returns the service for this request from the selector.
2019-06-03 19:44:43 +02:00
func (h *httpHandler) getService(r *http.Request) (string, error) {
var service *router.Route
2019-06-03 19:44:43 +02:00
if h.options.Router != nil {
2019-06-03 19:44:43 +02:00
// try get service from router
s, err := h.options.Router.Route(r)
if err != nil {
return "", err
}
2022-10-01 10:50:11 +02:00
2019-06-03 19:44:43 +02:00
service = s
} else {
// we have no way of routing the request
return "", errors.New("no route found")
}
// create a random selector
next := selector.Random(service.Versions)
2019-06-03 19:44:43 +02:00
// get the next node
s, err := next()
if err != nil {
return "", nil
}
2019-07-08 09:01:42 +02:00
return fmt.Sprintf("http://%s", s.Address), nil
2019-06-03 19:44:43 +02:00
}
func (h *httpHandler) String() string {
return "http"
}
2022-09-30 16:27:07 +02:00
// NewHandler returns a http proxy handler.
2019-06-03 19:44:43 +02:00
func NewHandler(opts ...handler.Option) handler.Handler {
options := handler.NewOptions(opts...)
return &httpHandler{
options: options,
}
}