| // 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") |
| } |