// 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 }