api.go (2252B)
1 package archive 2 3 import ( 4 "errors" 5 "fmt" 6 "log" 7 "net/http" 8 "net/url" 9 ) 10 11 const ( 12 GET = "GET" 13 PUT = "PUT" 14 POST = "POST" 15 DELETE = "DELETE" 16 ) 17 18 var ( 19 errbadreq = errors.New("malformed request") 20 errbaddate = errors.New("dates should be in a YYYYMMDDHHMM format and start should be earlier than end") 21 errempty = errors.New("archive empty") 22 errdate = errors.New("no such date in archive") 23 errbadtype = errors.New(fmt.Sprintf("Supported file types:%v", ftypestrings[1:ftypesize-1])) 24 ) 25 26 type Resource interface { 27 Get(url.Values) (int, chan reply) 28 Put(url.Values) (int, chan reply) 29 Post(url.Values) (int, chan reply) 30 Delete(url.Values) (int, chan reply) 31 } 32 33 type ( 34 GetNotAllowed struct{} 35 PutNotAllowed struct{} 36 PostNotAllowed struct{} 37 DeleteNotAllowed struct{} 38 ) 39 40 func (GetNotAllowed) Get(vals url.Values) (int, chan reply) { 41 return 405, nil 42 } 43 44 func (PutNotAllowed) Put(vals url.Values) (int, chan reply) { 45 return 405, nil 46 } 47 func (PostNotAllowed) Post(vals url.Values) (int, chan reply) { 48 return 405, nil 49 } 50 func (DeleteNotAllowed) Delete(vals url.Values) (int, chan reply) { 51 return 405, nil 52 } 53 54 type API struct{} 55 56 func (api *API) requestHandlerFunc(resource Resource) http.HandlerFunc { 57 return func(rw http.ResponseWriter, req *http.Request) { 58 var ( 59 datac chan reply 60 code int 61 ) 62 req.ParseForm() 63 method := req.Method 64 vals := req.Form 65 switch method { 66 case GET: 67 code, datac = resource.Get(vals) 68 case PUT: 69 code, datac = resource.Put(vals) 70 case POST: 71 code, datac = resource.Post(vals) 72 case DELETE: 73 code, datac = resource.Delete(vals) 74 } 75 rw.WriteHeader(code) 76 if datac != nil { // we got a proper channel to get datafrom 77 //go func(dc <-chan reply) { // fire a goroutine that will end upon the chan getting closed 78 for r := range datac { 79 if r.err == nil { 80 rw.Write(r.data) 81 } else { 82 log.Printf("Error in received from data channel:%s\n", r.err) 83 rw.Write([]byte(fmt.Sprintf("%s\n", r.err))) 84 } 85 } 86 //}(datac) 87 } 88 } 89 } 90 91 func (api *API) AddResource(resource Resource, path string) { 92 http.HandleFunc(path, api.requestHandlerFunc(resource)) 93 } 94 95 func (api *API) Start(port int) { 96 portstr := fmt.Sprintf(":%d", port) 97 http.ListenAndServe(portstr, nil) 98 }