func (h *reqHandler) getUpstreamReader(start, end uint64) io.ReadCloser { subh := *h subh.req = subh.getNormalizedRequest() subh.req.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", start, end)) h.Logger.Debugf("[%p] Making upstream request for %s, bytes [%d-%d]...", subh.req, subh.req.URL, start, end) //!TODO: optimize requests for the same pieces? if possible, make only 1 request to the upstream for the same part r, w := io.Pipe() subh.resp = httputils.NewFlexibleResponseWriter(func(rw *httputils.FlexibleResponseWriter) { respRng, err := httputils.GetResponseRange(rw.Code, rw.Headers) if err != nil { h.Logger.Debugf("[%p] Could not parse the content-range for the partial upstream request: %s", subh.req, err) _ = w.CloseWithError(err) } h.Logger.Debugf("[%p] Received response with status %d and range %v", subh.req, rw.Code, respRng) if rw.Code == http.StatusPartialContent { //!TODO: check whether the returned range corresponds to the requested range rw.BodyWriter = w } else if rw.Code == http.StatusOK { //!TODO: handle this, use skipWriter or something like that _ = w.CloseWithError(fmt.Errorf("NOT IMPLEMENTED")) } else { _ = w.CloseWithError(fmt.Errorf("Upstream responded with status %d", rw.Code)) } }) go utils.SafeExecute( subh.carbonCopyProxy, func(err error) { h.Logger.Errorf("[%p] Panic inside carbonCopyProxy %s", subh.req, err) w.CloseWithError(err) // !TODO maybe some other error }, ) return newWholeChunkReadCloser(r, h.Cache.PartSize.Bytes()) }
func safeExecute(f func(), key types.ObjectIDHash) { utils.SafeExecute(f, func(err error) { log.Printf("panic inside the function for key '%s' : %s", key, err) }) }