Skip to content

Commit

Permalink
fix stuff broken by porting to httpclient
Browse files Browse the repository at this point in the history
  • Loading branch information
mike-ward committed Apr 8, 2021
1 parent b25bdb0 commit 7a02885
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 44 deletions.
4 changes: 4 additions & 0 deletions src/tweetz.core/Commands/AddImageCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ private async ValueTask<string> UploadAsync(string filename, string mediaType)
{
var bytes = await File.ReadAllBytesAsync(filename).ConfigureAwait(false);
var media = await TwitterService.UploadMediaInit(bytes.Length, mediaType).ConfigureAwait(false);
if (media.MediaId is null) throw new Exception("error processing image init in UplaodAsync");
await TwitterService.UploadMediaAppend(media.MediaId, 0, bytes).ConfigureAwait(false);
var finalize = await TwitterService.UploadMediaFinalize(media.MediaId).ConfigureAwait(false);

Expand All @@ -99,7 +100,10 @@ private async ValueTask UntilProcessingFinishedAsync(string mediaId)
while (true)
{
var status = await TwitterService.UploadMediaStatus(mediaId).ConfigureAwait(false);
if (status.ProcessingInfo is null) throw new Exception("Image status processingInfo missing in UntilProcessingFinishedAsync");
if (status.ProcessingInfo.State.IsEqualTo(ProcessingInfo.StateSucceeded)) break;
if (status.ProcessingInfo.Error.Code != 0) throw new Exception(status.ProcessingInfo.Error.Message);
if (status.ProcessingInfo.CheckAfterSecs == 0) throw new Exception("Image status corrupted in UntilProcessingFinishedAsync");
var milliseconds = (int)TimeSpan.FromSeconds(status.ProcessingInfo.CheckAfterSecs).TotalMilliseconds;
await Task.Delay(milliseconds).ConfigureAwait(false);
}
Expand Down
4 changes: 2 additions & 2 deletions src/twitter.core/Models/UploadMedia.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace twitter.core.Models
public class UploadMedia
{
[JsonPropertyName("media_id_string")]
public string MediaId { get; set; } = string.Empty;
public string? MediaId { get; set; }

[JsonPropertyName("size")]
public int Size { get; set; }
Expand All @@ -14,6 +14,6 @@ public class UploadMedia
public int ExpiresAfterSecs { get; set; }

[JsonPropertyName("processing_info")]
public ProcessingInfo ProcessingInfo { get; set; } = ProcessingInfo.Empty;
public ProcessingInfo? ProcessingInfo { get; set; }
}
}
49 changes: 7 additions & 42 deletions src/twitter.core/Services/OAuthApiRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,6 @@ private async ValueTask<T> OAuthRequestAsync<T>(string url, IEnumerable<(string,

request.RequestUri = new Uri(url);
using var response = await MyHttpClient.SendAsync(request);

if (!response.IsSuccessStatusCode)
{
throw new HttpRequestException(response.ReasonPhrase, null, response.StatusCode);
}

var result = await JsonSerializer.DeserializeAsync<T>(await response.Content.ReadAsStreamAsync()).ConfigureAwait(false);
return result ?? throw new InvalidOperationException("JsonSerializer.DeserializeAsync<T>(stream) return null");
}
Expand All @@ -121,48 +115,19 @@ public async ValueTask AppendMediaAsync(string mediaId, int segmentIndex, byte[]
};
request.Headers.Add("Authorization", authorizeHeader);

var boundary = $"{Guid.NewGuid():N}";
var stream = new MemoryStream();
await TextParameterAsync(stream, boundary, "command", "APPEND").ConfigureAwait(false);
await TextParameterAsync(stream, boundary, "media_id", mediaId).ConfigureAwait(false);
await TextParameterAsync(stream, boundary, "segment_index", segmentIndex.ToString(CultureInfo.InvariantCulture)).ConfigureAwait(false);
await BinaryParameterAsync(stream, boundary, "media", payload).ConfigureAwait(false);
await WriteTextToStreamAsync(stream, $"--{boundary}--\r\n").ConfigureAwait(false);
stream.Flush();

request.Content = new StreamContent(stream);
request.Content.Headers.ContentType = new MediaTypeHeaderValue("multipart/form-data; boundary=" + boundary);
var form = new MultipartFormDataContent();
form.Add(new StringContent("APPEND"), "command");
form.Add(new StringContent(mediaId), "media_id");
form.Add(new StringContent(segmentIndex.ToString(CultureInfo.InvariantCulture)), "segment_index");
form.Add(new ByteArrayContent(payload), "media");
request.Content = form;

var response = await MyHttpClient.SendAsync(request).ConfigureAwait(false);

if (!response.IsSuccessStatusCode)
{
throw new HttpRequestException(response.ReasonPhrase, null, response.StatusCode);
}
}

private static async ValueTask TextParameterAsync(Stream stream, string boundary, string name, string payload)
{
var header = $"--{boundary}\r\nContent-Disposition: form-data; name=\"{name}\"\r\n\r\n";
await WriteTextToStreamAsync(stream, header).ConfigureAwait(false);
await WriteTextToStreamAsync(stream, payload).ConfigureAwait(false);
await WriteTextToStreamAsync(stream, "\r\n").ConfigureAwait(false);
}

private static async ValueTask BinaryParameterAsync(Stream stream, string boundary, string name, byte[] payload)
{
var header =
$"--{boundary}\r\nContent-Type: application/octet-stream\r\n" +
$"Content-Disposition: form-data; name=\"{name}\"\r\n\r\n";

await WriteTextToStreamAsync(stream, header).ConfigureAwait(false);
await stream.WriteAsync(payload.AsMemory(0, payload.Length)).ConfigureAwait(false);
await WriteTextToStreamAsync(stream, "\r\n").ConfigureAwait(false);
}

private static ValueTask WriteTextToStreamAsync(Stream stream, string text)
{
var buffer = Encoding.UTF8.GetBytes(text);
return stream.WriteAsync(buffer.AsMemory(0, buffer.Length));
}
}
}

0 comments on commit 7a02885

Please sign in to comment.