Beispiel #1
0
        /// <summary>
        /// API post using multipart/form-data.
        /// </summary>
        /// <param name="application">The full Uri you want to call (including any get parameters)</param>
        /// <param name="getParameters">Get parameters (or null if none)</param>
        /// <param name="postParameters">Post parameters as an  object or JObject
        /// </param>
        /// <returns>The result as a JObject, with MetaData filled in.</returns>
        public async Task <JObject> PostFormAsync(string application, object getParameters, object postParameters, params string[] fileParameterNames)
        {
            string uri = AddGetParams(makeUri(application), getParameters);

            using (DisposableCollection objectsToDispose = new DisposableCollection()) {
                MultipartFormDataContent content = objectsToDispose.Add(new MultipartFormDataContent());
                JObject data = postParameters.ToJObject();
                foreach (var o in data)
                {
                    if (o.Value.Type == JTokenType.Null)
                    {
                        continue;
                    }
                    if (Array.IndexOf(fileParameterNames, o.Key) >= 0)
                    {
                        string      filename = o.Value.ToString();
                        FileStream  fs       = objectsToDispose.Add(new FileStream(filename, FileMode.Open));
                        HttpContent v        = objectsToDispose.Add(new StreamContent(fs));
                        content.Add(v, o.Key, Path.GetFileName(filename));
                    }
                    else
                    {
                        HttpContent v = objectsToDispose.Add(new StringContent(o.Value.ToString()));
                        content.Add(v, o.Key);
                    }
                }
                return(await SendMessageAsync(HttpMethod.Post, uri, content));
            }
        }
Beispiel #2
0
        /// <summary>
        /// Send a message and get the result.
        /// Deal with rate limiting return values and redirects.
        /// </summary>
        /// <param name="method">Get/Post/etc.</param>
        /// <param name="uri">The full Uri you want to call (including any get parameters)</param>
        /// <param name="postParameters">Post parameters as an object or JObject</param>
        public async Task <HttpResponseMessage> SendMessageAsyncAndGetResponse(HttpMethod method, string uri, object postParameters = null)
        {
            LastRequest  = "";
            LastResponse = "";
            for (; ;)
            {
                string content = null;
                using (DisposableCollection disposeMe = new DisposableCollection()) {
                    var message = disposeMe.Add(new HttpRequestMessage(method, uri));
                    if (!string.IsNullOrEmpty(Settings.AccessToken))
                    {
                        message.Headers.Authorization = new AuthenticationHeaderValue("Bearer", Settings.AccessToken);
                    }
                    if (!string.IsNullOrEmpty(Settings.CsrfToken))
                    {
                        message.Headers.Add("X-CSRF-Token", Settings.CsrfToken);
                    }
                    message.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                    message.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/html"));
                    message.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
                    message.Headers.Add("User-Agent", Settings.ApplicationName);
                    if (postParameters != null)
                    {
                        if (postParameters is string s)
                        {
                            content         = s;
                            message.Content = disposeMe.Add(new StringContent(content, Encoding.UTF8, "text/plain"));
                        }
                        else if (postParameters is FileStream f)
                        {
                            content         = Path.GetFileName(f.Name);
                            f.Position      = 0;
                            message.Content = disposeMe.Add(new StreamContent(f));
                            string contentType = MimeMapping.MimeUtility.GetMimeMapping(content);
                            message.Content.Headers.ContentType        = new MediaTypeHeaderValue(contentType);
                            message.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
                            {
                                FileName = content
                            };
                            message.Content.Headers.ContentLength = f.Length;
                            content = "File: " + content;
                        }
                        else if (postParameters is HttpContent)
                        {
                            message.Content = (HttpContent)postParameters;
                        }
                        else
                        {
                            content         = postParameters.ToJson();
                            message.Content = disposeMe.Add(new StringContent(content, Encoding.UTF8, "application/json"));
                        }
                    }
                    LastRequest = $"{message}:{content}";
                    HttpResponseMessage result;
                    int backoff = 500;
                    int delay;
                    if (Settings.LogRequest > 0)
                    {
                        Log($"Sent -> {(Settings.LogRequest > 1 ? message.ToString() : message.RequestUri.ToString())}:{content}");
                    }
                    result = await _client.SendAsync(message);

                    LastResponse = result.ToString();
                    if (Settings.LogResult > 1)
                    {
                        Log($"Received -> {result}");
                    }
                    switch (result.StatusCode)
                    {
                    case HttpStatusCode.Found:                                  // Redirect
                        uri   = result.Headers.Location.AbsoluteUri;
                        delay = 1;
                        break;

                    case (HttpStatusCode)429:                                   // TooManyRequests
                        delay = 5000;
                        break;

                    case HttpStatusCode.BadGateway:
                    case HttpStatusCode.ServiceUnavailable:
                    case HttpStatusCode.GatewayTimeout:
                        backoff *= 2;
                        delay    = backoff;
                        if (delay > 16000)
                        {
                            return(result);
                        }
                        break;

                    default:
                        return(result);
                    }
                    result.Dispose();
                    Thread.Sleep(delay);
                }
            }
        }