diff --git a/http.go b/http.go index 27d6e06..2cb8e09 100644 --- a/http.go +++ b/http.go @@ -7,6 +7,7 @@ import ( "io/ioutil" "net" "net/http" + "net/url" "os/user" "strings" @@ -14,29 +15,36 @@ import ( "go.wit.com/log" ) -func (f *Forge) HttpPost(url string, data []byte) ([]byte, error) { +func (f *Forge) HttpPost(base string, route string, data []byte) ([]byte, error) { + // Fix using url.JoinPath (Best Practice) + baseURL, _ := url.Parse(f.forgeURL) // "http://forge.grid.wit.com:2520") + finalURL := baseURL.JoinPath(route) // Correctly produces ...:2520/patches + 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) + req, err = http.NewRequest(http.MethodPost, finalURL.String(), bytes.NewBuffer(data)) + if req == nil { + return nil, err + } usr, _ := user.Current() req.Header.Set("author", usr.Username) req.Header.Set("hostname", f.hostname) + return rawHttpPost(req) +} + +func rawHttpPost(req *http.Request) ([]byte, error) { 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 } diff --git a/patchset.Get.go b/patchset.Get.go index c650a82..5780fab 100644 --- a/patchset.Get.go +++ b/patchset.Get.go @@ -8,9 +8,7 @@ import ( // retrieves current patches from forge func (f *Forge) GetPatches() error { - url := f.forgeURL + "GetPatchsets" - log.Info("GetPatchsets() url", url) - body, err := f.HttpPost(url, nil) + body, err := f.HttpPost("junk", "GetPatchsets", nil) if err != nil { log.Info("httpPost() failed:", err) return err diff --git a/patchset.Send.go b/patchset.Send.go index 31e10ef..ab79718 100644 --- a/patchset.Send.go +++ b/patchset.Send.go @@ -11,6 +11,27 @@ import ( "go.wit.com/log" ) +func (f *Forge) SendPatches(what string, p *Patches) (*Patches, error) { + route := "/patches/" + what + data, err := p.Marshal() + if err != nil { + return nil, err + } + log.Infof("pb: len=%d, err=%v\n", len(data), err) + newdata, err := f.HttpPost("rm this", route, data) + if err != nil { + return nil, err + } + if newdata == nil { + return nil, err + } + if len(newdata) == 0 { + return nil, err + } + log.Info("TODO: Unmarshal() to patches", len(newdata)) + return nil, err +} + // makes a new patches protobuf. These are all the patches on your machine. func NewPatches() *Patches { x := new(Patches) @@ -47,19 +68,18 @@ func (f *Forge) SubmitDevelPatchSet(name string) (*Patchset, error) { } func (f *Forge) submitPatchset(pset *Patchset) error { - var url string - url = f.forgeURL + "patchset" msg, err := pset.Marshal() if err != nil { log.Info("proto.Marshal() failed:", err) return err } log.Info("proto.Marshal() msg len", len(msg)) - body, err := f.HttpPost(url, msg) + body, err := f.HttpPost("rm this", "patchset", msg) if err != nil { log.Info("httpPost() failed:", err) return err } + log.Info("HTTP: proto.Marshal() sent", len(msg), "ok and got back", len(body)) newpb := NewPatches() if err := newpb.Unmarshal(body); err != nil { @@ -83,19 +103,18 @@ func (f *Forge) submitPatchset(pset *Patchset) error { } func (f *Forge) SubmitPatchesNew(pset *Patches, urlpath string) (*Patches, error) { - var url string - url = f.forgeURL + "oldpatchset" msg, err := pset.Marshal() if err != nil { log.Info("proto.Marshal() failed:", err) return nil, err } log.Info("proto.Marshal() msg len", len(msg)) - body, err := f.HttpPost(url, msg) + body, err := f.HttpPost("rm this", urlpath, msg) if err != nil { log.Info("httpPost() failed:", err) return nil, err } + log.Info("HTTP: proto.Marshal() sent", len(msg), "ok and got back", len(body)) newpb := NewPatches() if err := newpb.Unmarshal(body); err != nil { diff --git a/patchset.http.go b/patchset.http.go new file mode 100644 index 0000000..34a9e10 --- /dev/null +++ b/patchset.http.go @@ -0,0 +1,114 @@ +// Copyright 1994-2025 WIT.COM Inc Licensed GPL 3.0 + +package forgepb + +import ( + "bytes" + "net/http" + "net/url" + "os" + "os/user" + + "go.wit.com/log" +) + +func (p *Patches) HttpPostVerbose(baseURL string, route string) (*Patches, error) { + p.PrintTable() + return p.HttpPost(baseURL, route) +} + +func (p *Patches) HttpPost(baseURL string, route string) (*Patches, error) { + // if you ever have "http://www.wit.com//" GO will regect the server recieving it. + // Even though the linux kernel gets the network payload + // also it never gives you an error about that, it just goes away invisably inside GO + tmpURL, _ := url.Parse(baseURL) // "http://forge.grid.wit.com:2520") + finalURL := tmpURL.JoinPath("/patches/", route) // Correctly produces ...:2520/patches + + data, _ := p.Marshal() + + var err error + var req *http.Request + + log.Info("patches PB HttpPost", finalURL.String()) + req, err = http.NewRequest(http.MethodPost, finalURL.String(), bytes.NewBuffer(data)) + if req == nil { + return nil, err + } + + usr, _ := user.Current() + req.Header.Set("author", usr.Username) + hostname, _ := os.Hostname() + req.Header.Set("hostname", hostname) + + newdata, err := rawHttpPost(req) + + newpb := NewPatches() + err = newpb.Unmarshal(newdata) + + log.Infof("patchset PB HttpPost %s sent len(%d) got len(%d)\n", finalURL.String(), p.Len(), newpb.Len()) + return newpb, err +} + +func (p *Patchset) HttpPost(baseURL string, route string) (*Patchset, error) { + // if you ever have "http://www.wit.com//" GO will regect the server recieving it. + // Even though the linux kernel gets the network payload + // also it never gives you an error about that, it just goes away invisably inside GO + tmpURL, _ := url.Parse(baseURL) // "http://forge.grid.wit.com:2520") + finalURL := tmpURL.JoinPath("/patchset/", route) // Correctly produces ...:2520/patches + + data, _ := p.Marshal() + + var err error + var req *http.Request + + log.Info("patchset PB HttpPost", finalURL.String()) + req, err = http.NewRequest(http.MethodPost, finalURL.String(), bytes.NewBuffer(data)) + if req == nil { + return nil, err + } + + usr, _ := user.Current() + req.Header.Set("author", usr.Username) + hostname, _ := os.Hostname() + req.Header.Set("hostname", hostname) + + newdata, err := rawHttpPost(req) + + newpb := new(Patchset) + err = newpb.Unmarshal(newdata) + + log.Infof("patchset PB HttpPost %s sent (%d)bytes got (%d)bytes\n", finalURL.String(), len(data), len(newdata)) + return newpb, err +} + +func (p *Patchsets) HttpPost(baseURL string, route string) (*Patchsets, error) { + // if you ever have "http://www.wit.com//" GO will regect the server recieving it. + // Even though the linux kernel gets the network payload + // also it never gives you an error about that, it just goes away invisably inside GO + tmpURL, _ := url.Parse(baseURL) // "http://forge.grid.wit.com:2520") + finalURL := tmpURL.JoinPath("/patchsets/", route) // Correctly produces ...:2520/patches + + data, _ := p.Marshal() + + var err error + var req *http.Request + + log.Info("patchsets PB HttpPost", finalURL.String()) + req, err = http.NewRequest(http.MethodPost, finalURL.String(), bytes.NewBuffer(data)) + if req == nil { + return nil, err + } + + usr, _ := user.Current() + req.Header.Set("author", usr.Username) + hostname, _ := os.Hostname() + req.Header.Set("hostname", hostname) + + newdata, err := rawHttpPost(req) + + newpb := NewPatchsets() + err = newpb.Unmarshal(newdata) + + log.Infof("patchset PB HttpPost %s sent len(%d) got len(%d)\n", finalURL.String(), p.Len(), newpb.Len()) + return newpb, err +} diff --git a/patchset.proto b/patchset.proto index edcd77d..d0df121 100644 --- a/patchset.proto +++ b/patchset.proto @@ -32,20 +32,20 @@ import "google/protobuf/timestamp.proto"; // Import the well-known type for Time message Patch { string namespace = 1; // the base repo git namespace bytes data = 2; // the raw data of the whole patch - string gH = 3; // after some deliberation, I think I'll just try variable names - string gT = 4; - string gP = 5; - string gs = 6; - string gaI = 7; // that exactly match what git uses. - string gan = 8; - string gae = 9; - string gcI = 10; - string gcn = 11; - string gce = 12; - string gN = 13; - string gGG = 14; - string gGS = 15; - string gGK = 16; + string gH = 3; // Commit Hash (%H) + string gT = 4; // Tree Hash (%T) + string gP = 5; // Parent Hashes (%P) + string gs = 6; // Subject (%s) + string gaI = 7; // Author Date, ISO 8601 format (%aI) + string gan = 8; // Author Name (%an) + string gae = 9; // Author Email (%ae) + string gcI = 10; // Committer Date, ISO 8601 format (%cI) + string gcn = 11; // Committer Name (%cn) + string gce = 12; // Committer Email (%ce) + string gN = 13; // Commit Notes (%N) + string gGG = 14; // GPG Signature, raw (%GG) + string gGS = 15; // GPG Signer Name (%GS) + string gGK = 16; // GPG Key ID (%GK) string newHash = 17; // new hash string state = 18; // the 'state' of the patch string filename = 19; // `autogenpb:unique` `autogenpb:sort`