package application import ( "net/http" "fmt" "strconv" // "io" "caj-larsson/bog/domain" "caj-larsson/bog/integration" ) type Bog struct { mux *http.ServeMux file_service domain.BogFileService address string } func buildFileDataRepository(config FileConfig) domain.FileDataRepository{ fsBogRepo := new(integration.FileSystemBogRepository) fsBogRepo.Root = config.Path return fsBogRepo } func buildUserAgentRepository(config DatabaseConfig) *integration.SQLiteUserAgentRepository{ if config.Backend != "sqlite" { panic("Can only handle sqlite") } return integration.NewSQLiteUserAgentRepository(config.Connection) } func buildHttpMux(file_service domain.BogFileService) *http.ServeMux { mux := http.NewServeMux() mux.HandleFunc("/",func(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/" { fmt.Fprintf(w, "Hi") return } ref := domain.FileReference {r.URL.Path, r.Header["User-Agent"][0]} switch r.Method { case "GET": bog_file, err := file_service.OpenOutFile(ref) if err == domain.ErrNotExists { http.NotFound(w, r) return } if err != nil { panic(err) } http.ServeContent(w, r, bog_file.Path(), bog_file.Modified(), bog_file) case "POST": fallthrough case "PUT": size_str := r.Header["Content-Length"][0] size, err := strconv.ParseInt(size_str, 10, 64) if err != nil { w.WriteHeader(422) return } err = file_service.SaveFile(ref, r.Body, size) if err != nil { panic(err) } } return }) return mux } func New(config *Configuration) *Bog { b := new(Bog) b.address = config.bindAddress() fsBogRepo := buildFileDataRepository(config.File) uaRepo := buildUserAgentRepository(config.Database) file_service := domain.NewBogFileService( uaRepo, fsBogRepo, config.Quota.DefaultSizeBytes(), config.Quota.DefaultDuration(), ) b.mux = buildHttpMux(file_service) return b } func (b *Bog) Run() { http.ListenAndServe(b.address, b.mux) }