// starts http handlers for HTML content based on the given configuration file
// optional parameters:  default.contentDirectory (location of html content to be served at https://example.com/ or https://example.com/html/index.html
func StartHtmlHandler() {
	if contentDir, _ := configFile.GetString("default", "contentDirectory"); contentDir != "" {
		logger.Printf("StartHtmlHandler(): serving HTML content from [%v]", contentDir)
		http.Handle("/html/", http.StripPrefix("/html/", http.FileServer(http.Dir(contentDir))))
		http.Handle("/", http.RedirectHandler("/html/", http.StatusTemporaryRedirect))
	}
}
Beispiel #2
0
func main() {
	log.SetFlags(0)
	flag.Parse()

	cgiHandler := &cgi.Handler{
		Path: *cgitPath,
		Env:  []string{},
		InheritEnv: []string{
			"CGIT_CONFIG",
		},
	}
	if *config != "" {
		cgiHandler.Env = append(cgiHandler.Env,
			"CGIT_CONFIG="+*config)
	}

	fs := http.FileServer(http.Dir(*cgitRes))
	http.Handle("/cgit.css", fs)
	http.Handle("/cgit.png", fs)
	http.Handle("/", cgiHandler)

	err := http.ListenAndServe(*addr+":"+strconv.Itoa(*port), nil)
	if err != nil {
		log.Fatal(err)
	}

	// Everything seems to work: daemonize (close file handles)
	os.Stdin.Close()
	os.Stdout.Close()
	os.Stderr.Close()
}
Beispiel #3
0
func main() {
	http.Handle("/echo", websocket.Handler(EchoServer))
	http.Handle("/lobby", websocket.Handler(LobbyServer))
	http.Handle("/", http.FileServer(http.Dir("/tmp")))
	fmt.Println("Listening on:", listenAddress)
	if err := http.ListenAndServe(listenAddress, nil); err != nil {
		panic("ListenAndServe: " + err.String())
	}
}
Beispiel #4
0
func main() {
	l, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		fmt.Printf("%s\n", err)
		os.Exit(1)
	}

	fmt.Printf("%d\n", l.Addr().(*net.TCPAddr).Port)

	http.Handle("/", http.FileServer(http.Dir(".")))
	http.Serve(l, nil)
}
Beispiel #5
0
func main() {
	port := "0.0.0.0:8080"
	room = NewRoom()
	staticDir := http.Dir("/projects/go/chat/static")
	staticServer := http.FileServer(staticDir)

	http.HandleFunc("/", Home)
	http.HandleFunc("/feed", FeedMux)
	http.HandleFunc("/login", LoginMux)
	http.Handle("/static/", http.StripPrefix("/static", staticServer))
	fmt.Printf("Serving at %s ----------------------------------------------------", port)
	http.ListenAndServe(port, nil)
}
Beispiel #6
0
/**
* Main Function
 */
func main() {
	fmt.Printf("Starting http Server ... \n")

	http.Handle("/$sys", http.HandlerFunc(handleSys))
	http.Handle("/$db", http.HandlerFunc(handleDb))

	//internal webserver should be disabled
	http.Handle("/", http.FileServer(http.Dir("web/")))

	err := http.ListenAndServe("127.0.0.1:8080", nil)
	if err != nil {
		fmt.Printf("ListenAndServe Error :" + err.String())
	}
}
Beispiel #7
0
Datei: godoc.go Projekt: ssrl/go
func initHandlers() {
	paths := filepath.SplitList(*pkgPath)
	for _, t := range build.Path {
		if t.Goroot {
			continue
		}
		paths = append(paths, t.SrcDir())
	}
	fsMap.Init(paths)

	fileServer = http.FileServer(http.Dir(*goroot))
	cmdHandler = httpHandler{"/cmd/", filepath.Join(*goroot, "src", "cmd"), false}
	pkgHandler = httpHandler{"/pkg/", filepath.Join(*goroot, "src", "pkg"), true}
}
Beispiel #8
0
//Start the web server
func runServer(port string, s chan int) {

	http.HandleFunc("/", viewHandle)
	http.HandleFunc("/logview/", logViewHandle)

	pwd, _ := os.Getwd()
	http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir(pwd+"/static/"))))

	err := http.ListenAndServe(":"+port, nil)
	if err != nil {
		println(err.String())
	}

	s <- 1
}
Beispiel #9
0
func main() {
	flag.Parse()
	if *help {
		flag.PrintDefaults()
		return
	}

	coord := NewDownloadCoordinator()
	http.Handle("/dl", NewDownloadHandler(*basePath, coord))
	//	http.Handle("/files/", http.StripPrefix("/files/", http.FileServer(http.Dir(*basePath))))
	http.Handle("/", http.FileServer(http.Dir("fs/")))
	if e := http.ListenAndServe(fmt.Sprintf(":%d", *port), nil); e != nil {
		fmt.Printf("Cannot listen! Error: %s\n", e.String())
	}
}
func main() {
	flag.Parse()

	// source of unique numbers
	go func() {
		for i := 0; ; i++ {
			uniq <- i
		}
	}()

	// set archChar
	var err os.Error
	archChar, err = build.ArchChar(runtime.GOARCH)
	if err != nil {
		log.Fatal(err)
	}

	// find and serve the go tour files
	t, _, err := build.FindTree(basePkg)
	if err != nil {
		log.Fatalf("Couldn't find tour files: %v", err)
	}
	root := filepath.Join(t.SrcDir(), basePkg)
	root := basePkg
	log.Println("Serving content from", root)
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Path == "/favicon.ico" || r.URL.Path == "/" {
			fn := filepath.Join(root, "static", r.URL.Path[1:])
			http.ServeFile(w, r, fn)
			return
		}
		http.Error(w, "not found", 404)
	})
	http.Handle("/static/", http.FileServer(http.Dir(root)))
	http.HandleFunc("/kill", kill)

	// set include path for ld and gc
	pkgDir = t.PkgDir()

	if !strings.HasPrefix(*httpListen, "127.0.0.1") &&
		!strings.HasPrefix(*httpListen, "localhost") {
		log.Print(localhostWarning)
	}

	log.Printf("Serving at http://%s/", *httpListen)
	log.Fatal(http.ListenAndServe(*httpListen, nil))
}
Beispiel #11
0
// A very simple chat server
func main() {
	buffer := new(vector.Vector)
	mutex := new(sync.Mutex)

	// create the socket.io server and mux it to /socket.io/
	config := socketio.DefaultConfig
	config.Origins = []string{"localhost:8080"}
	sio := socketio.NewSocketIO(&config)

	go func() {
		if err := sio.ListenAndServeFlashPolicy(":843"); err != nil {
			log.Println(err)
		}
	}()

	// when a client connects - send it the buffer and broadcasta an announcement
	sio.OnConnect(func(c *socketio.Conn) {
		mutex.Lock()
		c.Send(Buffer{buffer.Copy()})
		mutex.Unlock()
		sio.Broadcast(Announcement{"connected: " + c.String()})
	})

	// when a client disconnects - send an announcement
	sio.OnDisconnect(func(c *socketio.Conn) {
		sio.Broadcast(Announcement{"disconnected: " + c.String()})
	})

	// when a client send a message - broadcast and store it
	sio.OnMessage(func(c *socketio.Conn, msg socketio.Message) {
		payload := Message{[]string{c.String(), msg.Data()}}
		mutex.Lock()
		buffer.Push(payload)
		mutex.Unlock()
		sio.Broadcast(payload)
	})

	log.Println("Server starting. Tune your browser to http://localhost:8080/")

	mux := sio.ServeMux()
	mux.Handle("/", http.FileServer(http.Dir("www/")))

	if err := http.ListenAndServe(":8080", mux); err != nil {
		log.Fatal("ListenAndServe:", err)
	}
}
Beispiel #12
0
// Initialize HTTP server for frontend
func ListenAndServeHttp(backend appchilada.Backend) os.Error {
	http.HandleFunc("/", indexHandler(backend))
	http.HandleFunc("/show/", showHandler(backend))

	if dir, err := os.Getwd(); err != nil {
		return err
	} else {
		dir = dir + string(os.PathSeparator) + "assets"
		log.Printf("Opening webserver in %s", dir)
		// Handle static files in /public served on /public (stripped prefix)
		http.Handle("/assets/", http.StripPrefix("/assets", http.FileServer(http.Dir(dir))))
	}
	log.Printf("Opening webserver on :8080")
	if err := http.ListenAndServe(":8080", nil); err != nil {
		return err
	}
	return nil
}
Beispiel #13
0
func main() {
	flag.Parse()
	runtime.GOMAXPROCS(*Procs)
	//	port := 8082
	//	host := "130.226.133.44:8082"
	host := *(Host) + ":" + fmt.Sprint(*(Port))
	mux := dynamichttp.NewServeMux()
	dir := http.Dir("./www")
	mux.Handle("/", http.FileServer(dir))

	wshttp.EnableWsHttp(host, mux)

	fmt.Println("Running on " + host)
	err := dynamichttp.ListenAndServe(host, mux)
	if err != nil {
		fmt.Println("error", err)
	}
	fmt.Println("Bye!")
}
Beispiel #14
0
func main() {
	runtime.GOMAXPROCS(8)
	port := "0.0.0.0:8000"
	room = NewRoom()
	rolloffs = make([]*RollOff, 0)
	staticDir := http.Dir("/projects/go/chat/static")
	staticServer := http.FileServer(staticDir)
	homeTemplate = template.Must(template.ParseFile("templates/index.html"))

	http.HandleFunc("/", LogWrap(Home, "Home"))
	http.HandleFunc("/feed", LogWrap(FeedMux, "FeedMux"))
	http.HandleFunc("/login", LogWrap(LoginMux, "LoginMux"))
	http.HandleFunc("/users", LogWrap(GetUsers, "GetUsers"))
	http.HandleFunc("/roll", LogWrap(Roll, "Roll"))
	http.HandleFunc("/roll-off", LogWrap(NewRollOff, "NewRollOff"))
	http.HandleFunc("/roll-off-entry/", LogWrap(EnterRollOff, "EnterRollOff"))
	http.Handle("/static/", http.StripPrefix("/static", staticServer))
	fmt.Printf("Serving at %s ----------------------------------------------------\n", port)
	http.ListenAndServe(port, nil)
}
Beispiel #15
0
func main() {
	flag.Parse()

	// The counter is published as a variable directly.
	ctr := new(Counter)
	http.Handle("/counter", ctr)
	expvar.Publish("counter", ctr)

	http.Handle("/", http.HandlerFunc(Logger))
	http.Handle("/go/", http.StripPrefix("/go/", http.FileServer(http.Dir(*webroot))))
	http.Handle("/flags", http.HandlerFunc(FlagServer))
	http.Handle("/args", http.HandlerFunc(ArgServer))
	http.Handle("/go/hello", http.HandlerFunc(HelloServer))
	http.Handle("/chan", ChanCreate())
	http.Handle("/date", http.HandlerFunc(DateServer))
	err := http.ListenAndServe(":12345", nil)
	if err != nil {
		log.Panicln("ListenAndServe:", err)
	}
}
Beispiel #16
0
func TestFileTransport(t *testing.T) {
	check := checker(t)

	dname, err := ioutil.TempDir("", "")
	check("TempDir", err)
	fname := filepath.Join(dname, "foo.txt")
	err = ioutil.WriteFile(fname, []byte("Bar"), 0644)
	check("WriteFile", err)

	tr := &http.Transport{}
	tr.RegisterProtocol("file", http.NewFileTransport(http.Dir(dname)))
	c := &http.Client{Transport: tr}

	fooURLs := []string{"file:///foo.txt", "file://../foo.txt"}
	for _, urlstr := range fooURLs {
		res, err := c.Get(urlstr)
		check("Get "+urlstr, err)
		if res.StatusCode != 200 {
			t.Errorf("for %s, StatusCode = %d, want 200", urlstr, res.StatusCode)
		}
		if res.ContentLength != -1 {
			t.Errorf("for %s, ContentLength = %d, want -1", urlstr, res.ContentLength)
		}
		if res.Body == nil {
			t.Fatalf("for %s, nil Body", urlstr)
		}
		slurp, err := ioutil.ReadAll(res.Body)
		check("ReadAll "+urlstr, err)
		if string(slurp) != "Bar" {
			t.Errorf("for %s, got content %q, want %q", urlstr, string(slurp), "Bar")
		}
	}

	const badURL = "file://../no-exist.txt"
	res, err := c.Get(badURL)
	check("Get "+badURL, err)
	if res.StatusCode != 404 {
		t.Errorf("for %s, StatusCode = %d, want 404", badURL, res.StatusCode)
	}
}
Beispiel #17
0
func StartServer(listen string, world *World) {

	http.HandleFunc("/state", func(w http.ResponseWriter, req *http.Request) {
		player, err := world.Player(req.URL.Query()["player"][0])
		if err != nil {
			panic(err)
		}
		io.WriteString(w, player.State())
	})

	http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		index, _ := ioutil.ReadFile("public/index.html")
		io.WriteString(w, string(index))
	})

	http.Handle("/static/", http.StripPrefix("/static", http.FileServer(http.Dir("./public"))))

	err := http.ListenAndServe(listen, nil)
	if err != nil {
		log.Fatal("ListenAndServe: ", err.String())
	}
}
Beispiel #18
0
func main() {
	// Defer this first to ensure cleanup gets done properly
	//
	// Any error of type GracefulError is handled with an exit(1)
	// rather than by handing the user a backtrace.
	//
	// An error of type RestartSignal is technically not an error
	// but is the cleanest way to ensure no defers are skipped.
	defer func() {
		problem := recover()
		if problem == nil {
			return
		}
		switch problem.(type) {
		case GracefulError:
			fmt.Println(problem)
			os.Exit(1)
		case RestartSignal:
			fmt.Println(problem)
			// Probably requires closing any fds still open
			// Will investigate later
			os.Exec(os.Args[0], os.Args, os.Envs)
			// If we're still here something went wrong.
			fmt.Println("Couldn't restart. You'll have to restart manually.")
			os.Exit(0)
		default:
			panic(problem)
		}
	}()

	flag.Parse()

	if *basedir == "" {
		*basedir = dirname(os.Args[0])
	}

	fmt.Println("Switching dir to", *basedir)
	os.Chdir(*basedir)

	parseConfig(*conffile)
	parseNameSpaces(conf["namespace_file"])

	// Check for any new databases, including initial startup, and
	// perform pre-processing.
	hadFiles := performUpdates()

	// Load in the title cache
	if !loadTitleFile() {
		if hadFiles {
			fmt.Println("Unable to read Title cache file: Invalid format?")
		} else {
			fmt.Println("\n\nNo wiki files found and unable to read title cache.\n\nIf you never downloaded a wikipedia dump, you will have to do that now.\nIf you have, something went wrong or the cache format changed.\nYou will probably have to supply a new dump or put back your old one.")
		}
		return
	}
	prepSearchRoutines()
	prepRecents()

	fmt.Println("Loaded! Starting webserver . . .")

	// /wiki/... are pages.
	http.HandleFunc("/wiki/", pageHandle)
	// /search/ look for given text
	http.HandleFunc("/search/", searchHandle)
	// /recent, a list of recent searches
	http.HandleFunc("/recent", recentHandle)

	// Everything else is served from the web dir.
	http.Handle("/", http.FileServer(http.Dir(conf["web_dir"])))

	fmt.Printf("Forcing Go to use %d max threads.\n", searchRoutines)
	runtime.GOMAXPROCS(searchRoutines)

	fmt.Println("Starting Web server on port", conf["listen"])

	err := http.ListenAndServe(conf["listen"], nil)
	if err != nil {
		fmt.Println("Fatal error:", err.String())
	}
}
Beispiel #19
0
func main() {
	// Debug URLs to reload or restart the system
	http.Handle("/debug/gc", http.HandlerFunc(GCServer))
	http.Handle("/debug/stats", http.HandlerFunc(StatsServer))
	http.Handle("/debug/exit", http.HandlerFunc(ExitServer))

	// Go 'http' package
	http.Handle("/go/hello", http.HandlerFunc(HelloServer))
	http.Handle("/go/example/", http.StripPrefix("/go", http.FileServer(http.Dir("../http-data"))))
	http.Handle("/go/ipsum.txt", http.StripPrefix("/go", http.FileServer(http.Dir("../http-data"))))

	// Webpipes with Erlang chains
	http.Handle("/webpipe/erlang/hello", webpipes.Chain(
		webpipes.TextStringSource(helloworld),
		webpipes.OutputPipe,
	))
	http.Handle("/webpipe/erlang/example/", webpipes.Chain(
		webpipes.FileServer("../http-data", "/webpipe/erlang"),
		webpipes.OutputPipe,
	))
	http.Handle("/webpipe/erlang/ipsum.txt", webpipes.Chain(
		webpipes.FileServer("../http-data", "/webpipe/erlang"),
		webpipes.OutputPipe,
	))

	// Webpipes with Proc chains
	http.Handle("/webpipe/proc/hello", webpipes.NetworkHandler(
		webpipes.TextStringSource(helloworld),
		webpipes.OutputPipe,
	))
	http.Handle("/webpipe/proc/example/", webpipes.NetworkHandler(
		webpipes.FileServer("../http-data", "/webpipe/proc"),
		webpipes.OutputPipe,
	))
	http.Handle("/webpipe/proc/ipsum.txt", webpipes.NetworkHandler(
		webpipes.FileServer("../http-data", "/webpipe/proc"),
		webpipes.OutputPipe,
	))

	// CGI Examples
	pwd, pwderr := os.Getwd()
	if pwderr != nil {
		log.Fatalf("Cannot find pwd: %s", pwderr)
	}

	cgipath := path.Clean(path.Join(pwd, "../http-data/cgi-bin"))

	cgiscripts := []string{"echo_post.py", "hello.py", "printenv.py", "test.sh"}
	for _, script := range cgiscripts {
		http.Handle(path.Join("/cgi-bin", script), webpipes.Chain(
			webpipes.CGIServer(path.Join(cgipath, script), "/cgi-bin/"),
			webpipes.OutputPipe,
		))
	}

	http.Handle("/wiki/", webpipes.Chain(
		webpipes.CGIServer("/tmp/gorows-sputnik/sputnik.cgi", "/wiki/"),
		webpipes.OutputPipe,
	))

	http.Handle("/zip/", webpipes.Chain(
		webpipes.FileServer("../http-data", "/zip/"),
		webpipes.CompressionPipe,
		webpipes.OutputPipe,
	))

	//	var second int64 = 1e9
	server := &http.Server{
		Addr:    ":12345",
		Handler: http.DefaultServeMux,
		//		ReadTimeout: 5 * second,
		//		WriteTimeout: 5 * second,
	}

	log.Printf("Starting test server on %s", server.Addr)
	log.Printf("Running on %d processes\n", runtime.GOMAXPROCS(0))
	err := server.ListenAndServe()
	if err != nil {
		log.Fatalf("Error: %s", err.String())
	}
}
Beispiel #20
0
// Load the data form NormalizationTest.txt
func loadTestData() {
	if *localFiles {
		pwd, _ := os.Getwd()
		*url = "file://" + path.Join(pwd, file)
	}
	t := &http.Transport{}
	t.RegisterProtocol("file", http.NewFileTransport(http.Dir("/")))
	c := &http.Client{Transport: t}
	resp, err := c.Get(*url)
	if err != nil {
		logger.Fatal(err)
	}
	if resp.StatusCode != 200 {
		logger.Fatal("bad GET status for "+file, resp.Status)
	}
	f := resp.Body
	defer f.Close()
	input := bufio.NewReader(f)
	for {
		line, err := input.ReadString('\n')
		if err != nil {
			if err == os.EOF {
				break
			}
			logger.Fatal(err)
		}
		if len(line) == 0 || line[0] == '#' {
			continue
		}
		m := partRe.FindStringSubmatch(line)
		if m != nil {
			if len(m) < 3 {
				logger.Fatal("Failed to parse Part: ", line)
			}
			i, err := strconv.Atoi(m[1])
			if err != nil {
				logger.Fatal(err)
			}
			name := m[2]
			part = append(part, Part{name: name[:len(name)-1], number: i})
			continue
		}
		m = testRe.FindStringSubmatch(line)
		if m == nil || len(m) < 7 {
			logger.Fatalf(`Failed to parse: "%s" result: %#v`, line, m)
		}
		test := Test{name: m[6], partnr: len(part) - 1, number: counter}
		counter++
		for j := 1; j < len(m)-1; j++ {
			for _, split := range strings.Split(m[j], " ") {
				r, err := strconv.Btoui64(split, 16)
				if err != nil {
					logger.Fatal(err)
				}
				if test.rune == 0 {
					// save for CharacterByCharacterTests
					test.rune = int(r)
				}
				var buf [utf8.UTFMax]byte
				sz := utf8.EncodeRune(buf[:], int(r))
				test.cols[j-1] += string(buf[:sz])
			}
		}
		part := &part[len(part)-1]
		part.tests = append(part.tests, test)
	}
}
Beispiel #21
0
func main() {
	flag.Parse()
	readTemplates()

	if *root == "" {
		var err os.Error
		*root, err = os.Getwd()
		if err != nil {
			log.Fatalf("Failed to getwd: %v", err)
		}
	}

	fixupGitwebFiles()

	latestGits := filepath.Join(*root, "latestgits")
	os.Mkdir(latestGits, 0700)
	if *gerritHost != "" {
		go rsyncFromGerrit(latestGits)
	}

	mux := http.DefaultServeMux
	mux.Handle("/favicon.ico", http.FileServer(http.Dir(filepath.Join(*root, "static"))))
	mux.Handle("/robots.txt", http.FileServer(http.Dir(filepath.Join(*root, "static"))))
	mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir(filepath.Join(*root, "static")))))
	mux.Handle("/talks/", http.StripPrefix("/talks/", http.FileServer(http.Dir(filepath.Join(*root, "talks")))))

	gerritUrl, _ := url.Parse("http://gerrit-proxy:8000/")
	var gerritHandler http.Handler = http.NewSingleHostReverseProxy(gerritUrl)
	if *httpsAddr != "" {
		proxyHandler := gerritHandler
		gerritHandler = http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
			if req.TLS != nil {
				proxyHandler.ServeHTTP(rw, req)
				return
			}
			http.Redirect(rw, req, "https://camlistore.org"+req.URL.RawPath, http.StatusFound)
		})
	}
	mux.Handle("/r/", gerritHandler)

	testCgi := &cgi.Handler{Path: filepath.Join(*root, "test.cgi"),
		Root: "/test.cgi",
	}
	mux.Handle("/test.cgi", testCgi)
	mux.Handle("/test.cgi/foo", testCgi)

	mux.Handle("/code", http.RedirectHandler("/code/", http.StatusFound))
	if *gitwebScript != "" {
		env := os.Environ()
		env = append(env, "GITWEB_CONFIG="+filepath.Join(*root, "gitweb-camli.conf"))
		env = append(env, "CAMWEB_ROOT="+filepath.Join(*root))
		env = append(env, "CAMWEB_GITDIR="+latestGits)
		mux.Handle("/code/", &fixUpGitwebUrls{&gitwebHandler{
			Cgi: &cgi.Handler{
				Path: *gitwebScript,
				Root: "/code/",
				Env:  env,
			},
			Static: http.StripPrefix("/code/", http.FileServer(http.Dir(*gitwebFiles))),
		}})
	}
	mux.HandleFunc("/", mainHandler)

	var handler http.Handler = &noWwwHandler{Handler: mux}
	if *logDir != "" || *logStdout {
		handler = NewLoggingHandler(handler, *logDir, *logStdout)
	}

	errch := make(chan os.Error)

	httpServer := &http.Server{
		Addr:         *httpAddr,
		Handler:      handler,
		ReadTimeout:  connTimeoutNanos,
		WriteTimeout: connTimeoutNanos,
	}
	go func() {
		errch <- httpServer.ListenAndServe()
	}()

	if *httpsAddr != "" {
		log.Printf("Starting TLS server on %s", *httpsAddr)
		httpsServer := new(http.Server)
		*httpsServer = *httpServer
		httpsServer.Addr = *httpsAddr
		go func() {
			errch <- httpsServer.ListenAndServeTLS(*tlsCertFile, *tlsKeyFile)
		}()
	}

	log.Fatalf("Serve error: %v", <-errch)
}
Beispiel #22
0
func init() {
	http.Handle("/", http.FileServer(http.Dir("static")))
	http.HandleFunc("/check", handler)
}
Beispiel #23
0
func main() {
	flag.Usage = usage
	flag.Parse()

	// Check usage: either server and no args, or command line and args
	if (*httpAddr != "") != (flag.NArg() == 0) {
		usage()
	}

	if *tabwidth < 0 {
		log.Fatalf("negative tabwidth %d", *tabwidth)
	}

	// Determine file system to use.
	// TODO(gri) - fs and fsHttp should really be the same. Try to unify.
	//           - fsHttp doesn't need to be set up in command-line mode,
	//             same is true for the http handlers in initHandlers.
	if *zipfile == "" {
		// use file system of underlying OS
		*goroot = filepath.Clean(*goroot) // normalize path separator
		fs = OS
		fsHttp = http.Dir(*goroot)
	} 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)
		}
		*goroot = path.Join("/", *goroot) // fsHttp paths are relative to '/'
		fs = NewZipFS(rc)
		fsHttp = NewHttpZipFS(rc, *goroot)
	}

	readTemplates()
	initHandlers()

	if *httpAddr != "" {
		// 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")
			}
			if !fsMap.IsEmpty() {
				log.Print("user-defined mapping:")
				fsMap.Fprint(os.Stderr)
			}
			handler = loggingHandler(handler)
		}

		registerPublicHandlers(http.DefaultServeMux)
		if *syncCmd != "" {
			http.Handle("/debug/sync", http.HandlerFunc(dosync))
		}

		// Initialize default directory tree with corresponding timestamp.
		// (Do it in a goroutine so that launch is quick.)
		go initFSTree()

		// Initialize directory trees for user-defined file systems (-path flag).
		initDirTrees()

		// Start sync goroutine, if enabled.
		if *syncCmd != "" && *syncMin > 0 {
			syncDelay.set(*syncMin) // initial sync delay
			go func() {
				for {
					dosync(nil, nil)
					delay, _ := syncDelay.get()
					if *verbose {
						log.Printf("next sync in %dmin", delay.(int))
					}
					time.Sleep(int64(delay.(int)) * 60e9)
				}
			}()
		}

		// Start indexing goroutine.
		if *indexEnabled {
			go indexer()
		}

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

		return
	}

	// Command line mode.
	if *html {
		packageText = packageHTML
		searchText = packageHTML
	}

	if *query {
		// Command-line queries.
		for i := 0; i < flag.NArg(); i++ {
			res, err := remoteSearch(flag.Arg(i))
			if err != nil {
				log.Fatalf("remoteSearch: %s", err)
			}
			io.Copy(os.Stdout, res.Body)
		}
		return
	}

	// determine paths
	path := flag.Arg(0)
	if len(path) > 0 && path[0] == '.' {
		// assume cwd; don't assume -goroot
		cwd, _ := os.Getwd() // ignore errors
		path = filepath.Join(cwd, path)
	}
	relpath := path
	abspath := path
	if t, pkg, err := build.FindTree(path); err == nil {
		relpath = pkg
		abspath = filepath.Join(t.SrcDir(), pkg)
	} else if !filepath.IsAbs(path) {
		abspath = absolutePath(path, pkgHandler.fsRoot)
	} else {
		relpath = relativeURL(path)
	}

	var mode PageInfoMode
	if *srcMode {
		// only filter exports if we don't have explicit command-line filter arguments
		if flag.NArg() == 1 {
			mode |= exportsOnly
		}
	} else {
		mode = exportsOnly | genDoc
	}
	// TODO(gri): Provide a mechanism (flag?) to select a package
	//            if there are multiple packages in a directory.
	info := pkgHandler.getPageInfo(abspath, relpath, "", mode)

	if info.IsEmpty() {
		// try again, this time assume it's a command
		if !filepath.IsAbs(path) {
			abspath = absolutePath(path, cmdHandler.fsRoot)
		}
		cmdInfo := cmdHandler.getPageInfo(abspath, relpath, "", mode)
		// only use the cmdInfo if it actually contains a result
		// (don't hide errors reported from looking up a package)
		if !cmdInfo.IsEmpty() {
			info = cmdInfo
		}
	}
	if info.Err != nil {
		log.Fatalf("%v", info.Err)
	}

	// If we have more than one argument, use the remaining arguments for filtering
	if flag.NArg() > 1 {
		args := flag.Args()[1:]
		rx := makeRx(args)
		if rx == nil {
			log.Fatalf("illegal regular expression from %v", args)
		}

		filter := func(s string) bool { return rx.MatchString(s) }
		switch {
		case info.PAst != nil:
			ast.FilterFile(info.PAst, filter)
			// Special case: Don't use templates for printing
			// so we only get the filtered declarations without
			// package clause or extra whitespace.
			for i, d := range info.PAst.Decls {
				if i > 0 {
					fmt.Println()
				}
				if *html {
					var buf bytes.Buffer
					writeNode(&buf, info.FSet, d)
					FormatText(os.Stdout, buf.Bytes(), -1, true, "", nil)
				} else {
					writeNode(os.Stdout, info.FSet, d)
				}
				fmt.Println()
			}
			return

		case info.PDoc != nil:
			info.PDoc.Filter(filter)
		}
	}

	if err := packageText.Execute(os.Stdout, info); err != nil {
		log.Printf("packageText.Execute: %s", err)
	}
}
Beispiel #24
0
// Serve files from 'root', stripping 'prefix' from the URL being requested
func FileServer(root, prefix string) Component {
	handler := http.StripPrefix(prefix, http.FileServer(http.Dir(root)))
	return NewHandlerComponent(handler)
}