| 157 | } |
| 158 | |
| 159 | func (h *Handler) ServeHTTP(rw http.ResponseWriter, r *http.Request) { |
| 160 | err := h.secureHeaders.Process(rw, r) |
| 161 | if err != nil { |
| 162 | return |
| 163 | } |
| 164 | |
| 165 | // reqFile is the static file requested |
| 166 | reqFile := filePath(r.URL.Path) |
| 167 | state := htmlState{ |
| 168 | // Token is the CSRF token for the given request |
| 169 | CSRF: csrfState{Token: nosurf.Token(r)}, |
| 170 | BuildInfo: h.buildInfoJSON, |
| 171 | DocsURL: h.opts.DocsURL, |
| 172 | } |
| 173 | |
| 174 | // First check if it's a file we have in our templates |
| 175 | if h.serveHTML(rw, r, reqFile, state) { |
| 176 | return |
| 177 | } |
| 178 | |
| 179 | switch { |
| 180 | // If requesting binaries, serve straight up. |
| 181 | case reqFile == "bin" || strings.HasPrefix(reqFile, "bin/"): |
| 182 | h.handler.ServeHTTP(rw, r) |
| 183 | return |
| 184 | // If requesting assets, serve straight up with caching. |
| 185 | case reqFile == "assets" || strings.HasPrefix(reqFile, "assets/") || strings.HasPrefix(reqFile, "icon/"): |
| 186 | // It could make sense to cache 404s, but the problem is that during an |
| 187 | // upgrade a load balancer may route partially to the old server, and that |
| 188 | // would make new asset paths get cached as 404s and not load even once the |
| 189 | // new server was in place. To combat that, only cache if we have the file. |
| 190 | if h.exists(reqFile) && ShouldCacheFile(reqFile) { |
| 191 | rw.Header().Add("Cache-Control", "public, max-age=31536000, immutable") |
| 192 | } |
| 193 | // If the asset does not exist, this will return a 404. |
| 194 | h.handler.ServeHTTP(rw, r) |
| 195 | return |
| 196 | // If requesting the install.sh script, respond with the preprocessed version |
| 197 | // which contains the correct hostname and version information. |
| 198 | case reqFile == "install.sh": |
| 199 | if h.installScript == nil { |
| 200 | http.NotFound(rw, r) |
| 201 | return |
| 202 | } |
| 203 | rw.Header().Add("Content-Type", "text/plain; charset=utf-8") |
| 204 | http.ServeContent(rw, r, reqFile, time.Time{}, bytes.NewReader(h.installScript)) |
| 205 | return |
| 206 | // If the original file path exists we serve it. |
| 207 | case h.exists(reqFile): |
| 208 | if ShouldCacheFile(reqFile) { |
| 209 | rw.Header().Add("Cache-Control", "public, max-age=31536000, immutable") |
| 210 | } |
| 211 | h.handler.ServeHTTP(rw, r) |
| 212 | return |
| 213 | } |
| 214 | |
| 215 | // Serve the file assuming it's an html file |
| 216 | // This matches paths like `/app/terminal.html` |