main_vm.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. // Copyright 2011 Google Inc. All rights reserved.
  2. // Use of this source code is governed by the Apache 2.0
  3. // license that can be found in the LICENSE file.
  4. // +build !appengine
  5. package internal
  6. import (
  7. "io"
  8. "log"
  9. "net/http"
  10. "net/url"
  11. "os"
  12. "path/filepath"
  13. "runtime"
  14. )
  15. func Main() {
  16. MainPath = filepath.Dir(findMainPath())
  17. installHealthChecker(http.DefaultServeMux)
  18. port := "8080"
  19. if s := os.Getenv("PORT"); s != "" {
  20. port = s
  21. }
  22. host := ""
  23. if IsDevAppServer() {
  24. host = "127.0.0.1"
  25. }
  26. if err := http.ListenAndServe(host+":"+port, http.HandlerFunc(handleHTTP)); err != nil {
  27. log.Fatalf("http.ListenAndServe: %v", err)
  28. }
  29. }
  30. // Find the path to package main by looking at the root Caller.
  31. func findMainPath() string {
  32. pc := make([]uintptr, 100)
  33. n := runtime.Callers(2, pc)
  34. frames := runtime.CallersFrames(pc[:n])
  35. for {
  36. frame, more := frames.Next()
  37. // Tests won't have package main, instead they have testing.tRunner
  38. if frame.Function == "main.main" || frame.Function == "testing.tRunner" {
  39. return frame.File
  40. }
  41. if !more {
  42. break
  43. }
  44. }
  45. return ""
  46. }
  47. func installHealthChecker(mux *http.ServeMux) {
  48. // If no health check handler has been installed by this point, add a trivial one.
  49. const healthPath = "/_ah/health"
  50. hreq := &http.Request{
  51. Method: "GET",
  52. URL: &url.URL{
  53. Path: healthPath,
  54. },
  55. }
  56. if _, pat := mux.Handler(hreq); pat != healthPath {
  57. mux.HandleFunc(healthPath, func(w http.ResponseWriter, r *http.Request) {
  58. io.WriteString(w, "ok")
  59. })
  60. }
  61. }