(rw http.ResponseWriter, req *http.Request)
| 361 | } |
| 362 | |
| 363 | func (sh *SyncHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { |
| 364 | if req.Method == "POST" { |
| 365 | if req.FormValue("mode") == "validate" { |
| 366 | token := req.FormValue("token") |
| 367 | if xsrftoken.Valid(token, auth.Token(), "user", "runFullValidate") { |
| 368 | sh.startFullValidation() |
| 369 | http.Redirect(rw, req, "./", http.StatusFound) |
| 370 | return |
| 371 | } |
| 372 | } |
| 373 | http.Error(rw, "Bad POST request", http.StatusBadRequest) |
| 374 | return |
| 375 | } |
| 376 | |
| 377 | // TODO: remove this lock and instead just call currentStatus, |
| 378 | // and transition to using that here. |
| 379 | sh.mu.Lock() |
| 380 | defer sh.mu.Unlock() |
| 381 | f := func(p string, a ...interface{}) { |
| 382 | fmt.Fprintf(rw, p, a...) |
| 383 | } |
| 384 | now := time.Now() |
| 385 | f("<h1>Sync Status (for %s to %s)</h1>", sh.fromName, sh.toName) |
| 386 | f("<p><b>Current status: </b>%s</p>", html.EscapeString(sh.status)) |
| 387 | if sh.idle { |
| 388 | return |
| 389 | } |
| 390 | |
| 391 | f("<h2>Stats:</h2><ul>") |
| 392 | f("<li>Source: %s</li>", html.EscapeString(storageDesc(sh.from))) |
| 393 | f("<li>Target: %s</li>", html.EscapeString(storageDesc(sh.to))) |
| 394 | f("<li>Blobs synced: %d</li>", sh.totalCopies) |
| 395 | f("<li>Bytes synced: %d</li>", sh.totalCopyBytes) |
| 396 | f("<li>Blobs yet to copy: %d</li>", len(sh.needCopy)) |
| 397 | f("<li>Bytes yet to copy: %d</li>", sh.bytesRemain) |
| 398 | if !sh.recentCopyTime.IsZero() { |
| 399 | f("<li>Most recent copy: %s (%v ago)</li>", sh.recentCopyTime.Format(time.RFC3339), now.Sub(sh.recentCopyTime)) |
| 400 | } |
| 401 | clarification := "" |
| 402 | if len(sh.needCopy) == 0 && sh.totalErrors > 0 { |
| 403 | clarification = "(all since resolved)" |
| 404 | } |
| 405 | f("<li>Previous copy errors: %d %s</li>", sh.totalErrors, clarification) |
| 406 | f("</ul>") |
| 407 | |
| 408 | if sh.comparedRounds > 0 || sh.comparedBlobs > 0 { |
| 409 | f("<h2>Hourly compares</h2><ul>") |
| 410 | f("<li>Hourly rounds: %d</li>", sh.comparedRounds) |
| 411 | f("<li>Compared blobs: %d</li>", sh.comparedBlobs) |
| 412 | f("<li>Compared bytes: %d</li>", sh.comparedBytes) |
| 413 | f("<li>Latest blob: %s</li>", sh.compLastBlob) |
| 414 | f("</ul>") |
| 415 | if len(sh.compareErrors) > 0 { |
| 416 | f("<h3>Compare failures</h3><ul>") |
| 417 | for _, err := range sh.compareErrors { |
| 418 | f("<li><strong>%s</strong></li>", err) |
| 419 | } |
| 420 | f("</ul>") |
nothing calls this directly
no test coverage detected