blob: 7a1f7dc09bd52c3fce1a3448c4abb77e37530e4e [file] [log] [blame]
// Copyright 2018 The Goma Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package backend
import (
"context"
"net/http"
"net/http/httputil"
"net/url"
"path"
pb "go.chromium.org/goma/server/proto/backend"
)
// FromHTTPRPCBackend creates new httprpc backend from cfg.
func FromHTTPRPCBackend(ctx context.Context, cfg *pb.HttpRpcBackend) (HTTPRPC, func(), error) {
target, err := url.Parse(cfg.Target)
if err != nil {
return HTTPRPC{}, func() {}, err
}
return NewHTTPRPC(target), func() {}, nil
}
// HTTPRPC is httprpc backend.
type HTTPRPC struct {
proxy *httputil.ReverseProxy
}
// NewHTTPRPC creates httprpc backend proxies to target (scheme + host).
// target's path etc will be ignored.
func NewHTTPRPC(target *url.URL) HTTPRPC {
return HTTPRPC{
proxy: reverseProxy(target),
}
}
func reverseProxy(target *url.URL) *httputil.ReverseProxy {
// almost same as httputil.NewSingleHostReverseProxy, but
// - don't modify query.
// - rewrite Host header.
return &httputil.ReverseProxy{
Director: func(req *http.Request) {
req.URL.Scheme = target.Scheme
req.URL.Host = target.Host
req.URL.Path = path.Join(target.Path, req.URL.Path)
if _, ok := req.Header["User-Agent"]; !ok {
// explicitly disable User-Agent so it's not set to default value
req.Header.Set("User-Agent", "")
}
req.Host = target.Host
req.Header.Set("Host", target.Host)
},
Transport: http.DefaultClient.Transport,
}
}
// Ping forwards requests to target.
func (h HTTPRPC) Ping() http.Handler {
return h.proxy
}
// Exec forwards requests to target.
func (h HTTPRPC) Exec() http.Handler {
return h.proxy
}
// ByteStream forwards requests to target.
func (h HTTPRPC) ByteStream() http.Handler {
return h.proxy
}
// StoreFile forwards requests to target.
func (h HTTPRPC) StoreFile() http.Handler {
return h.proxy
}
// LookupFile forwards requests to target.
func (h HTTPRPC) LookupFile() http.Handler {
return h.proxy
}
// Execlog forwards requests to target.
func (h HTTPRPC) Execlog() http.Handler {
return h.proxy
}