code: func (h *Handler) pipeUpstream(w http.ResponseWriter, r *cacheRequest) {
  	rw := newResponseStreamer(w)
  	rdr, err := rw.Stream.NextReader()
  	if err != nil {
  		debugf("error creating next stream reader: %v", err)
  		w.Header().Set(CacheHeader, "SKIP")
  		h.upstream.ServeHTTP(w, r.Request)
  		return
  	}
  	defer rdr.Close()
  
  	debugf("piping request upstream")
  	go func() {
  		h.upstream.ServeHTTP(rw, r.Request)
  		rw.Stream.Close()
  	}()
  	rw.WaitHeaders()
  
  	if r.Method != "HEAD" && !r.isStateChanging() {
  		return
  	}
  
  	res := rw.Resource()
  	defer res.Close()
  
  	if r.Method == "HEAD" {
  		h.cache.Freshen(res, r.Key.ForMethod("GET").String())
  	} else if res.IsNonErrorStatus() {
  		h.invalidateResource(res, r)
  	}
  }
docs: // pipeUpstream makes the request via the upstream handler, the response is not stored or modified