Hallo zusammen,
ich verusche aktuell eine eigene Library zum erstellen/hochladen von Backups zu schreiben.
Soweit funktioniert die HTTP/2 verbindung auch, jedoch kann ich keine Fixed Indexes hochladen.
Testweise lade ich zwei, 4MB chunks hoch. Diese werden auch mit dem richtigen digest bestätigt:
Anschließend schließe ich den Fixed Index. Jedoch nicht erfolgreich.
Die Fehlermeldung im Log ist folgende:
Heißt also für mich, die chunks kommen an, werden verarbeitet (sonst gäbe es keine rückmeldung mit dem digest) jedoch muss beim schließen des Index etwas falsch laufen. Ich komme jedoch nicht drauf.
Ebenso werden blobs nicht automatisch in den Index übernommen, ich muss bei Ende des Backups ein index.json hochladen damit das Backup nicht fehlschlägt.
Tut dies der PBS nicht selber anlegen wie in der Doku beschrieben?
Hier noch mein code zum hochladen der chunks, etc.
ich verusche aktuell eine eigene Library zum erstellen/hochladen von Backups zu schreiben.
Soweit funktioniert die HTTP/2 verbindung auch, jedoch kann ich keine Fixed Indexes hochladen.
Testweise lade ich zwei, 4MB chunks hoch. Diese werden auch mit dem richtigen digest bestätigt:
Code:
{"data":"bb9f8df61474d25e71fa00722318cd387396ca1736605e1248821cc0de3d3af8"}
Anschließend schließe ich den Fixed Index. Jedoch nicht erfolgreich.
Die Fehlermeldung im Log ist folgende:
Code:
POST /fixed_close: 400 Bad Request: fixed writer 'sample.img.fidx' close failed - received wrong number of chunk (0 != 2)
Heißt also für mich, die chunks kommen an, werden verarbeitet (sonst gäbe es keine rückmeldung mit dem digest) jedoch muss beim schließen des Index etwas falsch laufen. Ich komme jedoch nicht drauf.
Ebenso werden blobs nicht automatisch in den Index übernommen, ich muss bei Ende des Backups ein index.json hochladen damit das Backup nicht fehlschlägt.
Tut dies der PBS nicht selber anlegen wie in der Doku beschrieben?
Hier noch mein code zum hochladen der chunks, etc.
C-like:
public async Task<bool> UploadBlobFile(string name, IDataBlob blob)
{
if (name.EndsWith(".blob"))
name.Substring(0, name.Length - 5);
byte[] data = await blob.RawByteFormat();
HeaderField[] headers = new HeaderField[]
{
new HeaderField { Name = ":method", Value = "POST" },
new HeaderField { Name = ":scheme", Value = "http" },
new HeaderField { Name = ":path", Value = $"/blob?file-name={name}.blob&encoded-size={data.Length}" },
};
var stream = await _connection.CreateStreamAsync(
headers, endOfStream: false);
await stream.WriteAsync(data, true);
// Wait for response headers
var reponseHeaders = await stream.ReadHeadersAsync();
if (reponseHeaders.First(s => s.Name == ":status").Value != "200")
return false;
// Read response data
StringBuilder sb = new StringBuilder();
byte[] buf = new byte[8192];
while (true)
{
var res = await stream.ReadAsync(new ArraySegment<byte>(buf));
if (res.EndOfStream) break;
var text = Encoding.UTF8.GetString(buf, 0, res.BytesRead);
sb.Append(text);
}
BackupFile file = new BackupFile()
{
Filename = name + ".blob",
CryptMode = blob.GetCryptMode(),
Size = blob.GetDataLength(),
Csum = blob.GetCsum(),
};
_index.Files.Add(file);
return true;
}
public async Task<int> CreateFixedIndex(string name, int size, bool reusecsum = false)
{
if (name.EndsWith(".fidx"))
name.Substring(0, name.Length - 5);
HeaderField[] headers = new HeaderField[]
{
new HeaderField { Name = ":method", Value = "POST" },
new HeaderField { Name = ":scheme", Value = "http" },
new HeaderField { Name = ":path", Value = $"/fixed_index?archive-name={name}.fidx&size={size}" },
};
var stream = await _connection.CreateStreamAsync(
headers, endOfStream: true);
// Wait for response headers
var reponseHeaders = await stream.ReadHeadersAsync();
if (reponseHeaders.First(s => s.Name == ":status").Value != "200")
return -1;
// Read response data
StringBuilder sb = new StringBuilder();
byte[] buf = new byte[8192];
while (true)
{
var res = await stream.ReadAsync(new ArraySegment<byte>(buf));
if (res.EndOfStream) break;
var text = Encoding.UTF8.GetString(buf, 0, res.BytesRead);
sb.Append(text);
}
var data = JsonConvert.DeserializeObject<WriterResponse>(sb.ToString());
return data.Data;
}
public async Task<string> UploadFixedChunk(int writer_id, byte[] data)
{
UnencryptedDataBlob blob = new UnencryptedDataBlob(data);
var _blobData = await blob.RawByteFormat();
var digest = BitConverter.ToString(SHA256.HashData(data)).Replace("-", "").ToLower();
HeaderField[] headers = new HeaderField[]
{
new HeaderField { Name = ":method", Value = "POST" },
new HeaderField { Name = ":scheme", Value = "http" },
new HeaderField { Name = ":path", Value = $"/fixed_chunk?digest={digest}&encoded-size={_blobData.Length}&size={data.Length}&wid={writer_id}" },
};
var stream = await _connection.CreateStreamAsync(
headers, endOfStream: false);
await stream.WriteAsync(_blobData, true);
// Wait for response headers
var reponseHeaders = await stream.ReadHeadersAsync();
if (reponseHeaders.First(s => s.Name == ":status").Value != "200")
return null;
// Read response data
StringBuilder sb = new StringBuilder();
byte[] buf = new byte[8192];
while (true)
{
var res = await stream.ReadAsync(new ArraySegment<byte>(buf));
if (res.EndOfStream) break;
var text = Encoding.UTF8.GetString(buf, 0, res.BytesRead);
sb.Append(text);
}
var resp = JsonConvert.DeserializeObject<ChunkResponse>(sb.ToString());
return resp.Data;
}
Last edited: