Example #1
0
// FetchHash issues a FileContent RPC to read an entire file.
func FetchFromContentServer(client *rpc.Client, rpcName string, size int64, hash []byte) []byte {
	chunkSize := 1 << 18

	buf := bytes.NewBuffer(make([]byte, 0, size))
	for {
		req := &ContentRequest{
			Hash:  hash,
			Start: buf.Len(),
			End:   buf.Len() + chunkSize,
		}

		rep := &ContentResponse{}
		err := client.Call(rpcName, req, rep)
		if err != nil && err != os.EOF {
			log.Println("FileContent error:", err)
			break
		}

		buf.Write(rep.Chunk)
		if len(rep.Chunk) < chunkSize {
			break
		}
	}

	if buf.Len() < int(size) {
		log.Fatal("Size mismatch", buf.Len(), size)
	}
	return buf.Bytes()
}
Example #2
0
// FetchHash issues a FileContent RPC to read an entire file, and store into ContentCache.
//
// TODO - open a connection for this instead.
func FetchBetweenContentServers(client *rpc.Client, rpcName string, size int64, hash string,
	dest *ContentCache) os.Error {
	chunkSize := 1 << 18

	output := dest.NewHashWriter()
	written := 0
	for {
		req := &ContentRequest{
			Hash:  hash,
			Start: written,
			End:   written + chunkSize,
		}

		rep := &ContentResponse{}
		err := client.Call(rpcName, req, rep)
		if err != nil {
			log.Println("FileContent error:", err)
			return err
		}

		n, err := output.Write(rep.Chunk)
		written += n
		if err != nil {
			return err
		}
		if len(rep.Chunk) < chunkSize {
			break
		}
	}

	if written < int(size) {
		return os.NewError(
			fmt.Sprintf("Size mismatch %d != %d", written, size))
	}

	output.Close()
	saved := string(output.hasher.Sum())
	if saved != hash {
		log.Fatalf("Corruption: savedHash %x != requested hash %x.", saved, hash)
	}
	return nil
}