Hello,
After some investigations, I found more stuff.
First, please consider the previous post as incorrect. Some things were not verified enough; I was having trouble trying too many thing concurrently (my brain is not thread-safe obviously).
A colleague found an intriguing workaround. He removed the metadata object that I was using and the request works.
Now I used Wireshark to determine what is happening on the wire.
Below is a working transaction that does not post metadata followed by a transaction with file metadata. It seems everything was done in a unique TCP stream.
It looks like metadata are given in HTTP headers and are problematic when they contain newlines (and other unexpected characters). Note the unexpected line returns between Remark and OriginalName at "tcp stream 2 | seq 977734" highlighted in red.
Before you look at the wireshark sample, here is how I create the metadata object. Note the newlines that I put in a metadata property.
// UI application code
model.Remark = "VCC temporary file. \r\nSessionKey: " + sessionKeyForThisFile + "\r\n";
domain.StoreTemporaryFile(model); // domain invocation
// domain code (inlined StoreTemporaryFile method and DAL methods)
var meta = new Dictionary<string, string>();
meta.Add("ExpireDate", model.ExpireDate.ToString("o"));
meta.Add("MimeType", model.MimeType);
meta.Add("Remark", model.Remark);
meta.Add("OriginalName", model.OriginalName);
var metadata = new RavenJObject();
if (data != null)
{
foreach (var item in data)
{
metadata.Add(item.Key, item.Value);
}
}
session.RegisterUpload(path, ms, metadata);
await session.SaveChangesAsync(); // crash
Now the wireshark sample:
[submit file with null metadata]
tcp stream 2 | seq 1 | client-to-raven
PUT /fs/test/files?name=Temp%2F0637bd45-5ec1-4f19-9dc3-a0df12fd3be2 HTTP/1.1
Raven-Client-Version: 3.5.4.0
RavenFS-Size: 977510
Host: pc-2:9000
Transfer-Encoding: chunked
Expect: 100-continue
tcp stream 2 | seq 1 | raven-to-client
HTTP/1.1 100 Continue
tcp stream 2 | seq [210..934610] | client-to-raven (+TCP ACKs)
[chunks of POST file]
tcp stream 2 | seq 26 | raven-to-client
HTTP/1.1 201 Created
Content-Length: 0
Server: Microsoft-HTTPAPI/2.0
Raven-Server-Build: 30115
Temp-Request-Time: 331
Date: Tue, 14 Nov 2017 17:48:02 GMT
[submit file with metadata]
tcp stream 2 | seq 977734 | client-to-raven
PUT /fs/test/files?name=Temp%2Fb90b22a2-5e20-43ab-9f5b-e7afd84d9f2d HTTP/1.1
Raven-Client-Version: 3.5.4.0
ExpireDate: 2017-12-14T17:48:08.7185602Z
MimeType: text/plain
Remark: VCC temporary file.
SessionKey: User/D05691506832B4D69D17044464B5/VCC/VC-33/File/b90b22a2-5e20-43ab-9f5b-e7afd84d9f2d
OriginalName: 20080212_1200_1210.stm
RavenFS-Size: 23639
Host: pc-2:9000
Transfer-Encoding: chunked
Expect: 100-continue
tcp stream 2 | seq 188 | raven-to-client
HTTP/1.1 400 Bad Request
Content-Type: text/html; charset=us-ascii
Server: Microsoft-HTTPAPI/2.0
Date: Tue, 14 Nov 2017 17:48:12 GMT
Connection: close
Content-Length: 334
<!DOCTYPE .....> (see previous post HTTP 400 response)
It now looks obvious that metadata are not sent in a safe way.
- Am I using them wrong?
- If I would fix that myself:
- I would consider sending metadata in a different dedicated query (big code time), or sending them with the file in a multipart request (non-obvious code change).
- I would also consider checking for unauthorized metadata characters during the upload phase with an exception thrown beforehand.
- Otherwise:
What do you think?