// NewSnappyResponseWriter returns a `http.ResponseWriter` wrapper which can encode // the output with Snappy if requested by the client. // If snappy isn't enabled, it will act like a regular `http.ResponseWriter` // `Close` must be call so the `*snappy.Writer` instance can be put back in the `sync.Pool` func NewSnappyResponseWriter(rw http.ResponseWriter, r *http.Request) *snappyResponseWriter { var s *snappy.Writer // Set the necessary `Vary` header rw.Header().Set("Vary", "Accept-Encoding") // Disable caching of responses. rw.Header().Set("Cache-control", "no-cache") var writer io.Writer switch r.Header.Get("Accept-Encoding") { case "snappy": rw.Header().Set("Content-Encoding", "snappy") // Try to get a snappy.Writer from the pool if is := snappyWriterPool.Get(); is != nil { s = is.(*snappy.Writer) s.Reset(rw) } else { // Creates a new one if the pool is empty s = snappy.NewWriter(rw) } writer = s default: // No `Accept-Encoding` header (or unsupported) // Default to plain-text writer = rw } return &snappyResponseWriter{ snappyWriter: s, rw: rw, w: writer, } }
func (remote RemoteSnapshotsLoc) SendSnapshot(snapshot Snapshot, parent Timestamp) (err error) { var sendCmd *exec.Cmd if parent == "" { if verbosity > 1 { log.Println("Performing full send/receive") } sendCmd = exec.Command(btrfsBin, "send", snapshot.Path()) } else { if verbosity > 1 { log.Println("Performing incremental send/receive") } parentPath := path.Join(path.Dir(snapshot.Path()), string(parent)) sendCmd = exec.Command(btrfsBin, "send", "-p", parentPath, snapshot.Path()) } if verbosity > 1 { sendCmd.Stderr = os.Stderr } sendRd, sendWr := io.Pipe() defer sendRd.Close() var recvRunner CmdRunner var compOut *snappy.Writer closeComp := false if remote.Host == "" { sendCmd.Stdout = sendWr recvRunner = remote.SnapshotsLoc.ReceiveAndCleanUp(sendRd, snapshot.timestamp) } else { if *noCompressionFlag { sendCmd.Stdout = sendWr recvRunner = remote.RemoteReceive(sendRd, snapshot.timestamp) } else { compOut = snappy.NewBufferedWriter(sendWr) closeComp = true sendCmd.Stdout = compOut recvRunner = remote.RemoteReceive(sendRd, snapshot.timestamp) } } sendRunner := RunCommand(sendCmd) err = <-recvRunner.Started if err != nil { log.Println("Error starting btrfs receive") return } if verbosity > 1 { printCommand(sendCmd) } err = <-sendRunner.Started if err != nil { log.Println("Error starting btrfs send") return } select { case err = <-sendRunner.Done: if err != nil { log.Println("Error running btrfs send") } if closeComp { compOut.Close() } sendWr.Close() <-recvRunner.Done return case err = <-recvRunner.Done: if err != nil { log.Println("Error running btrfs receive") } sendRunner.Signal <- os.Kill <-sendRunner.Done return } }