// 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() }
// 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 }