(rw http.ResponseWriter, r *http.Request)
| 100 | } |
| 101 | |
| 102 | func (w *Watcher) wakeFromHTTP(rw http.ResponseWriter, r *http.Request) (shouldNext bool) { |
| 103 | w.resetIdleTimer() |
| 104 | |
| 105 | // handle static files |
| 106 | switch r.URL.Path { |
| 107 | case idlewatcher.FavIconPath: |
| 108 | result, err := w.getFavIcon(r.Context()) |
| 109 | if err != nil { |
| 110 | rw.WriteHeader(result.StatusCode) |
| 111 | fmt.Fprint(rw, err) |
| 112 | return false |
| 113 | } |
| 114 | setNoStoreHeaders(rw.Header()) |
| 115 | serveStaticContent(rw, result.StatusCode, result.ContentType(), result.Icon) |
| 116 | return false |
| 117 | case idlewatcher.LoadingPageCSSPath: |
| 118 | setNoStoreHeaders(rw.Header()) |
| 119 | serveStaticContent(rw, http.StatusOK, "text/css", cssBytes) |
| 120 | return false |
| 121 | case idlewatcher.LoadingPageJSPath: |
| 122 | setNoStoreHeaders(rw.Header()) |
| 123 | serveStaticContent(rw, http.StatusOK, "application/javascript", jsBytes) |
| 124 | return false |
| 125 | case idlewatcher.WakeEventsPath: |
| 126 | w.handleWakeEventsSSE(rw, r) |
| 127 | return false |
| 128 | } |
| 129 | |
| 130 | // Allow request to proceed if the container is already ready. |
| 131 | // This check occurs after serving static files because a container can become ready quickly; |
| 132 | // otherwise, requests for assets may get a 404, leaving the user stuck on the loading screen. |
| 133 | if w.ready() { |
| 134 | return true |
| 135 | } |
| 136 | |
| 137 | // Check if start endpoint is configured and request path matches |
| 138 | if w.cfg.StartEndpoint != "" && r.URL.Path != w.cfg.StartEndpoint { |
| 139 | http.Error(rw, "Forbidden: Container can only be started via configured start endpoint", http.StatusForbidden) |
| 140 | return false |
| 141 | } |
| 142 | |
| 143 | accept := httputils.GetAccept(r.Header) |
| 144 | acceptHTML := (r.Method == http.MethodGet && accept.AcceptHTML() || r.RequestURI == "/" && accept.IsEmpty()) |
| 145 | |
| 146 | err := w.Wake(r.Context()) |
| 147 | if err != nil { |
| 148 | log.Err(err).Msg("Failed to wake container") |
| 149 | if !acceptHTML { |
| 150 | http.Error(rw, "Failed to wake container", http.StatusInternalServerError) |
| 151 | return false |
| 152 | } |
| 153 | } |
| 154 | |
| 155 | if !acceptHTML || w.cfg.NoLoadingPage { |
| 156 | // send a continue response to prevent client wait-header timeout |
| 157 | rw.WriteHeader(http.StatusContinue) |
| 158 | ready := w.waitForReady(r.Context()) |
| 159 | if !ready { |
no test coverage detected