Example #1
0
File: json.go Project: ndlib/bendo
// Open the item having the given key and unserialize it into value.
func (js JSONStore) Open(key string, value interface{}) error {
	r, _, err := js.Store.Open(key)
	if err != nil {
		return err
	}
	defer r.Close()
	dec := json.NewDecoder(store.NewReader(r))
	return dec.Decode(value)
}
Example #2
0
// BundleOpenHandler handles GET requests to "/bundle/open/:key"
func (s *RESTServer) BundleOpenHandler(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	key := ps.ByName("key")

	if s.useTape == false {
		w.WriteHeader(503)
		fmt.Fprintln(w, items.ErrNoStore)
		log.Printf("GET /bundle/open/%s returns 503 - tape disabled", key)
		return
	}

	data, _, err := s.Items.S.Open(key)
	if err != nil {
		fmt.Fprintln(w, err)
		return
	}
	io.Copy(w, store.NewReader(data))
	data.Close()
}
Example #3
0
File: item.go Project: ndlib/bendo
func (s *RESTServer) getblob(w http.ResponseWriter, r *http.Request, id string, bid items.BlobID) {
	key := fmt.Sprintf("%s+%04d", id, bid)
	cacheContents, length, err := s.Cache.Get(key)
	if err != nil {
		w.WriteHeader(500)
		fmt.Fprintln(w, err)
		return
	}
	var src io.Reader
	if cacheContents != nil {
		nCacheHit.Add(1)
		log.Printf("Cache Hit %s", key)
		w.Header().Set("X-Cached", "1")
		defer cacheContents.Close()
		// need to wrap this since Cache.Get returns a ReadAtCloser
		src = store.NewReader(cacheContents)
	} else {
		// cache miss...load from main store, AND put into cache
		nCacheMiss.Add(1)
		log.Printf("Cache Miss %s", key)

		// If Item Store Use disabled, and not in cache, return 503
		if s.useTape == false {
			w.WriteHeader(503)
			fmt.Fprintln(w, items.ErrNoStore)
			log.Printf("GET /blob/%s/%s returns 503 - tape disabled", id, bid)
			return
		}

		blobinfo, err := s.Items.BlobInfo(id, bid)
		if err != nil {
			w.WriteHeader(404)
			fmt.Fprintln(w, err)
			return
		}
		length = blobinfo.Size
		// cache this item if it is not too large.
		// doing 1/8th of the cache size is arbitrary.
		// not sure what a good cutoff would be.
		if length < s.Cache.Size()/8 {
			w.Header().Set("X-Cached", "0")
			if r.Method == "GET" {
				go s.copyBlobIntoCache(key, id, bid)
			}
		} else {
			// item is too large to be cached
			w.Header().Set("X-Cached", "2")
		}

		// If this is a GET, retrieve the blob- if it's a HEAD, don't
		if r.Method == "GET" {
			realContents, _, err := s.Items.Blob(id, bid)
			if err != nil {
				w.WriteHeader(404)
				fmt.Fprintln(w, err)
				return
			}
			defer realContents.Close()
			src = realContents
		}
	}
	w.Header().Set("ETag", fmt.Sprintf("%d", bid))
	w.Header().Set("Content-Length", fmt.Sprintf("%d", length))

	// if it's a GET, copy the data into the response- if it's a HEAD, don't
	if r.Method == "HEAD" {
		return
	}
	n, err := io.Copy(w, src)
	if err != nil {
		log.Printf("getblob (%s,%d) %d,%s", id, bid, n, err.Error())
	}
}