package web import ( "fmt" "log" "net/http" "strconv" "pcap-web-tools/internal/pcap" ) type reorderPage struct { MaxUpload string Error string } func (s *Server) handleReorderForm(w http.ResponseWriter, r *http.Request) { s.render(w, http.StatusOK, "reorder.html", "/reorder", reorderPage{MaxUpload: s.maxUpload()}) } func (s *Server) handleReorder(w http.ResponseWriter, r *http.Request) { page := reorderPage{MaxUpload: s.maxUpload()} fail := func(status int, msg string) { page.Error = msg s.render(w, status, "reorder.html", "/reorder", page) } file, hdr, status, msg := s.parseUpload(w, r) if status != 0 { fail(status, msg) return } defer file.Close() // Indexing reads the whole file, so problems are reported on the page // before any of the download is sent. ro, err := pcap.NewReorder(file, hdr.Size) if err != nil { fail(http.StatusBadRequest, hdr.Filename+": "+err.Error()) return } w.Header().Set("Content-Type", "application/vnd.tcpdump.pcap") w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%q", uploadStem(hdr)+"_reordered.pcap")) // Summary for scripted clients; browsers just save the file. w.Header().Set("X-Pcap-Packets", strconv.Itoa(ro.Packets())) w.Header().Set("X-Pcap-Out-Of-Order", strconv.Itoa(ro.OutOfOrder())) w.Header().Set("X-Pcap-Truncated", strconv.FormatBool(ro.Truncated())) if _, err := ro.WriteTo(w); err != nil { // The response has already started, so the error cannot be shown on the page. log.Printf("reorder %q: %v", hdr.Filename, err) } }