Пример #1
0
func init() {
	enforceHosts = !appengine.IsDevAppServer()
	playEnabled = true

	log.Println("initializing godoc ...")
	log.Printf(".zip file   = %s", zipFilename)
	log.Printf(".zip GOROOT = %s", zipGoroot)
	log.Printf("index files = %s", indexFilenames)

	goroot := path.Join("/", zipGoroot) // fsHttp paths are relative to '/'

	// 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.Bind("/", zipfs.New(rc, zipFilename), goroot, vfs.BindReplace)
	fs.Bind("/lib/godoc", mapfs.New(static.Files), "/", vfs.BindReplace)

	corpus := godoc.NewCorpus(fs)
	corpus.Verbose = false
	corpus.MaxResults = 10000 // matches flag default in main.go
	corpus.IndexEnabled = true
	corpus.IndexFiles = indexFilenames
	if err := corpus.Init(); err != nil {
		log.Fatal(err)
	}
	corpus.IndexDirectory = indexDirectoryDefault
	go corpus.RunIndexer()

	pres = godoc.NewPresentation(corpus)
	pres.TabWidth = 8
	pres.ShowPlayground = true
	pres.ShowExamples = true
	pres.DeclLinks = true
	pres.NotesRx = regexp.MustCompile("BUG")

	readTemplates(pres, true)

	mux := registerHandlers(pres)
	dl.RegisterHandlers(mux)
	short.RegisterHandlers(mux)

	// Register /compile and /share handlers against the default serve mux
	// so that other app modules can make plain HTTP requests to those
	// hosts. (For reasons, HTTPS communication between modules is broken.)
	proxy.RegisterHandlers(http.DefaultServeMux)

	log.Println("godoc initialization complete")
}
Пример #2
0
func main() {
	log.SetOutput(os.Stderr)

	port := flag.String("port", "8080", "server listening tcp port")
	dbServer := flag.String("server", "localhost", "database server")
	dbName := flag.String("db", "estia", "database name")
	siteType := flag.String("type", "dir", "site path type zip or dir")
	sitePath := flag.String("path", "wwwroot", "path containing site")
	flag.Parse()

	server = *dbServer
	database = *dbName

	db, err := mgo.Dial(server)
	if err != nil {
		log.Panic(err)
	}
	defer db.Close()

	router := NewRouter()
	if *siteType == "zip" {
		rd, err := zip.OpenReader(*sitePath)
		if err != nil {
			log.Fatal(err)
		}
		fs := zipfs.New(rd, *sitePath)
		router.PathPrefix("/").Handler(http.FileServer(httpfs.New(fs)))
	} else {
		router.PathPrefix("/").Handler(http.FileServer(http.Dir(*sitePath)))
	}

	withLog := handlers.LoggingHandler(os.Stdout, router)

	withdb := WithDB(db, withLog)

	withcors := handlers.CORS()(withdb)

	withGz := handlers.CompressHandler(withcors)

	log.Printf(
		"%s\t%s",
		"Server listening on ",
		*port,
	)

	log.Fatal(http.ListenAndServeTLS(":"+*port, "cert.pem", "key.pem", context.ClearHandler(withGz)))
}
Пример #3
0
// Init initialize the translations environment.
func Init(goRoot, goTranslations, goZipFile, goTemplateDir, goPath string) {
	if goZipFile != "" {
		rc, err := zip.OpenReader(goZipFile)
		if err != nil {
			log.Fatalf("local: %s: %s\n", goZipFile, err)
		}

		defaultRootFS = getNameSpace(zipfs.New(rc, goZipFile), goRoot)
		defaultDocFS = getNameSpace(defaultRootFS, "/doc")
		defaultBlogFS = getNameSpace(defaultRootFS, "/blog")
		if goTranslations != "" && goTranslations != Default {
			defaultLocalFS = getNameSpace(defaultRootFS, "/"+goTranslations)
		} else {
			defaultLocalFS = getNameSpace(defaultRootFS, "/"+Default)
		}
	} else {
		if goRoot != "" && goRoot != runtime.GOROOT() {
			defaultRootFS = getNameSpace(vfs.OS(goRoot), "/")
			defaultDocFS = getNameSpace(defaultRootFS, "/doc")
			defaultBlogFS = getNameSpace(defaultRootFS, "/blog")
			if goTranslations == "" || goTranslations == Default {
				defaultLocalFS = getNameSpace(defaultRootFS, "/"+Default)
			}
		}
		if goTranslations != "" && goTranslations != Default {
			defaultLocalFS = getNameSpace(vfs.OS(goTranslations), "/")
		}

		if goTemplateDir != "" {
			defaultStaticFS = getNameSpace(vfs.OS(goTemplateDir), "/")
		}

		// Bind $GOPATH trees into Go root.
		for _, p := range filepath.SplitList(goPath) {
			defaultRootFS.Bind("/src", vfs.OS(p), "/src", vfs.BindAfter)
		}

		// Prefer content from go.blog repository if present.
		if _, err := defaultBlogFS.Lstat("/"); err != nil {
			const blogRepo = "golang.org/x/blog"
			if pkg, err := build.Import(blogRepo, "", build.FindOnly); err == nil {
				defaultBlogFS = getNameSpace(defaultRootFS, pkg.Dir)
			}
		}
	}

}
Пример #4
0
func init() {
	playEnabled = true

	log.Println("initializing godoc ...")
	log.Printf(".zip file   = %s", zipFilename)
	log.Printf(".zip GOROOT = %s", zipGoroot)
	log.Printf("index files = %s", indexFilenames)

	goroot := path.Join("/", zipGoroot) // fsHttp paths are relative to '/'

	// 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.Bind("/", zipfs.New(rc, zipFilename), goroot, vfs.BindReplace)
	fs.Bind("/lib/godoc", mapfs.New(static.Files), "/", vfs.BindReplace)

	corpus := godoc.NewCorpus(fs)
	corpus.Verbose = false
	corpus.MaxResults = 10000 // matches flag default in main.go
	corpus.IndexEnabled = true
	corpus.IndexFiles = indexFilenames
	if err := corpus.Init(); err != nil {
		log.Fatal(err)
	}
	corpus.IndexDirectory = indexDirectoryDefault
	go corpus.RunIndexer()

	pres = godoc.NewPresentation(corpus)
	pres.TabWidth = 8
	pres.ShowPlayground = true
	pres.ShowExamples = true
	pres.DeclLinks = true
	pres.NotesRx = regexp.MustCompile("BUG")

	readTemplates(pres, true)
	registerHandlers(pres)

	log.Println("godoc initialization complete")
}
Пример #5
0
func main() {

	// example files to use
	files := map[string]string{"foo": "foo", "bar/baz": "baz"}

	// create test zip file from above files
	b := new(bytes.Buffer)
	zw := zip.NewWriter(b)
	for file, contents := range files {
		w, err := zw.Create(file)
		if err != nil {
			log.Fatal(err)
		}
		_, err = io.WriteString(w, contents)
		if err != nil {
			log.Fatal(err)
		}
	}
	zw.Close()

	// create zipfs from zip file
	zr, err := zip.NewReader(bytes.NewReader(b.Bytes()), int64(b.Len()))
	if err != nil {
		log.Fatal(err)
	}
	rc := &zip.ReadCloser{
		Reader: *zr,
	}
	fs := zipfs.New(rc, "foo")

	// try to list contents of root directory
	// FAILS HERE!
	infos, err := fs.ReadDir("/")
	if err != nil {
		log.Fatal(err)
	}
	for _, info := range infos {
		log.Printf("Found: %v\n", info.Name())
	}
}
Пример #6
0
// find end-of-directory struct, near the end of the file.
// it specifies the size & offset of the central directory.
// we assume the central directory is located just before the end-of-central-directory.
// so that allows us to calculate the original size of the zip file.
// which in turn allows us to use godoc's zipfs to serve the zip file withend.
func open() (vfs.FileSystem, error) {
	f, err := os.Open(os.Args[0])
	if err != nil {
		return nil, err
	}
	fi, err := f.Stat()
	if err != nil {
		return nil, err
	}

	n := int64(65 * 1024)
	size := fi.Size()
	if size < n {
		n = size
	}
	buf := make([]byte, n)
	_, err = io.ReadAtLeast(io.NewSectionReader(f, size-n, n), buf, len(buf))
	if err != nil {
		return nil, err
	}
	o := int64(findSignatureInBlock(buf))
	if o < 0 {
		return nil, errors.New("could not locate zip file, no end-of-central-directory signature found")
	}
	cdirsize := int64(binary.LittleEndian.Uint32(buf[o+12:]))
	cdiroff := int64(binary.LittleEndian.Uint32(buf[o+16:]))
	zipsize := cdiroff + cdirsize + (int64(len(buf)) - o)

	rr := io.NewSectionReader(f, size-zipsize, zipsize)
	r, err := zip.NewReader(rr, zipsize)
	if err != nil {
		return nil, err
	}

	rc := &zip.ReadCloser{Reader: *r}
	return &assetFS{zipfs.New(rc, "<asset>"), rc}, nil
}
Пример #7
0
func main() {
	flag.Usage = usage
	flag.Parse()

	playEnabled = *showPlayground

	// Check usage: either server and no args, command line and args, or index creation mode
	if (*httpAddr != "" || *urlFlag != "") != (flag.NArg() == 0) && !*writeIndex {
		usage()
	}

	var fsGate chan bool
	fsGate = make(chan bool, 20)

	// Determine file system to use.
	if *zipfile == "" {
		// use file system of underlying OS
		rootfs := gatefs.New(vfs.OS(*goroot), fsGate)
		fs.Bind("/", rootfs, "/", vfs.BindReplace)
	} else {
		// use file system specified via .zip file (path separator must be '/')
		rc, err := zip.OpenReader(*zipfile)
		if err != nil {
			log.Fatalf("%s: %s\n", *zipfile, err)
		}
		defer rc.Close() // be nice (e.g., -writeIndex mode)
		fs.Bind("/", zipfs.New(rc, *zipfile), *goroot, vfs.BindReplace)
	}
	if *templateDir != "" {
		fs.Bind("/lib/godoc", vfs.OS(*templateDir), "/", vfs.BindBefore)
	} else {
		fs.Bind("/lib/godoc", mapfs.New(static.Files), "/", vfs.BindReplace)
	}

	// Bind $GOPATH trees into Go root.
	for _, p := range filepath.SplitList(build.Default.GOPATH) {
		fs.Bind("/src", gatefs.New(vfs.OS(p), fsGate), "/src", vfs.BindAfter)
	}

	httpMode := *httpAddr != ""

	var typeAnalysis, pointerAnalysis bool
	if *analysisFlag != "" {
		for _, a := range strings.Split(*analysisFlag, ",") {
			switch a {
			case "type":
				typeAnalysis = true
			case "pointer":
				pointerAnalysis = true
			default:
				log.Fatalf("unknown analysis: %s", a)
			}
		}
	}

	corpus := godoc.NewCorpus(fs)
	corpus.Verbose = *verbose
	corpus.MaxResults = *maxResults
	corpus.IndexEnabled = *indexEnabled && httpMode
	if *maxResults == 0 {
		corpus.IndexFullText = false
	}
	corpus.IndexFiles = *indexFiles
	corpus.IndexDirectory = indexDirectoryDefault
	corpus.IndexThrottle = *indexThrottle
	corpus.IndexInterval = *indexInterval
	if *writeIndex {
		corpus.IndexThrottle = 1.0
		corpus.IndexEnabled = true
	}
	if *writeIndex || httpMode || *urlFlag != "" {
		if err := corpus.Init(); err != nil {
			log.Fatal(err)
		}
	}

	pres = godoc.NewPresentation(corpus)
	pres.TabWidth = *tabWidth
	pres.ShowTimestamps = *showTimestamps
	pres.ShowPlayground = *showPlayground
	pres.ShowExamples = *showExamples
	pres.DeclLinks = *declLinks
	pres.SrcMode = *srcMode
	pres.HTMLMode = *html
	if *notesRx != "" {
		pres.NotesRx = regexp.MustCompile(*notesRx)
	}

	readTemplates(pres, httpMode || *urlFlag != "")
	registerHandlers(pres)

	if *writeIndex {
		// Write search index and exit.
		if *indexFiles == "" {
			log.Fatal("no index file specified")
		}

		log.Println("initialize file systems")
		*verbose = true // want to see what happens

		corpus.UpdateIndex()

		log.Println("writing index file", *indexFiles)
		f, err := os.Create(*indexFiles)
		if err != nil {
			log.Fatal(err)
		}
		index, _ := corpus.CurrentIndex()
		_, err = index.WriteTo(f)
		if err != nil {
			log.Fatal(err)
		}

		log.Println("done")
		return
	}

	// Print content that would be served at the URL *urlFlag.
	if *urlFlag != "" {
		handleURLFlag()
		return
	}

	if httpMode {
		// HTTP server mode.
		var handler http.Handler = http.DefaultServeMux
		if *verbose {
			log.Printf("Go Documentation Server")
			log.Printf("version = %s", runtime.Version())
			log.Printf("address = %s", *httpAddr)
			log.Printf("goroot = %s", *goroot)
			log.Printf("tabwidth = %d", *tabWidth)
			switch {
			case !*indexEnabled:
				log.Print("search index disabled")
			case *maxResults > 0:
				log.Printf("full text index enabled (maxresults = %d)", *maxResults)
			default:
				log.Print("identifier search index enabled")
			}
			fs.Fprint(os.Stderr)
			handler = loggingHandler(handler)
		}

		// Initialize search index.
		if *indexEnabled {
			go corpus.RunIndexer()
		}

		// Start type/pointer analysis.
		if typeAnalysis || pointerAnalysis {
			go analysis.Run(pointerAnalysis, &corpus.Analysis)
		}

		// Start http server.
		if err := http.ListenAndServe(*httpAddr, handler); err != nil {
			log.Fatalf("ListenAndServe %s: %v", *httpAddr, err)
		}

		return
	}

	if *query {
		handleRemoteSearch()
		return
	}

	if err := godoc.CommandLine(os.Stdout, fs, pres, flag.Args()); err != nil {
		log.Print(err)
	}
}
Пример #8
0
//ZipSS is a convenience function to return a StaticServer based on godoc.zipfs
//For more info look at documentation for golang.org/x/tools/godoc/vfs/zipfs/
//Use errorHandlers to provide custom http.HandlerFunc to handle http.StatusNotFound
//and http.StatusInternalServerError or provide nil to use default implementation
//If a log.Logger is provided (ie. not nil), StaticServer does verbose logging
func ZipSS(rc *zip.ReadCloser, name string, errorHandlers map[int]http.HandlerFunc, logger *log.Logger) StaticServer {
	return VFSStaticServer(zipfs.New(rc, name), errorHandlers, logger)
}