Copyright 2019 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

package frontend

import (
	
	
	
	

	
	
	
	
	
	
	
)
serveDetails handles requests for package/directory/module details pages. It expects paths of the form "/<module-path>[@<version>?tab=<tab>]". stdlib module pages are handled at "/std", and requests to "/mod/std" will be redirected to that path.
func ( *Server) ( http.ResponseWriter,  *http.Request,  internal.DataSource) ( error) {
	defer middleware.ElapsedStat(.Context(), "serveDetails")()

	if .Method != http.MethodGet && .Method != http.MethodHead {
		return &serverError{status: http.StatusMethodNotAllowed}
	}
	if .URL.Path == "/" {
		.staticPageHandler("index.tmpl", "Home")(, )
		return nil
	}
	if strings.HasPrefix(.URL.Path, "/github.com/golang/go") {
		 := strings.TrimPrefix(strings.TrimPrefix(.URL.Path, "/github.com/golang/go"), "/src")
		if  == "" {
			http.Redirect(, , "/std", http.StatusMovedPermanently)
			return
		}
		http.Redirect(, , , http.StatusMovedPermanently)
		return
	}
	if strings.HasSuffix(.URL.Path, "/") {
		http.Redirect(, , strings.TrimSuffix(.URL.Path, "/"), http.StatusMovedPermanently)
		return
	}

If page statistics are enabled, use the "exp" query param to adjust the active experiments.
	if .serveStats {
		 = setExperimentsFromQueryParam(, )
	}

	,  := extractURLPathInfo(.URL.Path)
	if  != nil {
		var  *errorPage
		if  := new(userError); errors.As(, &) {
			 = &errorPage{MessageData: .userMessage}
		}
		return &serverError{
			status: http.StatusBadRequest,
			err:    ,
			epage:  ,
		}
	}
	if !isSupportedVersion(.fullPath, .requestedVersion) {
		return invalidVersionError(.fullPath, .requestedVersion)
	}
	if  := checkExcluded(, , .fullPath);  != nil {
		return 
	}
	return .serveUnitPage(, , , , )
}

func (,  string) error {
	return &serverError{
		status: http.StatusBadRequest,
		epage: &errorPage{
			messageTemplate: template.MakeTrustedTemplate(`
					<h3 class="Error-message">{{.Version}} is not a valid semantic version.</h3>
					<p class="Error-message">
					  To search for packages like {{.Path}}, <a href="/search?q={{.Path}}">click here</a>.
					</p>`),
			MessageData: struct{ ,  string }{, },
		},
	}
}

func () error {
	return &serverError{
		status: http.StatusFailedDependency,
		epage: &errorPage{
			messageTemplate: template.MakeTrustedTemplate(
				`<h3 class="Error-message">This page is not supported by the proxydatasource.</h3>`),
		},
	}
}

var (
	keyVersionType     = tag.MustNewKey("frontend.version_type")
	versionTypeResults = stats.Int64(
		"go-discovery/frontend_version_type_count",
		"The version type of a request to package, module, or directory page.",
		stats.UnitDimensionless,
	)
	VersionTypeCount = &view.View{
		Name:        "go-discovery/frontend_version_type/result_count",
		Measure:     versionTypeResults,
		Aggregation: view.Count(),
		Description: "version type results, by latest, master, or semver",
		TagKeys:     []tag.Key{keyVersionType},
	}
)

Tag versions based on latest, master and semver.
	 := 
	if semver.IsValid() {
		 = "semver"
	}
	stats.RecordWithTags(, []tag.Mutator{
		tag.Upsert(keyVersionType, ),
	}, versionTypeResults.M(1))