github.com/hoffie/larasync@v0.0.0-20151025221940-0384d2bddcef/api/server/nib.go (about) 1 package server 2 3 import ( 4 "fmt" 5 "io" 6 "net/http" 7 "os" 8 "strconv" 9 10 "github.com/gorilla/mux" 11 12 "github.com/hoffie/larasync/api" 13 "github.com/hoffie/larasync/helpers/bincontainer" 14 repositoryModule "github.com/hoffie/larasync/repository" 15 ) 16 17 // nibGet returns the NIB data for a given repository and a given UUID. 18 func (s *Server) nibGet(rw http.ResponseWriter, req *http.Request) { 19 vars := mux.Vars(req) 20 repositoryName := vars["repository"] 21 22 repository, err := s.rm.Open(repositoryName) 23 if err != nil { 24 errorJSONMessage(rw, "Internal Error", http.StatusInternalServerError) 25 return 26 } 27 28 nibID := vars["nibID"] 29 30 Log.Debug(fmt.Sprintf("Repository %s: Requesting NIB with ID %s", repositoryName, nibID)) 31 reader, err := repository.GetNIBReader(nibID) 32 33 if err != nil { 34 rw.Header().Set("Content-Type", "plain/text") 35 if os.IsNotExist(err) { 36 errorText(rw, "Not found", http.StatusNotFound) 37 } else { 38 errorText(rw, "Internal Error", http.StatusInternalServerError) 39 } 40 return 41 } 42 43 defer reader.Close() 44 45 rw.Header().Set("Content-Type", "application/octet-stream") 46 attachCurrentTransactionHeader(repository, rw) 47 rw.WriteHeader(http.StatusOK) 48 io.Copy(rw, reader) 49 } 50 51 // nibPut is the handler which adds a NIB to the repository. 52 func (s *Server) nibPut(rw http.ResponseWriter, req *http.Request) { 53 vars := mux.Vars(req) 54 repositoryName := vars["repository"] 55 56 repository, err := s.rm.Open(repositoryName) 57 if err != nil { 58 errorJSONMessage(rw, "Internal Error", http.StatusInternalServerError) 59 return 60 } 61 62 nibID := vars["nibID"] 63 64 successReturnStatus := http.StatusOK 65 if !repository.HasNIB(nibID) { 66 successReturnStatus = http.StatusCreated 67 } 68 69 Log.Debug(fmt.Sprintf("Repository %s: Adding NIB with ID %s", repositoryName, nibID)) 70 err = repository.AddNIBContent(req.Body) 71 72 if err != nil { 73 if err == repositoryModule.ErrSignatureVerification { 74 Log.Debug(fmt.Sprintf("Repository %s: Signature Verification failed when trying to add NIB with ID %s", repositoryName, nibID)) 75 errorText(rw, "Signature could not be verified", http.StatusUnauthorized) 76 } else if err == repositoryModule.ErrUnMarshalling { 77 Log.Debug(fmt.Sprintf("Repository %s: Unmarshalling failed when trying to add NIB with ID %s", repositoryName, nibID)) 78 errorText(rw, "Could not extract NIB", http.StatusBadRequest) 79 } else if err == repositoryModule.ErrNIBConflict { 80 Log.Debug(fmt.Sprintf("Repository %s: Conflict when trying to add NIB with ID %s", repositoryName, nibID)) 81 errorText(rw, "NIB conflict", http.StatusConflict) 82 } else if repositoryModule.IsNIBContentMissing(err) { 83 Log.Debug(fmt.Sprintf("Repository %s: Contents of NIB not in Server when trying to add NIB with ID %s", repositoryName, nibID)) 84 nibError := err.(*repositoryModule.ErrNIBContentMissing) 85 jsonError := &api.ContentIDsJSONError{} 86 jsonError.Error = nibError.Error() 87 jsonError.Type = "missing_content_ids" 88 jsonError.MissingContentIDs = nibError.MissingContentIDs() 89 errorJSON(rw, jsonError, http.StatusPreconditionFailed) 90 } else { 91 Log.Warn(fmt.Sprintf("Repository %s: Internal Error when trying to add NIB with ID %s. %s", repositoryName, nibID, err.Error())) 92 errorText(rw, "Internal Error", http.StatusInternalServerError) 93 } 94 return 95 } 96 97 rw.Header().Set("Location", req.URL.String()) 98 attachCurrentTransactionHeader(repository, rw) 99 rw.WriteHeader(successReturnStatus) 100 } 101 102 func (s *Server) nibList(rw http.ResponseWriter, req *http.Request) { 103 vars := mux.Vars(req) 104 repositoryName := vars["repository"] 105 106 repository, err := s.rm.Open(repositoryName) 107 if err != nil { 108 errorText(rw, "Internal Error", http.StatusInternalServerError) 109 return 110 } 111 112 values := req.URL.Query() 113 fromRepositoryIDString, ok := values["from-transaction-id"] 114 115 var nibChannel <-chan []byte 116 if !ok { 117 Log.Debug(fmt.Sprintf("Repository %s:, Requesting complete NIB list", repositoryName)) 118 nibChannel, err = repository.GetAllNIBBytes() 119 } else { 120 afterTransactionID, err := strconv.ParseInt(fromRepositoryIDString[0], 10, 64) 121 if err != nil { 122 errorText( 123 rw, 124 fmt.Sprintf( 125 "from-transaction-id %s is not a valid transaction id", 126 fromRepositoryIDString, 127 ), 128 http.StatusBadRequest, 129 ) 130 Log.Debug(fmt.Sprintf("Repository %s: Error while trying to extract transaction id of %s", repositoryName, fromRepositoryIDString[0])) 131 return 132 } 133 Log.Debug(fmt.Sprintf("Repository %s: Requesting NIB list after transaction id %d", repositoryName, afterTransactionID)) 134 nibChannel, err = repository.GetNIBBytesFrom(afterTransactionID) 135 } 136 137 if err != nil { 138 Log.Warn(fmt.Sprintf("Repository %s: Could not extract nib data.", repositoryName)) 139 errorText(rw, "Could not extract data", http.StatusInternalServerError) 140 return 141 } 142 143 header := rw.Header() 144 header.Set("Content-Type", "application/octet-stream") 145 attachCurrentTransactionHeader(repository, rw) 146 147 rw.WriteHeader(http.StatusOK) 148 149 encoder := bincontainer.NewEncoder(rw) 150 for nibData := range nibChannel { 151 encoder.WriteChunk(nibData) 152 } 153 }