Created
September 25, 2021 11:41
-
-
Save Ompluscator/9bd4b552b0bd900ddf3f24c011fd244f to your computer and use it in GitHub Desktop.
Go Proxy Full
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"archive/zip" | |
"bytes" | |
"encoding/json" | |
"fmt" | |
"io" | |
"io/ioutil" | |
"log" | |
"net/http" | |
"strconv" | |
"strings" | |
"time" | |
"github.com/gorilla/mux" | |
"github.com/xanzy/go-gitlab" | |
"gopkg.in/yaml.v2" | |
) | |
var gitlabProjectMap = map[string]int{} | |
var client *gitlab.Client | |
func list(w http.ResponseWriter, r *http.Request) { | |
module := mux.Vars(r)["module"] | |
project, ok := gitlabProjectMap[module] | |
if !ok { | |
http.NotFound(w, r) | |
return | |
} | |
tags, _, err := client.Tags.ListTags(project, &gitlab.ListTagsOptions{}) | |
if err != nil { | |
http.Error(w, err.Error(), http.StatusInternalServerError) | |
return | |
} | |
result := make([]string, len(tags)) | |
for index, tag := range tags { | |
result[index] = tag.Name | |
} | |
fmt.Print(w, strings.Join(result, "\n")) | |
} | |
func version(w http.ResponseWriter, r *http.Request) { | |
module := mux.Vars(r)["module"] | |
project, ok := gitlabProjectMap[module] | |
if !ok { | |
http.NotFound(w, r) | |
return | |
} | |
version := mux.Vars(r)["version"] | |
commit, _, err := client.Commits.GetCommit(project, version) | |
if err != nil { | |
http.Error(w, err.Error(), http.StatusInternalServerError) | |
return | |
} | |
finalVersion := fmt.Sprintf( | |
"v0.0.0-%s-%s", | |
commit.CommittedDate.Format("20060102150405"), | |
commit.ID[0:12], | |
) | |
json.NewEncoder(w).Encode(map[string]string{ | |
"Version": finalVersion, | |
"Time": commit.CommittedDate.Format(time.RFC3339), | |
}) | |
} | |
func mod(w http.ResponseWriter, r *http.Request) { | |
module := mux.Vars(r)["module"] | |
project, ok := gitlabProjectMap[module] | |
if !ok { | |
http.NotFound(w, r) | |
return | |
} | |
finalVersion := mux.Vars(r)["version"] | |
parts := strings.Split(finalVersion, "-") | |
if len(parts) != 3 { | |
http.Error(w, "invalid version", http.StatusInternalServerError) | |
return | |
} | |
version := parts[2] | |
content, _, err := client.RepositoryFiles.GetRawFile(project, "go.mod", &gitlab.GetRawFileOptions{ | |
Ref: &version, | |
}) | |
if err != nil { | |
http.Error(w, err.Error(), http.StatusInternalServerError) | |
return | |
} | |
io.WriteString(w, string(content)) | |
} | |
func archive(w http.ResponseWriter, r *http.Request) { | |
module := mux.Vars(r)["module"] | |
project, ok := gitlabProjectMap[module] | |
if !ok { | |
http.NotFound(w, r) | |
return | |
} | |
finalVersion := mux.Vars(r)["version"] | |
parts := strings.Split(finalVersion, "-") | |
if len(parts) != 3 { | |
http.Error(w, "invalid version", http.StatusInternalServerError) | |
return | |
} | |
version := parts[2] | |
format := "zip" | |
content, _, err := client.Repositories.Archive(project, &gitlab.ArchiveOptions{ | |
Format: &format, | |
SHA: &version, | |
}) | |
if err != nil { | |
http.Error(w, err.Error(), http.StatusInternalServerError) | |
return | |
} | |
reader, err := zip.NewReader(bytes.NewReader(content), int64(len(content))) | |
if err != nil { | |
http.Error(w, err.Error(), http.StatusInternalServerError) | |
return | |
} | |
buffer := bytes.NewBuffer([]byte{}) | |
writer := zip.NewWriter(buffer) | |
for _, item := range reader.File { | |
parts := strings.Split(item.Name, "/") | |
if len(parts) == 0 { | |
continue | |
} | |
directory := fmt.Sprintf("%s@%s", module, finalVersion) | |
file, err := writer.Create(strings.Replace(item.Name, parts[0], directory, 1)) | |
if err != nil { | |
http.Error(w, err.Error(), http.StatusInternalServerError) | |
return | |
} | |
closer, err := item.Open() | |
if err != nil { | |
http.Error(w, err.Error(), http.StatusInternalServerError) | |
return | |
} | |
data, err := ioutil.ReadAll(closer) | |
if err != nil { | |
http.Error(w, err.Error(), http.StatusInternalServerError) | |
return | |
} | |
closer.Close() | |
_, err = file.Write(data) | |
if err != nil { | |
http.Error(w, err.Error(), http.StatusInternalServerError) | |
return | |
} | |
} | |
err = writer.Close() | |
if err != nil { | |
http.Error(w, err.Error(), http.StatusInternalServerError) | |
return | |
} | |
w.Header().Set("Content-Length", strconv.FormatInt(int64(buffer.Len()), 10)) | |
io.WriteString(w, buffer.String()) | |
} | |
func init() { | |
var err error | |
client, err = gitlab.NewClient("<PRIVATE TOKEN>", gitlab.WithBaseURL("<GITLAB URL>")) | |
if err != nil { | |
log.Fatal(err) | |
} | |
data, err := ioutil.ReadFile("mappings.yml") | |
if err != nil { | |
log.Fatal(err) | |
} | |
err = yaml.Unmarshal(data, struct { | |
Modules *map[string]int `yaml:"modules"` | |
}{ | |
Modules: &gitlabProjectMap, | |
}) | |
if err != nil { | |
log.Fatal(err) | |
} | |
} | |
func main() { | |
router := mux.NewRouter() | |
router.HandleFunc("/{module:.+}/@v/list", list).Methods(http.MethodGet) | |
router.HandleFunc("/{module:.+}/@v/{version}.info", version).Methods(http.MethodGet) | |
router.HandleFunc("/{module:.+}/@v/{version}.mod", mod).Methods(http.MethodGet) | |
router.HandleFunc("/{module:.+}/@v/{version}.zip", archive).Methods(http.MethodGet) | |
http.ListenAndServe(":8080", router) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
modules: | |
company.com/project-a: 1 | |
company.com/project-b: 2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment