package main import ( "fmt" "net" "net/http" "strings" "go.wit.com/lib/protobuf/forgepb" "go.wit.com/lib/protobuf/gitpb" "go.wit.com/lib/protobuf/httppb" "go.wit.com/log" ) // remove '?' part and trailing '/' func cleanURL(url string) string { url = "/" + strings.Trim(url, "/") return url } 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 } func whoSent(r *http.Request) string { return log.Sprintf("%s\t%s", getClientIP(r), r.Header.Get("hostname")) } func okHandler(w http.ResponseWriter, r *http.Request) { reqPB, err := httppb.ReqToPB(r) if err != nil { log.Info("something crazy err", err) } who := whoSent(r) route := reqPB.Route parts := strings.Split(route, "?") requrl := parts[0] if route == "/" { w.Header().Set("Content-Type", "text") fmt.Fprintf(w, "go.wit.com/apps/utils/forged Version: %s\n", argv.Version()) fmt.Fprintf(w, "\n") return } // used for uptime monitor checking if route == "/uptime" { writeFile(w, "uptime.html") return } log.Warn("forged REQUEST URL =", requrl, "from =", who) if strings.HasPrefix(route, "/repos/") { pb, err := makeReposPB(reqPB) if err != nil { reqPB.Errors = append(reqPB.Errors, log.Sprintf("%v", err)) } result := gitpb.NewRepos() switch route { case "/repos/pull": result = pullRequest(pb, reqPB) case "/repos/add": result = addRequest(pb, reqPB) default: result = pullRequest(pb, reqPB) } if err := result.SendReply(w, reqPB); err != nil { log.Info("Oh well, Send to client failed. err =", err) } // todo: logReq(reqPB) return } if strings.HasPrefix(route, "/patches/") { pb, err := makePatchesPB(reqPB) if err != nil { reqPB.Errors = append(reqPB.Errors, log.Sprintf("%v", err)) } result := forgepb.NewPatches() switch route { case "/patches/new": result = addNewPatches(pb, reqPB) log.Infof("addNewPatches() pb.Len()=%d result.Len()=%d\n", pb.Len(), result.Len()) case "/patches/get": result = sendPendingPatches(pb, reqPB) default: result = addNewPatches(pb, reqPB) } if err := result.SendReply(w, reqPB); err != nil { log.Info("Oh well, Send to client failed. err =", err) } // todo: logReq(reqPB) return } /* if route == "/patchset" { if err := savePatchset(w, reqPB.Body); err != nil { log.Warn("forged /patchset error", err) return } if err := me.forge.SavePatchsets(); err != nil { log.Warn("savePatchsets() failed", err) return } return } if route == "/lookup" { log.Info("doing lookup len(reqPB.Body) =", len(reqPB.Body)) found, err := lookupRepos(reqPB.Body) if err != nil { return } found.SendPB(w) return } */ /* if strings.HasPrefix(route, "/patches/") { pb, err := forgepb.GetPatchesFromHttp(reqPB) if err != nil { log.Info("error converting to patches PB") return } handlePatches(w, pb) return } */ /* if route == "/patchset" { if err := savePatchset(w, reqPB.Body); err != nil { log.Warn("forged /patchset error", err) return } if err := me.forge.SavePatchsets(); err != nil { log.Warn("savePatchsets() failed", err) return } return } if route == "/lookup" { log.Info("doing lookup len(reqPB.Body) =", len(reqPB.Body)) found, err := lookupRepos(reqPB.Body) if err != nil { return } found.SendPB(w) return } if route == "/update" { log.Info("doing update len(reqPB.Body) =", len(reqPB.Body)) found, err := updateRepos(reqPB.Body) if err != nil { return } found.SendPB(w) return } */ /* if route == "/GetPatchsets" || route == "/patchsets/get" { data, err := me.forge.Patchsets.Marshal() if err != nil { log.Info("patchsets.Marshal() to wire failed", err) return } start := time.Now() log.Info("going to w.Write(data) with len", len(data)) w.Write(data) age := shell.FormatDuration(time.Since(start)) log.Printf("Done with xfer in (%s). happy hacking!\n", age) return } if route == "/patchsetget" { filename := r.URL.Query().Get("filename") getPatchset(w, filename) return } */ if route == "/goReference.svg" { w.Header().Set("Content-Type", "image/svg+xml") writeFile(w, "goReference.svg") return } if route == "/skeleton.v2.css" { writeFile(w, "skeleton.v2.css") return } if route == "/favicon.ico" { writeFile(w, "ipv6.png") return } log.Warn("BAD URL =", requrl, "from", who) badurl(w, r.URL.String()) } func writeFile(w http.ResponseWriter, filename string) { // fmt.Fprintln(w, "GOT TEST?") fullname := "resources/" + filename pfile, err := resources.ReadFile(fullname) if err != nil { log.Println("ERROR:", err) // w.Write(pfile) return } var repohtml string repohtml = string(pfile) fmt.Fprintln(w, repohtml) // log.Println("writeFile() found internal file:", filename) } func badurl(w http.ResponseWriter, badurl string) { fmt.Fprintln(w, "") fmt.Fprintln(w, "") fmt.Fprintln(w, "
") fmt.Fprintln(w, " ") fmt.Fprintln(w, " ") fmt.Fprintln(w, " ") fmt.Fprintln(w, " IPv4 IS NOT SUPPORTED