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 }