Ejemplo n.º 1
0
// 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,
	}
}
Ejemplo n.º 2
0
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
	}
}