Exemple #1
0
        public StreamMetadata(
            int?maxCount    = null,
            TimeSpan?maxAge = null,
            StreamPosition?truncateBefore = null,
            TimeSpan?cacheControl         = null,
            StreamAcl?acl = null,
            JsonDocument?customMetadata = null) : this()
        {
            if (maxCount <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(maxCount));
            }

            if (maxAge <= TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException(nameof(maxAge));
            }

            if (cacheControl <= TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException(nameof(cacheControl));
            }

            MaxAge         = maxAge;
            TruncateBefore = truncateBefore;
            CacheControl   = cacheControl;
            Acl            = acl;
            MaxCount       = maxCount;
            CustomMetadata = customMetadata ?? JsonDocument.Parse("{}");
        }
        public override List <Version> GetVersions(JsonDocument?contentJSON)
        {
            List <Version> allVersions = new();

            if (contentJSON is null)
            {
                return(allVersions);
            }

            JsonElement root = contentJSON.RootElement;

            try
            {
                JsonElement versions = root.GetProperty("releases");
                foreach (JsonProperty version in versions.EnumerateObject())
                {
                    // TODO: Fails if not a valid semver. ex 0.2 https://github.com/microsoft/OSSGadget/issues/328
                    allVersions.Add(new Version(version.Name));
                }
            }
            catch (KeyNotFoundException) { return(allVersions); }
            catch (InvalidOperationException) { return(allVersions); }

            return(allVersions);
        }
        /// <summary>
        /// Gets the asset filename from the Webpack manifest.
        /// </summary>
        /// <param name="bundle">The name of the Webpack bundle.</param>
        /// <returns>The asset filename.</returns>
        public async Task <string?> GetFromManifestAsync(string bundle)
        {
            JsonDocument manifest;

            if (_manifest == null)
            {
                var json = _sharedSettings.DevelopmentMode
                    ? await FetchDevelopmentManifestAsync(HttpClient, _sharedSettings.ManifestPath).ConfigureAwait(false)
                    : await _fileSystem.File.ReadAllTextAsync(_sharedSettings.ManifestPath).ConfigureAwait(false);

                manifest = JsonDocument.Parse(json);
                if (!_sharedSettings.DevelopmentMode)
                {
                    _manifest = manifest;
                }
            }
            else
            {
                manifest = _manifest;
            }

            try
            {
                return(manifest.RootElement.GetProperty(bundle).GetString());
            }
            catch (KeyNotFoundException)
            {
                return(null);
            }
        }
Exemple #4
0
        public DockerComposeParser(string dockerComposeYmlContents)
        {
            try
            {
                using var reader = new StringReader(dockerComposeYmlContents);

                var deserializer = new DeserializerBuilder().Build();
                var yamlObject   = deserializer.Deserialize(reader);
                if (yamlObject == null)
                {
                    return;
                }

                var serializer = new SerializerBuilder()
                                 .JsonCompatible()
                                 .Build();

                var json = serializer.Serialize(yamlObject);
                this.dockerComposeModel = JsonDocument.Parse(json);
            }
            catch (SyntaxErrorException ex)
            {
                throw new DockerComposeSyntaxErrorException(ex);
            }
        }
Exemple #5
0
        private static async Task <bool> ValidateResponse(HttpResponseMessage response, System.Net.IPAddress newIPAddress)
        {
            if (response.StatusCode != System.Net.HttpStatusCode.OK)
            {
                Console.WriteLine($"Failed - HTTP status {response.StatusCode}");
                Console.WriteLine("Response content: ");
                Console.WriteLine(await response.Content.ReadAsStringAsync());
                Console.WriteLine();
                return(false);
            }

            try
            {
                JsonDocument?doc = await JsonDocument.ParseAsync(await response.Content.ReadAsStreamAsync());

                if (doc == null)
                {
                    throw new Exception("Response content missing");
                }

                var  root    = doc.RootElement;
                bool success = root.GetProperty("success").GetBoolean();

                if (!success)
                {
                    Console.WriteLine($"Failed - Errors:");

                    JsonElement.ArrayEnumerator errors = root.GetProperty("errors").EnumerateArray();
                    foreach (JsonElement error in errors)
                    {
                        int    errorCode    = error.GetProperty("code").GetInt32();
                        string?errorMessage = error.GetProperty("message").GetString();

                        Console.WriteLine($"{errorCode}: {errorMessage ?? ""}");
                    }
                    Console.WriteLine();
                    return(false);
                }

                string?resultContent = root.GetProperty("result").GetProperty("content").GetString();

                if (!System.Net.IPAddress.TryParse(resultContent, out System.Net.IPAddress? responseIP))
                {
                    throw new Exception("IP result contains invalid IP address.");
                }

                if (!newIPAddress.Equals(responseIP))
                {
                    throw new Exception("Incorrect IP returned");
                }

                Console.WriteLine("Done");
                return(true);
            }
            catch (Exception e)
            {
                Console.WriteLine($"Failed - {e.Message}");
                return(false);
            }
        }
Exemple #6
0
        /// <summary>Attempts to represent the current JSON object as a <see cref="JwtDocument"/>.</summary>
        /// <param name="value">Receives the value.</param>
        /// <returns>
        ///   <see langword="true"/> if the JSON object can be represented as a <see cref="JwtDocument"/>,
        ///   <see langword="false"/> otherwise.
        /// </returns>
        /// <exception cref="InvalidOperationException">
        ///   This value's <see cref="ValueKind"/> is not <see cref="JsonValueKind.Object"/>.
        /// </exception>
        public bool TryGetJsonDocument([NotNullWhen(true)] out JsonDocument?value)
        {
            if (_parent is null)
            {
                value = null;
                return(false);
            }

            return(_parent.TryGetValue(_idx, out value));
        }
Exemple #7
0
        public LogEntry Parse(string?line, LogEntry previousEntry)
        {
            if (string.IsNullOrEmpty(line))
            {
                return(LogEntry.Empty);
            }

            JsonDocument?json = JsonDocument.Parse(line);

            if (json == null)
            {
                return(LogEntry.Empty);
            }

            try
            {
                Guid        id = Guid.NewGuid();
                JsonElement jsonRootElement = json.RootElement;
                DateTime    timestamp       = DateTime.Parse(jsonRootElement.GetProperty("@t").GetString() ?? "01.01.1900");
                string      message         = jsonRootElement.GetProperty("@mt").GetString() ?? string.Empty;
                string      sourceContext   = jsonRootElement.GetProperty("SourceContext").GetString() ?? string.Empty;
                string?     callerMember    = null;
                if (jsonRootElement.TryGetProperty("CallerMemberName", out JsonElement callerMemberElement))
                {
                    callerMember = callerMemberElement.GetString();
                }

                TimeSpan durationSpan = TimeSpan.MinValue;
                if (jsonRootElement.TryGetProperty("DurationMilliseconds", out JsonElement durationMillisecondsElement))
                {
                    if (durationMillisecondsElement.ValueKind == JsonValueKind.Number)
                    {
                        ulong durationMilliseconds = durationMillisecondsElement.GetUInt64();
                        durationSpan = TimeSpan.FromMilliseconds(durationMilliseconds);
                    }
                    else if (durationMillisecondsElement.ValueKind == JsonValueKind.String)
                    {
                        string?rcDuration = durationMillisecondsElement.GetString();
                        durationSpan = string.IsNullOrEmpty(rcDuration) ? TimeSpan.MinValue : TimeSpan.Parse(rcDuration);
                    }
                }

                if (jsonRootElement.TryGetProperty("RcDuration", out JsonElement rcDurationElement))
                {
                    string?rcDuration = rcDurationElement.GetString();
                    durationSpan = string.IsNullOrEmpty(rcDuration) ? TimeSpan.MinValue : TimeSpan.Parse(rcDuration);
                }

                return(new LogEntry(id, previousEntry, timestamp, message, sourceContext, callerMember, durationSpan));
            }
            catch
            {
                return(LogEntry.Error);
            }
        }
        private static byte[] JsonDocumentToByteArray(JsonDocument?document)
        {
            if (document == null)
            {
                return(Array.Empty <byte>());
            }

            using var stream = new MemoryStream();
            using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions { Indented = false });

            document.WriteTo(writer);
            writer.Flush();

            return(stream.ToArray());
        }
Exemple #9
0
        internal bool TryGetValue(int index, [NotNullWhen(true)] out JsonDocument?value)
        {
            JsonRow row = _parsedData.Get(index);

            ReadOnlySpan <byte> data    = _utf8Json.Span;
            ReadOnlySpan <byte> segment = data.Slice(row.Location, row.Length);
            var reader = new Utf8JsonReader(segment);

            if (JsonDocument.TryParseValue(ref reader, out var doc))
            {
                _disposableRegistry.Add(doc);
                value = doc;
                return(true);
            }

            value = null;
            return(false);
        }
        protected override async Task Handle(StringBuilder contentBuilder)
        {
            var content = await _httpContent !.ReadAsStreamAsync();

            JsonDocument?jsonDocument = null;

            try
            {
                jsonDocument = await JsonDocument.ParseAsync(content, new JsonDocumentOptions
                {
                    AllowTrailingCommas = true
                });
            }
            catch
            {
                // ignored
            }

            if (jsonDocument != null)
            {
                // write the JsonDocument into a MemoryStream as indented
                using var stream = new MemoryStream();
                var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
                {
                    Indented = true
                });
                jsonDocument.WriteTo(writer);
                await writer.FlushAsync();

                stream.Seek(0, SeekOrigin.Begin);

                // get the string Json from the MemoryStream
                using var streamReader = new StreamReader(stream, Encoding.UTF8);

                var jsonString = await streamReader.ReadToEndAsync();

                contentBuilder.Append(jsonString);
            }
            else
            {
                // append the content as it is if it cannot be parsed as a json
                contentBuilder.Append(await _httpContent.ReadAsStringAsync());
            }
        }
Exemple #11
0
        public async Task GetCurriculum(int id, [FromBody] JsonDocument?request)
        {
            if (Request.Headers.GetCommaSeparatedValues("Authorization").ToList().Count < 1)
            {
                Response.StatusCode = 403;
                return;
            }

            string token = Request.Headers.GetCommaSeparatedValues("Authorization").ToList().ElementAt(0);

            if (UserHelpers.GetUser(token, _context).AccessLevel < (int)Permissions.Pupil)
            {
                Response.StatusCode = 403;
                return;
            }

            if (_context.Form.FirstOrDefault(row => row.Id == id) == null)
            {
                Response.StatusCode = 400;
                return;
            }

            DateTime date = DateTime.Now;

            JObject jValue = WebMessageHelpers.GetJObjectFromBody(request);

            if (jValue.ContainsKey("date"))
            {
                string strDate = jValue.GetValue("date").ToString();
                if (!String.IsNullOrWhiteSpace(strDate))
                {
                    date = Convert.ToDateTime(strDate);
                }
            }

            Response.Headers.Add("Access-Control-Allow-Headers", "*");
            Response.Headers.Add("Content-Type", "application/json");

            byte[] body = CuriculumHelpers.GetHomeWork(_context, id, date);
            await Response.Body.WriteAsync(body, 0, body.Length);
        }
        public override JsonElement?GetVersionElement(JsonDocument?contentJSON, Version version)
        {
            if (contentJSON is null)
            {
                return(null);
            }
            JsonElement root = contentJSON.RootElement;

            try
            {
                JsonElement versionsJSON = root.GetProperty("versions");
                foreach (JsonProperty versionProperty in versionsJSON.EnumerateObject())
                {
                    if (versionProperty.Name == version.ToString())
                    {
                        return(versionsJSON.GetProperty(version.ToString()));
                    }
                }
            }
            catch (KeyNotFoundException) { return(null); }
            catch (InvalidOperationException) { return(null); }

            return(null);
        }
        public override List <Version> GetVersions(JsonDocument?contentJSON)
        {
            List <Version> allVersions = new List <Version>();

            if (contentJSON is null)
            {
                return(allVersions);
            }

            JsonElement root = contentJSON.RootElement;

            try
            {
                JsonElement versions = root.GetProperty("versions");
                foreach (var version in versions.EnumerateObject())
                {
                    allVersions.Add(new Version(version.Name));
                }
            }
            catch (KeyNotFoundException) { return(allVersions); }
            catch (InvalidOperationException) { return(allVersions); }

            return(allVersions);
        }
        /// <summary>
        /// Download one PyPI package and extract it to the target directory.
        /// </summary>
        /// <param name="purl">Package URL of the package to download.</param>
        /// <returns>the path or file written.</returns>
        public override async Task <IEnumerable <string> > DownloadVersionAsync(PackageURL purl, bool doExtract, bool cached = false)
        {
            Logger.Trace("DownloadVersion {0}", purl?.ToString());

            string?       packageName     = purl?.Name;
            string?       packageVersion  = purl?.Version;
            List <string> downloadedPaths = new();

            if (string.IsNullOrWhiteSpace(packageName) || string.IsNullOrWhiteSpace(packageVersion))
            {
                Logger.Debug("Unable to download [{0} {1}]. Both must be defined.", packageName, packageVersion);
                return(downloadedPaths);
            }

            try
            {
                HttpClient httpClient = CreateHttpClient();

                JsonDocument?doc = await GetJsonCache(httpClient, $"{ENV_PYPI_ENDPOINT}/pypi/{packageName}/json");

                if (!doc.RootElement.TryGetProperty("releases", out JsonElement releases))
                {
                    return(downloadedPaths);
                }

                foreach (JsonProperty versionObject in releases.EnumerateObject())
                {
                    if (versionObject.Name != packageVersion)
                    {
                        continue;
                    }
                    foreach (JsonElement release in versionObject.Value.EnumerateArray())
                    {
                        if (!release.TryGetProperty("packagetype", out JsonElement packageType))
                        {
                            continue;   // Missing a package type
                        }

                        System.Net.Http.HttpResponseMessage result = await httpClient.GetAsync(release.GetProperty("url").GetString());

                        result.EnsureSuccessStatusCode();
                        string targetName = $"pypi-{packageType}-{packageName}@{packageVersion}";
                        string extension  = ".tar.gz";
                        if (packageType.ToString() == "bdist_wheel")
                        {
                            extension = ".whl";
                        }
                        string extractionPath = Path.Combine(TopLevelExtractionDirectory, targetName);
                        if (doExtract && Directory.Exists(extractionPath) && cached == true)
                        {
                            downloadedPaths.Add(extractionPath);
                            return(downloadedPaths);
                        }
                        if (doExtract)
                        {
                            downloadedPaths.Add(await ArchiveHelper.ExtractArchiveAsync(TopLevelExtractionDirectory, targetName, await result.Content.ReadAsStreamAsync(), cached));
                        }
                        else
                        {
                            extractionPath += extension;
                            await File.WriteAllBytesAsync(extractionPath, await result.Content.ReadAsByteArrayAsync());

                            downloadedPaths.Add(extractionPath);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Debug(ex, "Error downloading PyPI package: {0}", ex.Message);
            }
            return(downloadedPaths);
        }
Exemple #15
0
 public static bool DeepEquals(this JsonDocument left, JsonDocument?right)
 {
     return(DeepEquals(left.RootElement, right?.RootElement));
 }
Exemple #16
0
 /// <summary>
 ///   Attempts to parse one JSON value (including objects or arrays) from the provided reader.
 /// </summary>
 /// <param name="reader">The reader to read.</param>
 /// <param name="document">Receives the parsed document.</param>
 /// <returns>
 ///   <see langword="true"/> if a value was read and parsed into a JsonDocument,
 ///   <see langword="false"/> if the reader ran out of data while parsing.
 ///   All other situations result in an exception being thrown.
 /// </returns>
 /// <remarks>
 ///   <para>
 ///     If the <see cref="Utf8JsonReader.TokenType"/> property of <paramref name="reader"/>
 ///     is <see cref="JsonTokenType.PropertyName"/> or <see cref="JsonTokenType.None"/>, the
 ///     reader will be advanced by one call to <see cref="Utf8JsonReader.Read"/> to determine
 ///     the start of the value.
 ///   </para>
 ///
 ///   <para>
 ///     Upon completion of this method, <paramref name="reader"/> will be positioned at the
 ///     final token in the JSON value.  If an exception is thrown, or <see langword="false"/>
 ///     is returned, the reader is reset to the state it was in when the method was called.
 ///   </para>
 ///
 ///   <para>
 ///     This method makes a copy of the data the reader acted on, so there is no caller
 ///     requirement to maintain data integrity beyond the return of this method.
 ///   </para>
 /// </remarks>
 /// <exception cref="ArgumentException">
 ///   <paramref name="reader"/> is using unsupported options.
 /// </exception>
 /// <exception cref="ArgumentException">
 ///   The current <paramref name="reader"/> token does not start or represent a value.
 /// </exception>
 /// <exception cref="JsonException">
 ///   A value could not be read from the reader.
 /// </exception>
 public static bool TryParseValue(ref Utf8JsonReader reader, [NotNullWhen(true)] out JsonDocument?document)
 {
     return(TryParseValue(ref reader, out document, shouldThrow: false, useArrayPools: true));
 }
Exemple #17
0
            static PatchElement ReadElement(ref Utf8JsonReader reader)
            {
                if (reader.TokenType != JsonTokenType.StartObject)
                {
                    throw new JsonException(
                              $"Expected {nameof(JsonTokenType.StartObject)}");
                }

                // add = 0, remove = 1, replace = 2, copy = 3, move = 4,
                // test = 5
                int?         operation = null;
                JsonPointer? path      = null;
                JsonDocument?value     = null;
                JsonPointer? from      = null;

                while (reader.Read())
                {
                    if (reader.TokenType == JsonTokenType.EndObject)
                    {
                        break;
                    }

                    if (reader.TokenType != JsonTokenType.PropertyName)
                    {
                        throw new JsonException(
                                  $"Expected {nameof(JsonTokenType.PropertyName)}");
                    }

                    if (reader.ValueTextEquals("op"))
                    {
                        if (!reader.Read())
                        {
                            throw new JsonException();
                        }

                        if (reader.TokenType != JsonTokenType.String)
                        {
                            throw new JsonException(
                                      $"Expected {nameof(JsonTokenType.String)}");
                        }

                        if (reader.ValueTextEquals("add"))
                        {
                            operation = 0;
                        }
                        else if (reader.ValueTextEquals("remove"))
                        {
                            operation = 1;
                        }
                        else if (reader.ValueTextEquals("replace"))
                        {
                            operation = 2;
                        }
                        else if (reader.ValueTextEquals("copy"))
                        {
                            operation = 3;
                        }
                        else if (reader.ValueTextEquals("move"))
                        {
                            operation = 4;
                        }
                        else if (reader.ValueTextEquals("test"))
                        {
                            operation = 5;
                        }
                        else
                        {
                            throw new JsonException(
                                      "The 'op' field must be one of 'add', " +
                                      "'remove', 'replace', 'copy', 'move' or " +
                                      "'test'.");
                        }
                    }
                    else if (reader.ValueTextEquals("path"))
                    {
                        if (!reader.Read())
                        {
                            throw new JsonException();
                        }

                        if (reader.TokenType != JsonTokenType.String)
                        {
                            throw new JsonException(
                                      $"Expected {nameof(JsonTokenType.String)}");
                        }

                        if (!JsonPointer.TryParse(reader.GetString() !,
                                                  out path))
                        {
                            throw new JsonException(
                                      "Failed to parse JSON Pointer");
                        }
                    }
                    else if (reader.ValueTextEquals("value"))
                    {
                        if (!JsonDocument.TryParseValue(ref reader, out value))
                        {
                            throw new JsonException("Failed to parse value");
                        }
                    }
                    else if (reader.ValueTextEquals("from"))
                    {
                        if (!reader.Read())
                        {
                            throw new JsonException();
                        }

                        if (reader.TokenType != JsonTokenType.String)
                        {
                            throw new JsonException(
                                      $"Expected {nameof(JsonTokenType.String)}");
                        }

                        if (!JsonPointer.TryParse(reader.GetString() !,
                                                  out from))
                        {
                            throw new JsonException(
                                      "Failed to parse JSON Pointer");
                        }
                    }
                }

                return(operation switch
                {
                    // add
                    0 => new PatchAddElement(path !, value !),
                    // remove
                    1 => new PatchRemoveElement(path !),
                    // replace
                    2 => new PatchReplaceElement(path !, value !),
                    // copy
                    3 => new PatchCopyElement(path !, from !),
                    // move
                    4 => new PatchMoveElement(path !, from !),
                    // test
                    5 => new PatchTestElement(path !, value !),
                    // should never happen since we handle this above
                    _ => null !,
                });
Exemple #18
0
        internal static bool TryParseValue(
            ref Utf8JsonReader reader,
            [NotNullWhen(true)] out JsonDocument?document,
            bool shouldThrow,
            bool useArrayPools)
        {
            JsonReaderState state = reader.CurrentState;

            CheckSupportedOptions(state.Options, nameof(reader));

            // Value copy to overwrite the ref on an exception and undo the destructive reads.
            Utf8JsonReader restore = reader;

            ReadOnlySpan <byte>     valueSpan     = default;
            ReadOnlySequence <byte> valueSequence = default;

            try
            {
                switch (reader.TokenType)
                {
                // A new reader was created and has never been read,
                // so we need to move to the first token.
                // (or a reader has terminated and we're about to throw)
                case JsonTokenType.None:
                // Using a reader loop the caller has identified a property they wish to
                // hydrate into a JsonDocument. Move to the value first.
                case JsonTokenType.PropertyName:
                {
                    if (!reader.Read())
                    {
                        if (shouldThrow)
                        {
                            ThrowHelper.ThrowJsonReaderException(
                                ref reader,
                                ExceptionResource.ExpectedJsonTokens);
                        }

                        reader   = restore;
                        document = null;
                        return(false);
                    }

                    break;
                }
                }

                switch (reader.TokenType)
                {
                // Any of the "value start" states are acceptable.
                case JsonTokenType.StartObject:
                case JsonTokenType.StartArray:
                {
                    long startingOffset = reader.TokenStartIndex;

                    if (!reader.TrySkip())
                    {
                        if (shouldThrow)
                        {
                            ThrowHelper.ThrowJsonReaderException(
                                ref reader,
                                ExceptionResource.ExpectedJsonTokens);
                        }

                        reader   = restore;
                        document = null;
                        return(false);
                    }

                    long totalLength = reader.BytesConsumed - startingOffset;
                    ReadOnlySequence <byte> sequence = reader.OriginalSequence;

                    if (sequence.IsEmpty)
                    {
                        valueSpan = reader.OriginalSpan.Slice(
                            checked ((int)startingOffset),
                            checked ((int)totalLength));
                    }
                    else
                    {
                        valueSequence = sequence.Slice(startingOffset, totalLength);
                    }

                    Debug.Assert(
                        reader.TokenType == JsonTokenType.EndObject ||
                        reader.TokenType == JsonTokenType.EndArray);

                    break;
                }

                case JsonTokenType.False:
                case JsonTokenType.True:
                case JsonTokenType.Null:
                    if (useArrayPools)
                    {
                        if (reader.HasValueSequence)
                        {
                            valueSequence = reader.ValueSequence;
                        }
                        else
                        {
                            valueSpan = reader.ValueSpan;
                        }

                        break;
                    }

                    document = CreateForLiteral(reader.TokenType);
                    return(true);

                case JsonTokenType.Number:
                {
                    if (reader.HasValueSequence)
                    {
                        valueSequence = reader.ValueSequence;
                    }
                    else
                    {
                        valueSpan = reader.ValueSpan;
                    }

                    break;
                }

                // String's ValueSequence/ValueSpan omits the quotes, we need them back.
                case JsonTokenType.String:
                {
                    ReadOnlySequence <byte> sequence = reader.OriginalSequence;

                    if (sequence.IsEmpty)
                    {
                        // Since the quoted string fit in a ReadOnlySpan originally
                        // the contents length plus the two quotes can't overflow.
                        int payloadLength = reader.ValueSpan.Length + 2;
                        Debug.Assert(payloadLength > 1);

                        ReadOnlySpan <byte> readerSpan = reader.OriginalSpan;

                        Debug.Assert(
                            readerSpan[(int)reader.TokenStartIndex] == (byte)'"',
                            $"Calculated span starts with {readerSpan[(int)reader.TokenStartIndex]}");

                        Debug.Assert(
                            readerSpan[(int)reader.TokenStartIndex + payloadLength - 1] == (byte)'"',
                            $"Calculated span ends with {readerSpan[(int)reader.TokenStartIndex + payloadLength - 1]}");

                        valueSpan = readerSpan.Slice((int)reader.TokenStartIndex, payloadLength);
                    }
                    else
                    {
                        long payloadLength = 2;

                        if (reader.HasValueSequence)
                        {
                            payloadLength += reader.ValueSequence.Length;
                        }
                        else
                        {
                            payloadLength += reader.ValueSpan.Length;
                        }

                        valueSequence = sequence.Slice(reader.TokenStartIndex, payloadLength);
                        Debug.Assert(
                            valueSequence.First.Span[0] == (byte)'"',
                            $"Calculated sequence starts with {valueSequence.First.Span[0]}");

                        Debug.Assert(
                            valueSequence.ToArray()[payloadLength - 1] == (byte)'"',
                            $"Calculated sequence ends with {valueSequence.ToArray()[payloadLength - 1]}");
                    }

                    break;
                }

                default:
                {
                    if (shouldThrow)
                    {
                        // Default case would only hit if TokenType equals JsonTokenType.EndObject or JsonTokenType.EndArray in which case it would never be sequence
                        Debug.Assert(!reader.HasValueSequence);
                        byte displayByte = reader.ValueSpan[0];

                        ThrowHelper.ThrowJsonReaderException(
                            ref reader,
                            ExceptionResource.ExpectedStartOfValueNotFound,
                            displayByte);
                    }

                    reader   = restore;
                    document = null;
                    return(false);
                }
                }
            }
            catch
            {
                reader = restore;
                throw;
            }

            int length = valueSpan.IsEmpty ? checked ((int)valueSequence.Length) : valueSpan.Length;

            if (useArrayPools)
            {
                byte[] rented = ArrayPool <byte> .Shared.Rent(length);

                Span <byte> rentedSpan = rented.AsSpan(0, length);

                try
                {
                    if (valueSpan.IsEmpty)
                    {
                        valueSequence.CopyTo(rentedSpan);
                    }
                    else
                    {
                        valueSpan.CopyTo(rentedSpan);
                    }

                    document = Parse(rented.AsMemory(0, length), state.Options, rented);
                }
                catch
                {
                    // This really shouldn't happen since the document was already checked
                    // for consistency by Skip.  But if data mutations happened just after
                    // the calls to Read then the copy may not be valid.
                    rentedSpan.Clear();
                    ArrayPool <byte> .Shared.Return(rented);

                    throw;
                }
            }
            else
            {
                byte[] owned;

                if (valueSpan.IsEmpty)
                {
                    owned = valueSequence.ToArray();
                }
                else
                {
                    owned = valueSpan.ToArray();
                }

                document = ParseUnrented(owned, state.Options, reader.TokenType);
            }

            return(true);
        }
Exemple #19
0
        async public Task handleRequest(HttpContext httpContext)
        {
            if (Introspection && httpContext.Request.Path == "/ast.json" && httpContext.Request.Method.ToUpperInvariant() == "GET")
            {
                await httpContext.Response.WriteAsync(Api.GetAstJson());

                return;
            }

            Context?     context      = null;
            JsonDocument?bodyDocument = null;
            var          stopWatch    = new Stopwatch();

            stopWatch.Start();

            try
            {
                StringValues origin;
                if (DynamicCorsOrigin && httpContext.Request.Headers.TryGetValue("origin", out origin))
                {
                    httpContext.Response.Headers.Add("Access-Control-Allow-Origin", origin);
                    httpContext.Response.Headers.Add("Vary", "Origin");
                }

                string method = httpContext.Request.Method.ToUpperInvariant();

                foreach (var header in Headers)
                {
                    if (method == "OPTIONS" && !header.Key.ToLowerInvariant().StartsWith("access-control-"))
                    {
                        continue;
                    }

                    httpContext.Response.Headers.Add(header.Key, header.Value);
                }

                if (method == "OPTIONS")
                {
                    return;
                }

                httpContext.Response.Headers.Add("Content-Type", "application/json; charset=utf-8");

                if (method == "HEAD")
                {
                    return;
                }

                if (method == "GET")
                {
                    if (httpContext.Request.Path.Value != "/")
                    {
                        httpContext.Response.StatusCode = 404;
                        return;
                    }

                    var ok = false;
                    try
                    {
                        ok = await OnHealthCheck();
                    }
                    catch (Exception)
                    {
                    }

                    httpContext.Response.StatusCode = ok ? 200 : 500;
                    await httpContext.Response.WriteAsync(ok? "{\"ok\":true}" : "{\"ok\":false}");

                    return;
                }

                if (method != "POST")
                {
                    httpContext.Response.StatusCode = 404;
                    return;
                }

                bodyDocument = await JsonDocument.ParseAsync(httpContext.Request.Body);

                context         = ContextParser.DecodeContext(bodyDocument.RootElement, "body");
                context.Headers = httpContext.Request.Headers;
                // TODO: X-Forwarded-For with trusted proxies
                context.Ip = httpContext.Connection.RemoteIpAddress.ToString();

                var duration     = stopWatch.Elapsed.TotalSeconds;
                var bufferWriter = new ArrayBufferWriter <byte>();
                using (var resultWriter = new Utf8JsonWriter(bufferWriter))
                {
                    resultWriter.WriteStartObject();
                    resultWriter.WritePropertyName("result");
                    await Api.ExecuteFunction(context, resultWriter);

                    resultWriter.WriteNull("error");
                    resultWriter.WriteNumber("duration", duration);
                    resultWriter.WriteString("host", Dns.GetHostName());
                    resultWriter.WriteEndObject();
                }

                Console.WriteLine($"{context.Id} [{duration.ToString("0.000000")}s] {context.Name}() -> OK");

                await httpContext.Response.WriteAsync(Encoding.UTF8.GetString(bufferWriter.WrittenSpan));
            }
            catch (Exception error)
            {
                Console.WriteLine(error.ToString());
                SdkgenException sdkgenError;
                if (error is SdkgenException)
                {
                    sdkgenError = (error as SdkgenException) !;
                }
                else
                {
                    sdkgenError = new SdkgenException("Fatal", error.Message, error);
                }

                var duration = stopWatch.Elapsed.TotalSeconds;

                if (OnRequestError != null && context != null)
                {
                    OnRequestError.Invoke(context, sdkgenError);
                    Console.WriteLine($"{context.Id} [{duration.ToString("0.000000")}s] {context.Name}() -> {sdkgenError.Type}");
                }

                httpContext.Response.StatusCode = sdkgenError.Type == "Fatal" ? 500 : 400;

                using (var resultWriter = new Utf8JsonWriter(httpContext.Response.Body))
                {
                    resultWriter.WriteStartObject();
                    resultWriter.WriteNull("result");
                    resultWriter.WriteStartObject("error");
                    resultWriter.WriteString("type", sdkgenError.Type);
                    resultWriter.WriteString("message", sdkgenError.Message);
                    resultWriter.WriteEndObject();
                    resultWriter.WriteNumber("duration", duration);
                    resultWriter.WriteString("host", Dns.GetHostName());
                    resultWriter.WriteEndObject();
                }
            }
            finally
            {
                bodyDocument?.Dispose();
            }
        }