@@ -21,6 +21,7 @@ package http
2121
2222import (
2323 "archive/tar"
24+ "bytes"
2425 "encoding/json"
2526 "errors"
2627 "fmt"
@@ -290,6 +291,95 @@ func (s *Server) HandleDelete(w http.ResponseWriter, r *Request) {
290291 fmt .Fprint (w , newKey )
291292}
292293
294+ func (s * Server ) HandlePostResource (w http.ResponseWriter , r * Request ) {
295+ var outdata string
296+ if r .uri .Path != "" {
297+ frequency , err := strconv .ParseUint (r .uri .Path , 10 , 64 )
298+ if err != nil {
299+ s .BadRequest (w , r , fmt .Sprintf ("Cannot parse frequency parameter: %v" , err ))
300+ return
301+ }
302+ key , err := s .api .ResourceCreate (r .Context (), r .uri .Addr , frequency )
303+ if err != nil {
304+ s .Error (w , r , fmt .Errorf ("Resource creation failed: %v" , err ))
305+ return
306+ }
307+ outdata = key .Hex ()
308+ }
309+
310+ data , err := ioutil .ReadAll (r .Body )
311+ if err != nil {
312+ s .Error (w , r , err )
313+ return
314+ }
315+ _ , _ , _ , err = s .api .ResourceUpdate (r .Context (), r .uri .Addr , data )
316+ if err != nil {
317+ s .Error (w , r , fmt .Errorf ("Update resource failed: %v" , err ))
318+ return
319+ }
320+
321+ if outdata != "" {
322+ w .Header ().Add ("Content-type" , "text/plain" )
323+ w .WriteHeader (http .StatusOK )
324+ fmt .Fprint (w , outdata )
325+ return
326+ }
327+ w .WriteHeader (http .StatusOK )
328+ }
329+
330+ // Retrieve mutable resource updates:
331+ // bzz-resource://<id> - get latest update
332+ // bzz-resource://<id>/<n> - get latest update on period n
333+ // bzz-resource://<id>/<n>/<m> - get update version m of period n
334+ // <id> = ens name or hash
335+ func (s * Server ) HandleGetResource (w http.ResponseWriter , r * Request ) {
336+ s .handleGetResource (w , r , r .uri .Addr )
337+ }
338+
339+ func (s * Server ) handleGetResource (w http.ResponseWriter , r * Request , name string ) {
340+ var params []string
341+ if len (r .uri .Path ) > 0 {
342+ params = strings .Split (r .uri .Path , "/" )
343+ }
344+ var updateKey storage.Key
345+ var period uint64
346+ var version uint64
347+ var data []byte
348+ var err error
349+ now := time .Now ()
350+ log .Debug ("handlegetdb" , "name" , name )
351+ switch len (params ) {
352+ case 0 :
353+ updateKey , data , err = s .api .ResourceLookup (r .Context (), name , 0 , 0 )
354+ case 2 :
355+ version , err = strconv .ParseUint (params [1 ], 10 , 32 )
356+ if err != nil {
357+ break
358+ }
359+ period , err = strconv .ParseUint (params [0 ], 10 , 32 )
360+ if err != nil {
361+ break
362+ }
363+ updateKey , data , err = s .api .ResourceLookup (r .Context (), name , uint32 (period ), uint32 (version ))
364+ case 1 :
365+ period , err = strconv .ParseUint (params [0 ], 10 , 32 )
366+ if err != nil {
367+ break
368+ }
369+ updateKey , data , err = s .api .ResourceLookup (r .Context (), name , uint32 (period ), uint32 (version ))
370+ default :
371+ s .BadRequest (w , r , "Invalid mutable resource request" )
372+ return
373+ }
374+ if err != nil {
375+ s .Error (w , r , fmt .Errorf ("Mutable resource lookup failed: %v" , err ))
376+ return
377+ }
378+ log .Debug ("Found update" , "key" , updateKey )
379+ w .Header ().Set ("Content-Type" , "application/octet-stream" )
380+ http .ServeContent (w , & r .Request , "" , now , bytes .NewReader (data ))
381+ }
382+
293383// HandleGet handles a GET request to
294384// - bzz-raw://<key> and responds with the raw content stored at the
295385// given storage key
@@ -335,7 +425,7 @@ func (s *Server) HandleGet(w http.ResponseWriter, r *Request) {
335425 return api .SkipManifest
336426 })
337427 if entry == nil {
338- s .NotFound (w , r , fmt . Errorf ("Manifest entry could not be loaded" ))
428+ s .NotFound (w , r , errors . New ("Manifest entry could not be loaded" ))
339429 return
340430 }
341431 key = storage .Key (common .Hex2Bytes (entry .Hash ))
@@ -357,7 +447,6 @@ func (s *Server) HandleGet(w http.ResponseWriter, r *Request) {
357447 contentType = typ
358448 }
359449 w .Header ().Set ("Content-Type" , contentType )
360-
361450 http .ServeContent (w , & r .Request , "" , time .Now (), reader )
362451 case r .uri .Hash ():
363452 w .Header ().Set ("Content-Type" , "text/plain" )
@@ -604,6 +693,8 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
604693 case "POST" :
605694 if uri .Raw () || uri .DeprecatedRaw () {
606695 s .HandlePostRaw (w , req )
696+ } else if uri .Resource () {
697+ s .HandlePostResource (w , req )
607698 } else {
608699 s .HandlePostFiles (w , req )
609700 }
@@ -629,6 +720,12 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
629720 s .HandleDelete (w , req )
630721
631722 case "GET" :
723+
724+ if uri .Resource () {
725+ s .HandleGetResource (w , req )
726+ return
727+ }
728+
632729 if uri .Raw () || uri .Hash () || uri .DeprecatedRaw () {
633730 s .HandleGet (w , req )
634731 return
0 commit comments