Skip to content

Instantly share code, notes, and snippets.

@Ompluscator
Created September 25, 2021 11:41
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Ompluscator/9bd4b552b0bd900ddf3f24c011fd244f to your computer and use it in GitHub Desktop.
Save Ompluscator/9bd4b552b0bd900ddf3f24c011fd244f to your computer and use it in GitHub Desktop.
Go Proxy Full
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)
}
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