func LogFetchResultLoadingError(res *FetchResult, w http.ResponseWriter, r *http.Request) {
	// 404 and 502 Error already become logged in logger.go
	if res.Content.HttpStatusCode() != 404 && res.Content.HttpStatusCode() != 502 {
		logging.Application(r.Header).WithField("fetchResult", res).Errorf("error loading content from: %v", res.Def.URL)
	}
	res.Def.ErrHandler.Handle(res.Err, res.Content.HttpStatusCode(), w, r)
}
func (agg *CompositionHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	// If we know the host but don't have the Host header [any more] then we
	// set [or restore] the header, because why would You just remove it!?:
	if (r.Host != "") && (r.Header.Get("Host") == "") {
		r.Header.Set("Host", r.Host)
	}

	fetcher := agg.contentFetcherFactory(r)

	if agg.handleEmptyFetcher(fetcher, w, r) {
		return
	}

	// fetch all contents
	results := fetcher.WaitForResults()

	// Allow HEAD requests and disable composition of body fragments
	if agg.handleHeadRequests(results, w, r) {
		return
	}

	mergeContext := agg.contentMergerFactory(fetcher.MetaJSON())

	for _, res := range results {
		if res.Err == nil && res.Content != nil {

			// Handle responses with 30x status code or with response bodies
			if agg.handleNonMergeableResponses(res, w, r) {
				return
			}

			mergeContext.AddContent(res.Content, res.Def.Priority)

		} else if res.Def.Required {
			LogFetchResultLoadingError(res, w, r)
			return
		} else {
			logging.Application(r.Header).WithField("fetchResult", res).Warnf("optional content not loaded: %v", res.Def.URL)
		}
	}

	status := agg.extractStatusCode(results, w, r)

	agg.copyHeadersIfNeeded(results, w, r)

	// Overwrite Content-Type to ensure, that the encoding is correct
	w.Header().Set("Content-Type", "text/html; charset=utf-8")

	html, err := agg.processHtml(mergeContext, w, r)
	// Return if an error occured within the html aggregation
	if err != nil {
		agg.purgeCacheEntries(results)
		return
	}

	w.Header().Set("Content-Length", strconv.Itoa(len(html)))
	w.WriteHeader(status)
	w.Write(html)
}
func (agg *CompositionHandler) processHtml(mergeContext ContentMerger, w http.ResponseWriter, r *http.Request) ([]byte, error) {
	html, err := mergeContext.GetHtml()
	if err != nil {
		logging.Application(r.Header).Error(err.Error())
		http.Error(w, "Internal Server Error: "+err.Error(), 500)
	}
	return html, err
}
func (agg *CompositionHandler) handleEmptyFetcher(fetcher FetchResultSupplier, w http.ResponseWriter, r *http.Request) bool {
	if fetcher.Empty() {
		w.WriteHeader(500)
		w.Write([]byte("Internal server error"))
		logging.Application(r.Header).Error("No fetchers available for composition, throwing error 500")
		return true
	}
	return false
}