package main
import (
"io"
"net/http"
)const (
REPO = "repo" // repo where the file is located
ID = "id" // a sha in Git, nodeid in Mercurial, etc.
)// Sends a response containing the file blob, if it exists// Currently uses request params - to change to path params?// i.e. /file/repo/id instead of// /file?repo=repo1&id=sha1shafunc GetFile(w http.ResponseWriter, r *http.Request) {
repoName := r.URL.Query().Get(REPO)
id := r.URL.Query().Get(ID)
if len(repoName) != 0 && len(id) != 0 {
//GetRepository(repoName).GetFile(id)
repo := GetRepository(repoName)
w.Header().Set("Content-Type", "application/octet-stream")
w.Write(repo.GetFile(id))
}
}// Sends a true or false response depending on whether the file exists// Currently uses request params - to change to path params?// i.e. /file/repo/name/id instead of// /file?repo=repo1&id=sha1func FileExists(w http.ResponseWriter, r *http.Request
Web Service
package main
import (
"net/http"
"log"
)func main() {
// this calls loadConfig in util.go.
// I might put util.go in another package in the near future
LoadConfig()
// this calls service.go's route to handle the routing.
Route()
// Start the server on port 8888
err := http.ListenAndServe(":8888", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}Main
| Util | |
|---|---|
| 1 | package main |
| 2 | |
| 3 | import ( |
| 4 | "encoding/json" |
| 5 | "log" |
| 6 | "io/ioutil" |
| 7 | ) |
| 8 | |
| 9 | var Repos []Repository |
| 10 | |
| 11 | // Loads the configuration file. The configuration file is assumed to |
| 12 | // be a json file. Currently just loads all repositories with their |
| 13 | // corresponding file paths. It also reads in the SCM type, which |
| 14 | // I intend to identify through the program in the future without |
| 15 | // needing it to be specified in the config |
| 16 | func LoadConfig() { |
| 17 | const CONF_PATH = "config.json" |
| 18 | |
| 19 | type JsonRepo struct { |
| 20 | Name string |
| 21 | Path string |
| 22 | Scm string |
| 23 | } |
| 24 | |
| 25 | type Configuration struct { |
| 26 | Repositories []JsonRepo |
| 27 | } |
| 28 | |
| 29 | var conf Configuration |
| 30 | |
| 31 | content, err := ioutil.ReadFile(CONF_PATH) |
| 32 | if err != nil { |
| 33 | log.Fatal("ReadFile: ", err) |
| 34 | } |
| 35 | |
| 36 | if json.Unmarshal(content, &conf) != nil { |
| 37 | log.Fatal("Unmarshal: ", err) |
| 38 | } |
| 39 | |
| 40 | for _, r := range conf.Repositories { |
| 41 | switch r.Scm { |
| 42 | // to implement more later.. for now it's just git |
| 43 | case "git": |
| 44 | Repos = append(Repos, |
| 45 | &GitRepository { RepositoryInfo { r.Name, r.Path } }) |
| 46 | } |
| 47 | } |
| 48 | } |
| 49 | |
| 50 | // Gets the repository by name - assuming name uniqueness right now |
| 51 | // based on the config file, likely will need a way to reinforce this later. |
| 52 | func GetRepository(name string) Repository { |
| 53 | // Simply iterating through the array - shouldn't be an issue |
| 54 | // if we aren't assuming clients have hundreds of repositories. |
| 55 | // If it is, I will use a map implementation instead. |
| 56 | var repo Repository |
| 57 | |
| 58 | for _, r := range Repos { |
| 59 | if r.GetName() == name { |
| 60 | repo = r |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | return repo |
| 65 | } |