forgepb/http.go

149 lines
3.3 KiB
Go

// Copyright 1994-2025 WIT.COM Inc Licensed GPL 3.0
package forgepb
import (
"bytes"
"io/ioutil"
"net"
"net/http"
"os/user"
"strings"
"go.wit.com/lib/protobuf/gitpb"
"go.wit.com/log"
)
func (f *Forge) HttpPost(url string, data []byte) ([]byte, error) {
var err error
var req *http.Request
req, err = http.NewRequest(http.MethodPost, url, bytes.NewBuffer(data))
// log.Info("httpPost() with len", len(data), "url", url)
usr, _ := user.Current()
req.Header.Set("author", usr.Username)
req.Header.Set("hostname", f.hostname)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
log.Error(err)
return []byte("client.Do(req) error"), err
}
defer resp.Body.Close()
// log.Info("httpPost() with len", len(data))
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Error(err)
return body, err
}
return body, nil
}
func (f *Forge) LookupPBorig(check *gitpb.Repos) (*gitpb.Repos, error) {
url := f.forgeURL + "lookup"
for repo := range check.IterByFullPath() {
if repo.Namespace == "" {
repo.Namespace = repo.GoInfo.GoPath
}
}
return check.SubmitReposPB(url)
}
func (f *Forge) LookupPB(check *gitpb.Repos) (*gitpb.Repos, error) {
url := f.forgeURL + "lookup"
queryPB := gitpb.NewRepos()
for repo := range check.IterByFullPath() {
ns := repo.Namespace
if ns == "" {
ns = repo.GoInfo.GoPath
}
newr := new(gitpb.Repo)
newr.Namespace = ns
queryPB.AppendByNamespace(newr)
}
return queryPB.SubmitReposPB(url)
}
func (f *Forge) UpdatePB(check *gitpb.Repos) (*gitpb.Repos, error) {
url := f.forgeURL + "update"
queryPB := gitpb.NewRepos()
for repo := range check.IterByFullPath() {
ns := repo.Namespace
if ns == "" {
ns = repo.GoInfo.GoPath
}
newr := new(gitpb.Repo)
newr.Namespace = ns
queryPB.AppendByNamespace(newr)
}
return queryPB.SubmitReposPB(url)
}
// HTTPRequestToProto converts an *http.Request to our custom HttpRequest protobuf message.
func (pb *Patches) AddHttpToPB(r *http.Request) error {
if pb == nil {
return log.Errorf("AddHttpToPB() pb was nil")
}
// Convert the header map. http.Header is a map[string][]string.
// We'll just take the first value for each header for simplicity.
headers := make(map[string]string)
for name, values := range r.Header {
if len(values) > 0 {
headers[name] = strings.Join(values, "\n")
}
}
pb.HttpRequest = &Patches_HttpRequest{
Method: r.Method,
Url: r.URL.String(),
Proto: r.Proto,
Headers: headers,
RemoteAddr: getClientIP(r),
Host: r.Host,
Hostname: r.Header.Get("hostname"),
}
return nil
}
func getIpSimple(r *http.Request) string {
host, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
log.Printf("could not split host port: %v", err)
return r.RemoteAddr // Fallback
}
return host
}
// getClientIP inspects the request for common headers to find the true client IP.
func getClientIP(r *http.Request) string {
// Caddy sets the X-Forwarded-For header.
if forwardedFor := r.Header.Get("X-Forwarded-For"); forwardedFor != "" {
// The header can be a comma-separated list of IPs. The first one is the original client.
ips := strings.Split(forwardedFor, ",")
return strings.TrimSpace(ips[0])
}
// Fallback to RemoteAddr if the header is not present.
host, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
return r.RemoteAddr
}
return host
}