-
-
Save tullo/82c717f8239a9c240ee41015b06912ac 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