/// <summary> /// Adds a query string to a <see cref="Uri"/> or replaces the existing query string. /// </summary> public static Uri WithQueryString(this Uri instance, QueryString qs) { if (instance == null) throw new ArgumentNullException("instance"); if (qs == null) throw new ArgumentNullException("qs"); var fragment = instance.GetComponents(UriComponents.Fragment, UriFormat.UriEscaped); var beforeQs = instance.GetComponents(UriComponents.AbsoluteUri & ~(UriComponents.Fragment | UriComponents.Query), UriFormat.UriEscaped); return new Uri(beforeQs + qs + fragment, instance.IsAbsoluteUri ? UriKind.Absolute : UriKind.Relative); }
private string TryDetermineIncomingMessageUrl() { if (_incomingSequenceReference == null || _sessionID == null) return null; var qs = new QueryString(); qs["sn"] = _incomingSequenceReference.ToString(); qs["sid"] = _sessionID.Value.ToString(); return IncomingRootUrl + qs; }
/// <summary> /// Executes a set of commands in a transaction, returning the results of those commands. /// This function can be called multiple times concurrently - the transactions will be executed sequentially. /// </summary> private async Task<JArray> ExecuteCommands(object[] commands, CancellationToken cancellationToken = default(CancellationToken)) { VerifyNotDisposed(); using (await AcquireLock(cancellationToken)) { var qs = new QueryString(); qs["id"] = unchecked(_sequenceID++).ToString(CultureInfo.InvariantCulture); if (_sessionID.HasValue) qs["sid"] = _sessionID.Value.ToString(); var url = OutgoingRootUrl + qs; var result = await _outgoingClient.PostAsJsonAsyncCancellationSafe(url, commands, cancellationToken); // Error codes here are a request-level error equivalent to EAGAIN (-3). result.EnsureSuccessStatusCode(); // API errors still come to us with 200 OK. // API errors are sometimes treated as results, e.g. for a two-command transaction, we could get back [-1, -1] // But SOMETIMES they are not results! We could just get back -3 and that's it. Bit of a pain in the ass... var responseBody = await result.Content.ReadAsStringAsync(); Debug.WriteLine(responseBody); var resultObject = JsonConvert.DeserializeObject(responseBody); JArray results; if (resultObject is JArray) results = (JArray)resultObject; // We got a list of result codes. else if (resultObject is long) results = new JArray(resultObject); // We got a single result code. Just wrap it in an array for processing. else throw new MegaException(responseBody); // Find any failure in the results and throw if found one. foreach (var r in results) ThrowOnFailureResult(r); return results; } }