blob: 8c93425f387879bca6ff469c213dcd4759875e17 [file] [log] [blame]
// Copyright 2011 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.
// To run godoc under app engine, substitute main.go with
// this file (appinit.go), provide a .zip file containing
// the file system to serve, the index file (or files)
// containing the pre-computed search index and adjust
// the configuration parameters in appconfig.go accordingly.
//
// The current app engine SDK may be based on an older Go
// release version. To correct for version skew, copy newer
// packages into the alt directory (e.g. alt/strings) and
// adjust the imports in the godoc source files (e.g. from
// `import "strings"` to `import "alt/strings"`). Both old
// and new packages may be used simultaneously as long as
// there is no package global state that needs to be shared.
//
// The directory structure should look as follows:
//
// godoc-app // directory containing the app engine app
// alt // alternative packages directory to
// // correct for version skew
// strings // never version of the strings package
// ... //
// app.yaml // app engine control file
// godoc.zip // .zip file containing the file system to serve
// godoc // contains godoc sources
// appinit.go // this file instead of godoc/main.go
// appconfig.go // godoc for app engine configuration
// ... //
// index.split.* // index file(s) containing the search index to serve
//
// To run app the engine emulator locally:
//
// dev_appserver.py -a 0 godoc-app
//
// The godoc home page is served at: <hostname>:8080 and localhost:8080.
package main
import (
"archive/zip"
"http"
"log"
"os"
"path"
)
func serveError(w http.ResponseWriter, r *http.Request, relpath string, err os.Error) {
contents := applyTemplate(errorHTML, "errorHTML", err) // err may contain an absolute path!
w.WriteHeader(http.StatusNotFound)
servePage(w, "File "+relpath, "", "", contents)
}
func init() {
log.Println("initializing godoc ...")
log.Printf(".zip file = %s", zipFilename)
log.Printf(".zip GOROOT = %s", zipGoroot)
log.Printf("index files = %s", indexFilenames)
// initialize flags for app engine
*goroot = path.Join("/", zipGoroot) // fsHttp paths are relative to '/'
*indexEnabled = true
*indexFiles = indexFilenames
*maxResults = 100 // reduce latency by limiting the number of fulltext search results
*indexThrottle = 0.3 // in case *indexFiles is empty (and thus the indexer is run)
// read .zip file and set up file systems
const zipfile = zipFilename
rc, err := zip.OpenReader(zipfile)
if err != nil {
log.Fatalf("%s: %s\n", zipfile, err)
}
// rc is never closed (app running forever)
fs = NewZipFS(rc)
fsHttp = NewHttpZipFS(rc, *goroot)
// initialize http handlers
readTemplates()
initHandlers()
registerPublicHandlers(http.DefaultServeMux)
// initialize default directory tree with corresponding timestamp.
initFSTree()
// initialize directory trees for user-defined file systems (-path flag).
initDirTrees()
// initialize search index
if *indexEnabled {
go indexer()
}
log.Println("godoc initialization complete")
}