| 45 | ) |
| 46 | |
| 47 | func startHTTPServer(addr, token, keyAuth string) *http.Server { |
| 48 | srv := &http.Server{ |
| 49 | Addr: addr, |
| 50 | ReadHeaderTimeout: 15 * time.Second, |
| 51 | } |
| 52 | |
| 53 | http.HandleFunc(fmt.Sprintf("/.well-known/acme-challenge/%s", token), func(w http.ResponseWriter, _ *http.Request) { |
| 54 | w.Header().Set("Content-Type", "application/octet-stream") |
| 55 | w.Write([]byte(keyAuth)) |
| 56 | }) |
| 57 | |
| 58 | go func() { |
| 59 | // returns ErrServerClosed on graceful close |
| 60 | if err := srv.ListenAndServe(); err != http.ErrServerClosed { |
| 61 | // NOTE: there is a chance that next line won't have time to run, |
| 62 | // as main() doesn't wait for this goroutine to stop. don't use |
| 63 | // code with race conditions like these for production. see post |
| 64 | // comments below on more discussion on how to handle this. |
| 65 | ui.Printf("\nListenAndServe(): %s\n", err) |
| 66 | } |
| 67 | }() |
| 68 | |
| 69 | // returning reference so caller can call Shutdown() |
| 70 | return srv |
| 71 | } |
| 72 | |
| 73 | type issueMode interface { |
| 74 | Run() error |