go-bgp

a collection of golang BGP tools to monitor, archive and serve
git clone git://git.2f30.org/go-bgp.git
Log | Files | Refs | README

commit c0b0f39a016f36b92b2cb314a2b4ad7ac4273a19
parent f36b04125906b8f654a46650d83d7e17caa1e8d5
Author: dsp <dsp@2f30.org>
Date:   Tue Feb 10 20:03:38 -0700

seperating the HTTP api logic in another file. archive/api.go

Diffstat:
archive/api.go | 97+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
archive/archive.go | 97+++++++------------------------------------------------------------------------
2 files changed, 105 insertions(+), 89 deletions(-)
diff --git a/archive/api.go b/archive/api.go @@ -0,0 +1,97 @@ +package archive + +import ( + "net/http" + "net/url" + "errors" + "fmt" + "log" +) + +const ( + GET = "GET" + PUT = "PUT" + POST = "POST" + DELETE = "DELETE" +) + +var ( + errbadreq = errors.New("malformed request") + errbaddate = errors.New("dates should be in a YYYYMMDDHHMM format and start should be earlier than end") + errempty = errors.New("archive empty") + errdate = errors.New("no such date in archive") +) + +type Resource interface { + Get(url.Values) (int, chan reply) + Put(url.Values) (int, chan reply) + Post(url.Values) (int, chan reply) + Delete(url.Values) (int, chan reply) +} + +type ( + GetNotAllowed struct{} + PutNotAllowed struct{} + PostNotAllowed struct{} + DeleteNotAllowed struct{} +) + +func (GetNotAllowed) Get(vals url.Values) (int, chan reply) { + return 405, nil +} + +func (PutNotAllowed) Put(vals url.Values) (int, chan reply) { + return 405, nil +} +func (PostNotAllowed) Post(vals url.Values) (int, chan reply) { + return 405, nil +} +func (DeleteNotAllowed) Delete(vals url.Values) (int, chan reply) { + return 405, nil +} + +type API struct{} + +func (api *API) requestHandlerFunc(resource Resource) http.HandlerFunc { + return func(rw http.ResponseWriter, req *http.Request) { + var ( + datac chan reply + code int + ) + req.ParseForm() + method := req.Method + vals := req.Form + switch method { + case GET: + code, datac = resource.Get(vals) + case PUT: + code, datac = resource.Put(vals) + case POST: + code, datac = resource.Post(vals) + case DELETE: + code, datac = resource.Delete(vals) + } + rw.WriteHeader(code) + if datac != nil { // we got a proper channel to get datafrom + //go func(dc <-chan reply) { // fire a goroutine that will end upon the chan getting closed + for r := range datac { + if r.err == nil { + rw.Write(r.data) + } else { + log.Printf("Error in received from data channel:%s\n", r.err) + rw.Write([]byte(fmt.Sprintf("%s\n", r.err))) + } + } + //}(datac) + } + } +} + +func (api *API) AddResource(resource Resource, path string) { + http.HandleFunc(path, api.requestHandlerFunc(resource)) +} + +func (api *API) Start(port int) { + portstr := fmt.Sprintf(":%d", port) + http.ListenAndServe(portstr, nil) +} diff --git a/archive/archive.go b/archive/archive.go @@ -1,11 +1,8 @@ package archive import ( - "errors" "fmt" "log" - "net/http" - "net/url" //"io/ioutil" //"bytes" "bufio" @@ -20,96 +17,17 @@ import ( "sync" "time" "unicode" + "net/url" ) -const ( - GET = "GET" - PUT = "PUT" - POST = "POST" - DELETE = "DELETE" -) - -var ( - errbadreq = errors.New("malformed request") - errbaddate = errors.New("dates should be in a YYYYMMDDHHMM format and start should be earlier than end") - errempty = errors.New("archive empty") - errdate = errors.New("no such date in archive") -) -type Resource interface { - Get(url.Values) (int, chan reply) - Put(url.Values) (int, chan reply) - Post(url.Values) (int, chan reply) - Delete(url.Values) (int, chan reply) -} -type ( - GetNotAllowed struct{} - PutNotAllowed struct{} - PostNotAllowed struct{} - DeleteNotAllowed struct{} +//constants for archentryfile.ftype +const ( + mrtfile = iota + xmlfile ) -func (GetNotAllowed) Get(vals url.Values) (int, chan reply) { - return 405, nil -} - -func (PutNotAllowed) Put(vals url.Values) (int, chan reply) { - return 405, nil -} -func (PostNotAllowed) Post(vals url.Values) (int, chan reply) { - return 405, nil -} -func (DeleteNotAllowed) Delete(vals url.Values) (int, chan reply) { - return 405, nil -} - -type API struct{} - -func (api *API) requestHandlerFunc(resource Resource) http.HandlerFunc { - return func(rw http.ResponseWriter, req *http.Request) { - var ( - datac chan reply - code int - ) - req.ParseForm() - method := req.Method - vals := req.Form - switch method { - case GET: - code, datac = resource.Get(vals) - case PUT: - code, datac = resource.Put(vals) - case POST: - code, datac = resource.Post(vals) - case DELETE: - code, datac = resource.Delete(vals) - } - rw.WriteHeader(code) - if datac != nil { // we got a proper channel to get datafrom - //go func(dc <-chan reply) { // fire a goroutine that will end upon the chan getting closed - for r := range datac { - if r.err == nil { - rw.Write(r.data) - } else { - log.Printf("Error in received from data channel:%s\n", r.err) - rw.Write([]byte(fmt.Sprintf("%s\n", r.err))) - } - } - //}(datac) - } - } -} - -func (api *API) AddResource(resource Resource, path string) { - http.HandleFunc(path, api.requestHandlerFunc(resource)) -} - -func (api *API) Start(port int) { - portstr := fmt.Sprintf(":%d", port) - http.ListenAndServe(portstr, nil) -} - type reply struct { data []byte err error @@ -138,6 +56,7 @@ type archentryfile struct { path string sdate time.Time sz int64 + ftype int } type timeentryslice []archentryfile @@ -368,7 +287,7 @@ func (fsa *mrtarchive) visit(path string, f os.FileInfo, err error) error { log.Print("time.Parse() failed on file: ", fname, " that should be in fooHHMM format with error: ", errtime) return nil } - fsa.tempentryfiles = append(fsa.tempentryfiles, archentryfile{path: path, sdate: time, sz: f.Size()}) + fsa.tempentryfiles = append(fsa.tempentryfiles, archentryfile{path: path, sdate: time, sz: f.Size(), ftype: mrtfile}) } return nil } @@ -537,7 +456,7 @@ func (fsa *xmlarchive) visit(path string, f os.FileInfo, err error) error { log.Print("time.Parse() failed on file: ", fname, " that should be in fooHHMM format with error: ", errtime) return nil } - fsa.tempentryfiles = append(fsa.tempentryfiles, archentryfile{path: path, sdate: time, sz: f.Size()}) + fsa.tempentryfiles = append(fsa.tempentryfiles, archentryfile{path: path, sdate: time, sz: f.Size(), ftype: xmlfile}) } return nil }