public static async Task <Responses.UploadResponse> UploadAsync( string auth_url, string db_url, string username, string password, long datasize, string datatype, string datestr, string devicestr, string timestr, string userstr, IEnumerable <byte[]> callback ) { var header = new Requests.UploadHeader(); header.datasize = (ulong)datasize; header.datatype = datatype; header.datestr = datestr; header.devicestr = devicestr; header.timestr = timestr; header.userstr = userstr; var payload = JsonConvert.SerializeObject(header); var packet = await API.Auth.BuildAuthWithPayloadAsync( auth_url, username, password, payload ); var packet_bytes = Encoding.UTF8.GetBytes($"{packet}\n"); var wr = WebRequest.Create($"{db_url}/upload"); wr.ContentType = "text/json"; wr.Method = "POST"; ((HttpWebRequest)wr).AllowWriteStreamBuffering = false; ((HttpWebRequest)wr).SendChunked = true; // When sending a very long post this might need to be turned off // since it can cause an abrupt canceling of the request. ((HttpWebRequest)wr).KeepAlive = false; var reqstream = await wr.GetRequestStreamAsync(); await reqstream.WriteAsync(packet_bytes, 0, packet_bytes.Length); foreach (var stream_chunk in callback) { await reqstream.WriteAsync(stream_chunk, 0, stream_chunk.Length); } reqstream.Close(); var chunk = new byte[1024]; var resp = await wr.GetResponseAsync(); var rstream = resp.GetResponseStream(); var resp_length = await rstream.ReadAsync(chunk, 0, chunk.Length); var resp_text = Encoding.UTF8.GetString(chunk, 0, resp_length); return(JsonConvert.DeserializeObject <Responses.UploadResponse>(resp_text)); }
public static async Task <Responses.UploadResponse> UploadAsync( string auth_url, string db_url, string username, string password, long datasize, string datatype, string datestr, string devicestr, string timestr, string userstr, Stream data ) { var header = new Requests.UploadHeader(); header.datasize = (ulong)datasize; header.datatype = datatype; header.datestr = datestr; header.devicestr = devicestr; header.timestr = timestr; header.userstr = userstr; var payload = JsonConvert.SerializeObject(header); Console.WriteLine("Waiting for auth..."); var packet = await API.Auth.BuildAuthWithPayloadAsync( auth_url, username, password, payload ); Console.WriteLine("Got auth..."); var packet_bytes = Encoding.UTF8.GetBytes($"{packet}\n"); var wr = WebRequest.Create($"{db_url}/upload"); wr.ContentType = "text/json"; wr.Method = "POST"; // Workaround, TODO, BUG: The server is not likely correctly doing something which causes // the connection to hang since the subsystem appears to be reusing // the sockets (which is appropriate and good) yet without forcing // a new connection this will cause hangs/failures in the code below. wr.ConnectionGroupName = DateTime.Now.ToString(); ((HttpWebRequest)wr).AllowWriteStreamBuffering = false; ((HttpWebRequest)wr).SendChunked = true; // When sending a very long post this might need to be turned off // since it can cause an abrupt canceling of the request. ((HttpWebRequest)wr).KeepAlive = false; wr.Timeout = 1000 * 30; var reqstreamTask = wr.GetRequestStreamAsync(); if (await Task.WhenAny(reqstreamTask, Task.Delay(1000 * 12)) != reqstreamTask) { return(new Responses.UploadResponse() { success = false, fqpath = null, security_id = null, }); } var reqstream = reqstreamTask.Result; var firstWriteTask = reqstream.WriteAsync(packet_bytes, 0, packet_bytes.Length); if (await Task.WhenAny(firstWriteTask, Task.Delay(1000 * 12)) != firstWriteTask) { return(new Responses.UploadResponse() { success = false, fqpath = null, security_id = null, }); } Console.WriteLine("First write done."); int sent = 0; byte[] buf = new byte[1024 * 32]; while (sent < data.Length) { //Console.WriteLine("Read"); var amtTask = data.ReadAsync(buf, 0, buf.Length); if (await Task.WhenAny(amtTask, Task.Delay(1000 * 12)) != amtTask) { //Console.WriteLine("ReadTimeout"); return(new Responses.UploadResponse() { success = false, fqpath = null, security_id = null, }); } //Console.WriteLine("ReadDone"); var amt = amtTask.Result; // Is it possible for amt to be zero and that create an infinite loop here? // This checks for that condition since the documentation says zero means that // the end of the stream has been reached. if (amt < 1) { break; } //Console.WriteLine("Write"); var writeTask = reqstream.WriteAsync(buf, 0, amt); if (await Task.WhenAny(writeTask, Task.Delay(1000 * 12)) != writeTask) { //Console.WriteLine("WriteTimeout"); return(new Responses.UploadResponse() { success = false, fqpath = null, security_id = null, }); } //Console.WriteLine("WriteDone"); sent += amt; } Console.WriteLine("All writes done."); reqstream.Close(); var chunk = new byte[1024]; Console.WriteLine("Reading the response."); var respTask = wr.GetResponseAsync(); if (await Task.WhenAny(respTask, Task.Delay(1000 * 60 * 5)) != respTask) { return(new Responses.UploadResponse() { success = false, fqpath = null, security_id = null, }); } var rstream = respTask.Result.GetResponseStream(); var respBytesTask = rstream.ReadAsync(chunk, 0, chunk.Length); if (await Task.WhenAny(respBytesTask, Task.Delay(1000 * 60 * 5)) != respBytesTask) { return(new Responses.UploadResponse() { success = false, fqpath = null, security_id = null, }); } var respLength = respBytesTask.Result; var respText = Encoding.UTF8.GetString(chunk, 0, respLength); return(JsonConvert.DeserializeObject <Responses.UploadResponse>(respText)); }