main_vm.go 1.5 KB

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