public async Task <MultipartRequestParsedObjects <TModel> > ParseMultipartRequest <TModel>(HttpRequest request)
            where TModel : new()
        {
            var boundary = GetBoundary(MediaTypeHeaderValue.Parse(request.ContentType),
                                       _defaultFormOptions.MultipartBoundaryLengthLimit);
            var reader  = new MultipartReader(boundary, request.Body);
            var section = await reader.ReadNextSectionAsync();

            if (section == null)
            {
                return(null);
            }

            var apiModelTypeProperties = typeof(TModel).GetProperties();
            var response = new MultipartRequestParsedObjects <TModel>();

            do
            {
                var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition,
                                                                                         out ContentDispositionHeaderValue contentDisposition);

                if (hasContentDispositionHeader)
                {
                    if (contentDisposition.IsFileDisposition())
                    {
                        response.FileUploadRequest = new FileUploadRequest
                        {
                            Bytes    = section.Body.ToByteArray(),
                            FileName = section.AsFileSection().FileName
                        };
                    }

                    else if (contentDisposition.IsFormDisposition())
                    {
                        var key      = HeaderUtilities.RemoveQuotes(contentDisposition.Name).Value;
                        var encoding = GetEncoding(section);
                        using (var streamReader = new StreamReader(
                                   section.Body,
                                   encoding,
                                   true,
                                   1024,
                                   true))
                        {
                            // The value length limit is enforced by MultipartBodyLengthLimit
                            var stringedValue = await streamReader.ReadToEndAsync();

                            if (!(string.IsNullOrEmpty(stringedValue) || string.IsNullOrWhiteSpace(stringedValue)))
                            {
                                var prop = apiModelTypeProperties.FirstOrDefault(p => string.Equals(p.Name, key,
                                                                                                    StringComparison.OrdinalIgnoreCase));
                                if (prop != null)
                                {
                                    var converter = _converterManager.Get(prop.PropertyType);

                                    if (converter.CanConvertFrom(typeof(string)))
                                    {
                                        var value = converter.TypeConverter.ConvertFrom(stringedValue);
                                        prop.SetValue(response.Model, value);
                                    }
                                }
                            }
                        }
                    }
                }

                section = await reader.ReadNextSectionAsync();
            } while (section != null);

            // Drains any remaining section body that has not been consumed and
            // reads the headers for the next section.
            return(response);
        }
        public async Task <IActionResult> Post()
        {
            if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
            {
                return(BadRequest($"Expected a multipart request, but got {Request.ContentType}"));
            }

            // Used to accumulate all the form url encoded key value pairs in the
            // request.
            var    formAccumulator = new KeyValueAccumulator();
            string targetFilePath  = null;

            var boundary = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(Request.ContentType),
                _defaultFormOptions.MultipartBoundaryLengthLimit);
            var reader = new MultipartReader(boundary, HttpContext.Request.Body);

            var section = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                ContentDispositionHeaderValue contentDisposition;
                var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out contentDisposition);

                if (hasContentDispositionHeader)
                {
                    if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                    {
                        targetFilePath = Path.GetTempFileName();
                        using (var targetStream = System.IO.File.Create(targetFilePath))
                        {
                            await section.Body.CopyToAsync(targetStream);

                            Console.WriteLine($"Copied the uploaded file '{targetFilePath}'");
                        }
                    }
                    else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                    {
                        // Content-Disposition: form-data; name="key"
                        //
                        // value

                        // Do not limit the key name length here because the
                        // multipart headers length limit is already in effect.
                        var key      = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                        var encoding = GetEncoding(section);
                        using (var streamReader = new StreamReader(
                                   section.Body,
                                   encoding,
                                   detectEncodingFromByteOrderMarks: true,
                                   bufferSize: 1024,
                                   leaveOpen: true))
                        {
                            // The value length limit is enforced by MultipartBodyLengthLimit
                            var value = await streamReader.ReadToEndAsync();

                            if (String.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                            {
                                value = String.Empty;
                            }
                            formAccumulator.Append(key.ToString(), value);

                            if (formAccumulator.ValueCount > _defaultFormOptions.ValueCountLimit)
                            {
                                throw new InvalidDataException($"Form key count limit {_defaultFormOptions.ValueCountLimit} exceeded.");
                            }
                        }
                    }
                }

                // Drains any remaining section body that has not been consumed and
                // reads the headers for the next section.
                section = await reader.ReadNextSectionAsync();
            }
            IDictionary <string, StringValues> parameters = formAccumulator.GetResults();

            if (parameters.ContainsKey(PARAM_ID_CONCEPT_LIE))
            {
                Debugger.Log((int)LogLevel.Information, "Info", parameters[PARAM_ID_CONCEPT_LIE].ToString());
            }
            else
            {
                Debugger.Log((int)LogLevel.Error, "Info", $"La requête ne contenait pas le paramètre {PARAM_ID_CONCEPT_LIE}");
            }
            return(Ok(new
            {
                FilePath = targetFilePath
            }));
        }
Exemple #3
0
        public static async Task <string?> GetDigestTokenForCredential(NetworkCredential credential, HttpRequestMessage request, DigestResponse digestResponse)
        {
            StringBuilder sb = StringBuilderCache.Acquire();

            // It is mandatory for servers to implement sha-256 per RFC 7616
            // Keep MD5 for backward compatibility.
            string?algorithm;
            bool   isAlgorithmSpecified = digestResponse.Parameters.TryGetValue(Algorithm, out algorithm);

            if (isAlgorithmSpecified)
            {
                if (!algorithm !.Equals(Sha256, StringComparison.OrdinalIgnoreCase) &&
                    !algorithm.Equals(Md5, StringComparison.OrdinalIgnoreCase) &&
                    !algorithm.Equals(Sha256Sess, StringComparison.OrdinalIgnoreCase) &&
                    !algorithm.Equals(MD5Sess, StringComparison.OrdinalIgnoreCase))
                {
                    if (NetEventSource.Log.IsEnabled())
                    {
                        NetEventSource.Error(digestResponse, $"Algorithm not supported: {algorithm}");
                    }
                    return(null);
                }
            }
            else
            {
                algorithm = Md5;
            }

            // Check if nonce is there in challenge
            string?nonce;

            if (!digestResponse.Parameters.TryGetValue(Nonce, out nonce))
            {
                if (NetEventSource.Log.IsEnabled())
                {
                    NetEventSource.Error(digestResponse, "Nonce missing");
                }
                return(null);
            }

            // opaque token may or may not exist
            string?opaque;

            digestResponse.Parameters.TryGetValue(Opaque, out opaque);

            string?realm;

            if (!digestResponse.Parameters.TryGetValue(Realm, out realm))
            {
                if (NetEventSource.Log.IsEnabled())
                {
                    NetEventSource.Error(digestResponse, "Realm missing");
                }
                return(null);
            }

            // Add username
            string?userhash;

            if (digestResponse.Parameters.TryGetValue(UserHash, out userhash) && userhash == "true")
            {
                sb.AppendKeyValue(Username, ComputeHash(credential.UserName + ":" + realm, algorithm));
                sb.AppendKeyValue(UserHash, userhash, includeQuotes: false);
            }
            else
            {
                if (HeaderUtilities.ContainsNonAscii(credential.UserName))
                {
                    string usernameStar = HeaderUtilities.Encode5987(credential.UserName);
                    sb.AppendKeyValue(UsernameStar, usernameStar, includeQuotes: false);
                }
                else
                {
                    sb.AppendKeyValue(Username, credential.UserName);
                }
            }

            // Add realm
            sb.AppendKeyValue(Realm, realm);

            // Add nonce
            sb.AppendKeyValue(Nonce, nonce);

            Debug.Assert(request.RequestUri != null);
            // Add uri
            sb.AppendKeyValue(Uri, request.RequestUri.PathAndQuery);

            // Set qop, default is auth
            string qop            = Auth;
            bool   isQopSpecified = digestResponse.Parameters.ContainsKey(Qop);

            if (isQopSpecified)
            {
                // Check if auth-int present in qop string
                int index1 = digestResponse.Parameters[Qop].IndexOf(AuthInt, StringComparison.Ordinal);
                if (index1 != -1)
                {
                    // Get index of auth if present in qop string
                    int index2 = digestResponse.Parameters[Qop].IndexOf(Auth, StringComparison.Ordinal);

                    // If index2 < index1, auth option is available
                    // If index2 == index1, check if auth option available later in string after auth-int.
                    if (index2 == index1)
                    {
                        index2 = digestResponse.Parameters[Qop].IndexOf(Auth, index1 + AuthInt.Length, StringComparison.Ordinal);
                        if (index2 == -1)
                        {
                            qop = AuthInt;
                        }
                    }
                }
            }

            // Set cnonce
            string cnonce = GetRandomAlphaNumericString();

            // Calculate response
            string a1 = credential.UserName + ":" + realm + ":" + credential.Password;

            if (algorithm.EndsWith("sess", StringComparison.OrdinalIgnoreCase))
            {
                a1 = ComputeHash(a1, algorithm) + ":" + nonce + ":" + cnonce;
            }

            string a2 = request.Method.Method + ":" + request.RequestUri.PathAndQuery;

            if (qop == AuthInt)
            {
                string content = request.Content == null ? string.Empty : await request.Content.ReadAsStringAsync().ConfigureAwait(false);

                a2 = a2 + ":" + ComputeHash(content, algorithm);
            }

            string response;

            if (isQopSpecified)
            {
                response = ComputeHash(ComputeHash(a1, algorithm) + ":" +
                                       nonce + ":" +
                                       DigestResponse.NonceCount + ":" +
                                       cnonce + ":" +
                                       qop + ":" +
                                       ComputeHash(a2, algorithm), algorithm);
            }
            else
            {
                response = ComputeHash(ComputeHash(a1, algorithm) + ":" +
                                       nonce + ":" +
                                       ComputeHash(a2, algorithm), algorithm);
            }

            // Add response
            sb.AppendKeyValue(Response, response, includeComma: opaque != null || isAlgorithmSpecified || isQopSpecified);

            // Add opaque
            if (opaque != null)
            {
                sb.AppendKeyValue(Opaque, opaque, includeComma: isAlgorithmSpecified || isQopSpecified);
            }

            if (isAlgorithmSpecified)
            {
                // Add algorithm
                sb.AppendKeyValue(Algorithm, algorithm, includeQuotes: false, includeComma: isQopSpecified);
            }

            if (isQopSpecified)
            {
                // Add qop
                sb.AppendKeyValue(Qop, qop, includeQuotes: false);

                // Add nc
                sb.AppendKeyValue(NC, DigestResponse.NonceCount, includeQuotes: false);

                // Add cnonce
                sb.AppendKeyValue(CNonce, cnonce, includeComma: false);
            }

            return(StringBuilderCache.GetStringAndRelease(sb));
        }
 public virtual bool AllowCacheStorage(ResponseCachingContext context)
 {
     // Check request no-store
     return(!HeaderUtilities.ContainsCacheDirective(context.HttpContext.Request.Headers.CacheControl, CacheControlHeaderValue.NoStoreString));
 }
        public async Task PostImportAsync()
        {
            using (ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
            {
                if (HttpContext.Request.HasFormContentType == false)
                {
                    HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest; // Bad request
                    using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream()))
                    {
                        context.Write(writer, new DynamicJsonValue
                        {
                            ["Type"]  = "Error",
                            ["Error"] = "This endpoint requires form content type"
                        });
                        return;
                    }
                }

                var operationId = GetLongQueryString("operationId", false) ?? Database.Operations.GetNextOperationId();
                var token       = CreateOperationToken();

                var result = new SmugglerResult();
                await Database.Operations.AddOperation(Database, "Import to: " + Database.Name,
                                                       Operations.OperationType.DatabaseImport,
                                                       onProgress =>
                {
                    return(Task.Run(async() =>
                    {
                        try
                        {
                            var boundary = MultipartRequestHelper.GetBoundary(
                                MediaTypeHeaderValue.Parse(HttpContext.Request.ContentType),
                                MultipartRequestHelper.MultipartBoundaryLengthLimit);
                            var reader = new MultipartReader(boundary, HttpContext.Request.Body);
                            DatabaseSmugglerOptionsServerSide options = null;

                            while (true)
                            {
                                var section = await reader.ReadNextSectionAsync().ConfigureAwait(false);
                                if (section == null)
                                {
                                    break;
                                }

                                if (ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out ContentDispositionHeaderValue contentDisposition) == false)
                                {
                                    continue;
                                }

                                if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                                {
                                    var key = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                                    if (key != "importOptions")
                                    {
                                        continue;
                                    }

                                    BlittableJsonReaderObject blittableJson;
                                    if (section.Headers.ContainsKey("Content-Encoding") && section.Headers["Content-Encoding"] == "gzip")
                                    {
                                        using (var gzipStream = new GZipStream(section.Body, CompressionMode.Decompress))
                                        {
                                            blittableJson = await context.ReadForMemoryAsync(gzipStream, "importOptions");
                                        }
                                    }
                                    else
                                    {
                                        blittableJson = await context.ReadForMemoryAsync(section.Body, "importOptions");
                                    }

                                    options = JsonDeserializationServer.DatabaseSmugglerOptions(blittableJson);
                                    continue;
                                }

                                if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition) == false)
                                {
                                    continue;
                                }

                                var stream = new GZipStream(section.Body, CompressionMode.Decompress);
                                DoImportInternal(context, stream, options, result, onProgress, token);
                            }
                        }
                        catch (Exception e)
                        {
                            result.AddError($"Error occurred during import. Exception: {e.Message}");
                            onProgress.Invoke(result.Progress);
                            throw;
                        }

                        return (IOperationResult)result;
                    }));
                }, operationId, token).ConfigureAwait(false);

                WriteImportResult(context, result, ResponseBodyStream());
            }
    /// <summary>
    /// Finalize cache headers.
    /// </summary>
    /// <param name="context"></param>
    /// <returns><c>true</c> if a vary by entry needs to be stored in the cache; otherwise <c>false</c>.</returns>
    private bool OnFinalizeCacheHeaders(ResponseCachingContext context)
    {
        if (_policyProvider.IsResponseCacheable(context))
        {
            var storeVaryByEntry = false;
            context.ShouldCacheResponse = true;

            // Create the cache entry now
            var response      = context.HttpContext.Response;
            var headers       = response.Headers;
            var varyHeaders   = new StringValues(headers.GetCommaSeparatedValues(HeaderNames.Vary));
            var varyQueryKeys = new StringValues(context.HttpContext.Features.Get <IResponseCachingFeature>()?.VaryByQueryKeys);
            context.CachedResponseValidFor = context.ResponseSharedMaxAge ??
                                             context.ResponseMaxAge ??
                                             (context.ResponseExpires - context.ResponseTime !.Value) ??
                                             DefaultExpirationTimeSpan;

            // Generate a base key if none exist
            if (string.IsNullOrEmpty(context.BaseKey))
            {
                context.BaseKey = _keyProvider.CreateBaseKey(context);
            }

            // Check if any vary rules exist
            if (!StringValues.IsNullOrEmpty(varyHeaders) || !StringValues.IsNullOrEmpty(varyQueryKeys))
            {
                // Normalize order and casing of vary by rules
                var normalizedVaryHeaders   = GetOrderCasingNormalizedStringValues(varyHeaders);
                var normalizedVaryQueryKeys = GetOrderCasingNormalizedStringValues(varyQueryKeys);

                // Update vary rules if they are different
                if (context.CachedVaryByRules == null ||
                    !StringValues.Equals(context.CachedVaryByRules.QueryKeys, normalizedVaryQueryKeys) ||
                    !StringValues.Equals(context.CachedVaryByRules.Headers, normalizedVaryHeaders))
                {
                    context.CachedVaryByRules = new CachedVaryByRules
                    {
                        VaryByKeyPrefix = FastGuid.NewGuid().IdString,
                        Headers         = normalizedVaryHeaders,
                        QueryKeys       = normalizedVaryQueryKeys
                    };
                }

                // Always overwrite the CachedVaryByRules to update the expiry information
                _logger.VaryByRulesUpdated(normalizedVaryHeaders.ToString(), normalizedVaryQueryKeys.ToString());
                storeVaryByEntry = true;

                context.StorageVaryKey = _keyProvider.CreateStorageVaryByKey(context);
            }

            // Ensure date header is set
            if (!context.ResponseDate.HasValue)
            {
                context.ResponseDate = context.ResponseTime !.Value;
                // Setting the date on the raw response headers.
                headers.Date = HeaderUtilities.FormatDate(context.ResponseDate.Value);
            }

            // Store the response on the state
            context.CachedResponse = new CachedResponse
            {
                Created    = context.ResponseDate.Value,
                StatusCode = response.StatusCode,
                Headers    = new HeaderDictionary()
            };

            foreach (var header in headers)
            {
                if (!string.Equals(header.Key, HeaderNames.Age, StringComparison.OrdinalIgnoreCase))
                {
                    context.CachedResponse.Headers[header.Key] = header.Value;
                }
            }

            return(storeVaryByEntry);
        }

        context.ResponseCachingStream.DisableBuffering();
        return(false);
    }
Exemple #7
0
 private static string FormatInt64(long input)
 {
     return(HeaderUtilities.FormatNonNegativeInt64(input));
 }
Exemple #8
0
    /// <summary>
    /// Initializes a new instance of <see cref="StringWithQualityHeaderValue"/>.
    /// </summary>
    /// <param name="value">The <see cref="StringSegment"/> used to initialize the new instance.</param>
    public StringWithQualityHeaderValue(StringSegment value)
    {
        HeaderUtilities.CheckValidToken(value, nameof(value));

        _value = value;
    }
Exemple #9
0
        public override async Task <InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context)
        {
            if (context is null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            try
            {
                var request = context.HttpContext.Request;

                if (request.Body.CanSeek)
                {
                    request.Body.Seek(0, SeekOrigin.Begin);
                }

                object model = context.ModelType.GetConstructor(Type.EmptyTypes).Invoke(null);

                string          boundary = MultipartRequestHelper.GetBoundary(MediaTypeHeaderValue.Parse(request.ContentType), DefaultFormOptions.MultipartBoundaryLengthLimit);
                MultipartReader reader   = new MultipartReader(boundary, request.Body);

                bool isSuccess  = false;
                bool isReadable = true;

                do
                {
                    MultipartSection section = await reader.ReadNextSectionAsync();

                    isReadable = section != null;
                    if (isReadable && ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out ContentDispositionHeaderValue contentDisposition))
                    {
                        if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                        {
                            SetProperty(model, FileNamePropertyName, HeaderUtilities.RemoveQuotes(contentDisposition.FileName).ToString());
                            SetProperty(model, StreamPropertyName, section.Body, false);

                            isSuccess = true;

                            isReadable = false;
                        }
                        else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                        {
                            string   key      = HeaderUtilities.RemoveQuotes(contentDisposition.Name).ToString();
                            Encoding encoding = GetEncoding(section);

                            string value = null;

                            using (StreamReader streamReader = new StreamReader(section.Body, encoding, detectEncodingFromByteOrderMarks: true, bufferSize: 1024, leaveOpen: true))
                            {
                                value = await streamReader.ReadToEndAsync();

                                if (string.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                                {
                                    value = string.Empty;
                                }
                            }

                            SetProperty(model, key, value);

                            isSuccess = true;
                        }
                    }
                }while (isReadable);

                if (!isSuccess && !context.TreatEmptyInputAsDefaultValue)
                {
                    return(InputFormatterResult.NoValue());
                }

                return(InputFormatterResult.Success(model));
            }
            catch
            {
                return(InputFormatterResult.Failure());
            }
        }
Exemple #10
0
        public async Task <IActionResult> UploadFiles()
        {
            if (!IsMultipartContentType(Request.ContentType))
            {
                return(new UnsupportedMediaTypeResult());
            }

            Log.Information($"POSTing files...");

            var boundary = HeaderUtilities.RemoveQuotes(MediaTypeHeaderValue.Parse(Request.ContentType).Boundary);
            var reader   = new MultipartReader(boundary.Value, Request.Body);

            MultipartSection section;

            IList <Image> imagesRequest = null;
            var           result        = new List <FileImages>();

            while ((section = await reader.ReadNextSectionAsync()) != null)
            {
                var contentDisposition = section.GetContentDispositionHeader();
                if (contentDisposition.IsFormDisposition() && imagesRequest is null)
                {
                    var    formSection = section.AsFormDataSection();
                    string formValue   = await formSection.GetValueAsync();

                    imagesRequest = JsonConvert.DeserializeObject <IList <Image> >(formValue, new JsonSerializerSettings
                    {
                        Error = delegate(object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args)
                        {
                            args.ErrorContext.Handled = true;
                        }
                    });
                }
                if (contentDisposition.IsFileDisposition())
                {
                    var fileSection = section.AsFileSection();
                    if (string.IsNullOrEmpty(fileSection.FileName))
                    {
                        Log.Information($"Empty file section");
                        continue;
                    }
                    Log.Information($"Saving file {fileSection.FileName}");

                    var blobId = await _blobStorage.AddFileAsync(Path.GetFileName(fileSection.FileName), fileSection.FileStream, fileSection.Section.ContentType, _bucket);

                    if (imagesRequest is null || !imagesRequest.Any())
                    {
                        imagesRequest = new Image[]
                        {
                            new Image
                            {
                                Width  = int.Parse(_configuration["DefaultImage:Width"]),
                                Format = _configuration["DefaultImage:Format"],
                                Height = int.Parse(_configuration["DefaultImage:Height"])
                            }
                        };
                    }

                    foreach (var requestedImage in imagesRequest)
                    {
                        requestedImage.Id = NewId.Next().ToGuid();

                        if (requestedImage.Width <= 0)
                        {
                            requestedImage.Width = int.Parse(_configuration["DefaultImage:Width"]);
                        }

                        if (requestedImage.Height <= 0)
                        {
                            requestedImage.Height = int.Parse(_configuration["DefaultImage:Height"]);
                        }
                    }

                    var fileImages = new FileImages
                    {
                        Id     = blobId,
                        Images = imagesRequest,
                        Bucket = _bucket
                    };

                    //await _imagesMetaCollection.InsertOneAsync(fileImages);

                    foreach (var requestedImage in imagesRequest)
                    {
                        await _bus.Publish <GenerateImage>(new
                        {
                            Id     = requestedImage.Id,
                            Bucket = _bucket,
                            BlobId = blobId,
                            Image  = requestedImage,
                            UserId = new Guid(_bucket)
                        });
                    }

                    result.Add(fileImages);
                }
            }

            return(Ok(result));
        }
Exemple #11
0
 static bool AllowCacheStorage(HttpContext context)
 {
     // cache-control: no-store ?
     return(!HeaderUtilities.ContainsCacheDirective(context.Request.Headers[HeaderNames.CacheControl], CacheControlHeaderValue.NoStoreString));
 }
Exemple #12
0
        public async Task <IActionResult> UploadDatabase()
        {
            var returner = new BaseDeveloperResponse();

            if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
            {
                ModelState.AddModelError("File",
                                         $"The request couldn't be processed (Error 1).");
                // Log error

                return(BadRequest(ModelState));
            }

            // Accumulate the form data key-value pairs in the request (formAccumulator).
            var formAccumulator             = new KeyValueAccumulator();
            var trustedFileNameForDisplay   = string.Empty;
            var untrustedFileNameForStorage = string.Empty;
            var streamedFileContent         = new byte[0];

            var boundary = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(Request.ContentType),
                _defaultFormOptions.MultipartBoundaryLengthLimit);
            var reader = new MultipartReader(boundary, HttpContext.Request.Body);

            var section = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                var hasContentDispositionHeader =
                    ContentDispositionHeaderValue.TryParse(
                        section.ContentDisposition, out var contentDisposition);

                if (hasContentDispositionHeader)
                {
                    if (MultipartRequestHelper
                        .HasFileContentDisposition(contentDisposition))
                    {
                        untrustedFileNameForStorage = contentDisposition.FileName.Value;
                        // Don't trust the file name sent by the client. To display
                        // the file name, HTML-encode the value.
                        trustedFileNameForDisplay = WebUtility.HtmlEncode(
                            contentDisposition.FileName.Value);

                        streamedFileContent =
                            await FileHelpers.ProcessStreamedFile(section, contentDisposition,
                                                                  ModelState, _permittedExtensions, _fileSizeLimit);

                        if (!ModelState.IsValid)
                        {
                            return(BadRequest(ModelState));
                        }
                    }
                    else if (MultipartRequestHelper
                             .HasFormDataContentDisposition(contentDisposition))
                    {
                        // Don't limit the key name length because the
                        // multipart headers length limit is already in effect.
                        var key = HeaderUtilities
                                  .RemoveQuotes(contentDisposition.Name).Value;
                        var encoding = GetEncoding(section);

                        if (encoding == null)
                        {
                            ModelState.AddModelError("File",
                                                     $"The request couldn't be processed (Error 2).");
                            // Log error

                            return(BadRequest(ModelState));
                        }

                        using (var streamReader = new StreamReader(
                                   section.Body,
                                   encoding,
                                   detectEncodingFromByteOrderMarks: true,
                                   bufferSize: 1024,
                                   leaveOpen: true))
                        {
                            // The value length limit is enforced by
                            // MultipartBodyLengthLimit
                            var value = await streamReader.ReadToEndAsync();

                            if (string.Equals(value, "undefined",
                                              StringComparison.OrdinalIgnoreCase))
                            {
                                value = string.Empty;
                            }

                            formAccumulator.Append(key, value);

                            if (formAccumulator.ValueCount >
                                _defaultFormOptions.ValueCountLimit)
                            {
                                // Form key count limit of
                                // _defaultFormOptions.ValueCountLimit
                                // is exceeded.
                                ModelState.AddModelError("File",
                                                         $"The request couldn't be processed (Error 3).");
                                // Log error

                                return(BadRequest(ModelState));
                            }
                        }
                    }
                }

                // Drain any remaining section body that hasn't been consumed and
                // read the headers for the next section.
                section = await reader.ReadNextSectionAsync();
            }

            // Bind form data to the model
            var formData          = new MultiPartTestRequestMultiple();
            var formValueProvider = new FormValueProvider(
                BindingSource.Form,
                new FormCollection(formAccumulator.GetResults()),
                CultureInfo.CurrentCulture);
            var bindingSuccessful = await TryUpdateModelAsync(formData, prefix : "",
                                                              valueProvider : formValueProvider);

            if (!bindingSuccessful)
            {
                ModelState.AddModelError("File",
                                         "The request couldn't be processed (Error 5).");
                // Log error

                return(BadRequest(ModelState));
            }

            // **WARNING!**
            // In the following example, the file is saved without
            // scanning the file's contents. In most production
            // scenarios, an anti-virus/anti-malware scanner API
            // is used on the file before making the file available
            // for download or for use by other systems.
            // For more information, see the topic that accompanies
            // this sample app.

            var check = formData.FormFiles.ToList().Count;

            return(Ok(returner.Stop()));
        }
        public static async Task <string> ExtractJsonString(this HttpRequest request, string jsonPartName)
        {
            if (!IsMultipartContentType(request.ContentType))
            {
                throw new Exception($"Expected a multipart request, but got {request.ContentType}");
            }

            var boundary = GetBoundary(
                MediaTypeHeaderValue.Parse(request.ContentType),
                _defaultFormOptions.MultipartBoundaryLengthLimit);
            var reader = new MultipartReader(boundary, request.Body);

            var section = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                ContentDispositionHeaderValue contentDisposition;
                var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out contentDisposition);

                if (hasContentDispositionHeader)
                {
                    if (HasFileContentDisposition(contentDisposition))
                    {
                        // skip
                    }
                    else if (HasFormDataContentDisposition(contentDisposition))
                    {
                        // Content-Disposition: form-data; name="key"
                        //
                        // value

                        // Do not limit the key name length here because the
                        // multipart headers length limit is already in effect.
                        var key = HeaderUtilities.RemoveQuotes(contentDisposition.Name);

                        if (key.Value == jsonPartName)
                        {
                            var encoding = GetEncoding(section) ?? System.Text.Encoding.UTF8;
                            using (var streamReader = new StreamReader(
                                       section.Body,
                                       encoding,
                                       detectEncodingFromByteOrderMarks: true,
                                       bufferSize: 1024,
                                       leaveOpen: true))
                            {
                                // The value length limit is enforced by MultipartBodyLengthLimit
                                var value = await streamReader.ReadToEndAsync();

                                if (String.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                                {
                                    value = String.Empty;
                                }

                                return(value);
                            }
                        }
                        else
                        {
                            // skip
                        }
                    }
                }

                // Drains any remaining section body that has not been consumed and
                // reads the headers for the next section.
                section = await reader.ReadNextSectionAsync();
            }

            // did not find the part
            return(string.Empty);
        }
 private static void CheckNameValueFormat(StringSegment name, StringSegment value)
 {
     HeaderUtilities.CheckValidToken(name, nameof(name));
     CheckValueFormat(value);
 }
        public static async Task <FormValueProvider> StreamFile(this HttpRequest request, Stream targetStream, int bufferSize)
        {
            if (!MultipartRequestHelper.IsMultipartContentType(request.ContentType))
            {
                throw new Exception($"Expected a multipart request, but got {request.ContentType}");
            }

            // Used to accumulate all the form url encoded key value pairs in the
            // request.
            KeyValueAccumulator formAccumulator = new KeyValueAccumulator();
            // string targetFilePath = null;

            string boundary = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(request.ContentType),
                _defaultFormOptions.MultipartBoundaryLengthLimit);
            MultipartReader reader = new MultipartReader(boundary, request.Body);

            MultipartSection section = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                bool hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out ContentDispositionHeaderValue contentDisposition);

                if (hasContentDispositionHeader)
                {
                    if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                    {
                        await section.Body.CopyToAsync(targetStream);
                    }
                    else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                    {
                        // Content-Disposition: form-data; name="key"
                        //
                        // value

                        // Do not limit the key name length here because the
                        // multipart headers length limit is already in effect.
                        Microsoft.Extensions.Primitives.StringSegment key = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                        Encoding encoding = GetEncoding(section);
                        using (StreamReader streamReader = new StreamReader(
                                   section.Body,
                                   encoding,
                                   detectEncodingFromByteOrderMarks: true,
                                   bufferSize: bufferSize,
                                   leaveOpen: true))
                        {
                            // The value length limit is enforced by MultipartBodyLengthLimit
                            string value = await streamReader.ReadToEndAsync();

                            if (string.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                            {
                                value = string.Empty;
                            }
                            formAccumulator.Append(key.Value, value); // For .NET Core <2.0 remove ".Value" from key

                            if (formAccumulator.ValueCount > _defaultFormOptions.ValueCountLimit)
                            {
                                throw new InvalidDataException($"Form key count limit {_defaultFormOptions.ValueCountLimit} exceeded.");
                            }
                        }
                    }
                }

                // Drains any remaining section body that has not been consumed and
                // reads the headers for the next section.
                section = await reader.ReadNextSectionAsync();
            }

            // Bind form data to a model
            FormValueProvider formValueProvider = new FormValueProvider(
                BindingSource.Form,
                new FormCollection(formAccumulator.GetResults()),
                CultureInfo.CurrentCulture);

            return(formValueProvider);
        }
Exemple #16
0
        public static async Task <string> GetDigestTokenForCredential(NetworkCredential credential, HttpRequestMessage request, DigestResponse digestResponse)
        {
            StringBuilder sb = StringBuilderCache.Acquire();

            // It is mandatory for servers to implement sha-256 per RFC 7616
            // Keep MD5 for backward compatibility.
            string algorithm;

            if (digestResponse.Parameters.TryGetValue(Algorithm, out algorithm))
            {
                if (algorithm != Sha256 && algorithm != Md5 && algorithm != Sha256Sess && algorithm != MD5Sess)
                {
                    return(null);
                }
            }
            else
            {
                algorithm = Md5;
            }

            // Check if nonce is there in challenge
            string nonce;

            if (!digestResponse.Parameters.TryGetValue(Nonce, out nonce))
            {
                return(null);
            }

            // opaque token may or may not exist
            string opaque;

            digestResponse.Parameters.TryGetValue(Opaque, out opaque);

            string realm;

            if (!digestResponse.Parameters.TryGetValue(Realm, out realm))
            {
                return(null);
            }

            // Add username
            string userhash;

            if (digestResponse.Parameters.TryGetValue(UserHash, out userhash) && userhash == "true")
            {
                sb.AppendKeyValue(Username, ComputeHash(credential.UserName + ":" + realm, algorithm));
                sb.AppendKeyValue(UserHash, userhash, includeQuotes: false);
            }
            else
            {
                string usernameStar;
                if (HeaderUtilities.IsInputEncoded5987(credential.UserName, out usernameStar))
                {
                    sb.AppendKeyValue(UsernameStar, usernameStar, includeQuotes: false);
                }
                else
                {
                    sb.AppendKeyValue(Username, credential.UserName);
                }
            }

            // Add realm
            if (realm != string.Empty)
            {
                sb.AppendKeyValue(Realm, realm);
            }

            // Add nonce
            sb.AppendKeyValue(Nonce, nonce);

            // Add uri
            sb.AppendKeyValue(Uri, request.RequestUri.PathAndQuery);

            // Set qop, default is auth
            string qop = Auth;

            if (digestResponse.Parameters.ContainsKey(Qop))
            {
                // Check if auth-int present in qop string
                int index1 = digestResponse.Parameters[Qop].IndexOf(AuthInt);
                if (index1 != -1)
                {
                    // Get index of auth if present in qop string
                    int index2 = digestResponse.Parameters[Qop].IndexOf(Auth);

                    // If index2 < index1, auth option is available
                    // If index2 == index1, check if auth option available later in string after auth-int.
                    if (index2 == index1)
                    {
                        index2 = digestResponse.Parameters[Qop].IndexOf(Auth, index1 + AuthInt.Length);
                        if (index2 == -1)
                        {
                            qop = AuthInt;
                        }
                    }
                }
            }

            // Set cnonce
            string cnonce = GetRandomAlphaNumericString();

            // Calculate response
            string a1 = credential.UserName + ":" + realm + ":" + credential.Password;

            if (algorithm.IndexOf("sess") != -1)
            {
                a1 = ComputeHash(a1, algorithm) + ":" + nonce + ":" + cnonce;
            }

            string a2 = request.Method.Method + ":" + request.RequestUri.PathAndQuery;

            if (qop == AuthInt)
            {
                string content = request.Content == null ? string.Empty : await request.Content.ReadAsStringAsync().ConfigureAwait(false);

                a2 = a2 + ":" + ComputeHash(content, algorithm);
            }

            string response = ComputeHash(ComputeHash(a1, algorithm) + ":" +
                                          nonce + ":" +
                                          DigestResponse.NonceCount + ":" +
                                          cnonce + ":" +
                                          qop + ":" +
                                          ComputeHash(a2, algorithm), algorithm);

            // Add response
            sb.AppendKeyValue(Response, response);

            // Add algorithm
            sb.AppendKeyValue(Algorithm, algorithm, includeQuotes: false);

            // Add opaque
            if (opaque != null)
            {
                sb.AppendKeyValue(Opaque, opaque);
            }

            // Add qop
            sb.AppendKeyValue(Qop, qop, includeQuotes: false);

            // Add nc
            sb.AppendKeyValue(NC, DigestResponse.NonceCount, includeQuotes: false);

            // Add cnonce
            sb.AppendKeyValue(CNonce, cnonce, includeComma: false);

            return(StringBuilderCache.GetStringAndRelease(sb));
        }
    internal async Task <bool> TryServeCachedResponseAsync(ResponseCachingContext context, IResponseCacheEntry?cacheEntry)
    {
        if (!(cacheEntry is CachedResponse cachedResponse))
        {
            return(false);
        }

        context.CachedResponse        = cachedResponse;
        context.CachedResponseHeaders = cachedResponse.Headers;
        context.ResponseTime          = _options.SystemClock.UtcNow;
        var cachedEntryAge = context.ResponseTime.Value - context.CachedResponse.Created;

        context.CachedEntryAge = cachedEntryAge > TimeSpan.Zero ? cachedEntryAge : TimeSpan.Zero;

        if (_policyProvider.IsCachedEntryFresh(context))
        {
            // Check conditional request rules
            if (ContentIsNotModified(context))
            {
                _logger.NotModifiedServed();
                context.HttpContext.Response.StatusCode = StatusCodes.Status304NotModified;

                if (context.CachedResponseHeaders != null)
                {
                    foreach (var key in HeadersToIncludeIn304)
                    {
                        if (context.CachedResponseHeaders.TryGetValue(key, out var values))
                        {
                            context.HttpContext.Response.Headers[key] = values;
                        }
                    }
                }
            }
            else
            {
                var response = context.HttpContext.Response;
                // Copy the cached status code and response headers
                response.StatusCode = context.CachedResponse.StatusCode;
                foreach (var header in context.CachedResponse.Headers)
                {
                    response.Headers[header.Key] = header.Value;
                }

                // Note: int64 division truncates result and errors may be up to 1 second. This reduction in
                // accuracy of age calculation is considered appropriate since it is small compared to clock
                // skews and the "Age" header is an estimate of the real age of cached content.
                response.Headers.Age = HeaderUtilities.FormatNonNegativeInt64(context.CachedEntryAge.Value.Ticks / TimeSpan.TicksPerSecond);

                // Copy the cached response body
                var body = context.CachedResponse.Body;
                if (body.Length > 0)
                {
                    try
                    {
                        await body.CopyToAsync(response.BodyWriter, context.HttpContext.RequestAborted);
                    }
                    catch (OperationCanceledException)
                    {
                        context.HttpContext.Abort();
                    }
                }
                _logger.CachedResponseServed();
            }
            return(true);
        }

        return(false);
    }
Exemple #18
0
        public async Task <IActionResult> UpLoad()
        {
            if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
            {
                return(BadRequest($"Expected a multipart request, but got {Request.ContentType}"));
            }
            // Used to accumulate all the form url encoded key value pairs in the
            // request.
            var    formAccumulator = new KeyValueAccumulator();
            string targetFilePath  = null;
            var    boundary        = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(Request.ContentType),
                _defaultFormOptions.MultipartBoundaryLengthLimit);
            var reader  = new MultipartReader(boundary, HttpContext.Request.Body); //读取表单内容的对象
            var section = await reader.ReadNextSectionAsync();                     //读取

            while (section != null)
            {
                ContentDispositionHeaderValue contentDisposition;
                var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out contentDisposition);
                if (hasContentDispositionHeader)
                {
                    if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                    {
                        targetFilePath = Path.GetTempFileName();  //换下路径
                        using (var targetStream = System.IO.File.Create(targetFilePath))
                        {
                            await section.Body.CopyToAsync(targetStream);

                            ;
                        }
                    }
                    else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                    {
                        var key      = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                        var encoding = GetEncoding(section);
                        using (var streamReader = new StreamReader(
                                   section.Body,
                                   encoding,
                                   detectEncodingFromByteOrderMarks: true,
                                   bufferSize: 1024,
                                   leaveOpen: true))
                        {
                            var value = await streamReader.ReadToEndAsync();

                            if (String.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                            {
                                value = String.Empty;
                            }
                            formAccumulator.Append(key.Value.Trim('"'), value);
                            if (formAccumulator.ValueCount > _defaultFormOptions.ValueCountLimit)
                            {
                                throw new InvalidDataException($"Form key count limit {_defaultFormOptions.ValueCountLimit} exceeded.");
                            }
                        }
                    }
                }
                section = await reader.ReadNextSectionAsync();
            }
            var user = new User();
            var formValueProvider = new FormValueProvider(
                BindingSource.Form,
                new FormCollection(formAccumulator.GetResults()),
                CultureInfo.CurrentCulture);
            var bindingSuccessful = await TryUpdateModelAsync(user, prefix : "",
                                                              valueProvider : formValueProvider);

            if (!bindingSuccessful)
            {
                if (!ModelState.IsValid)
                {
                    return(BadRequest(ModelState));
                }
            }
            var uploadedData = new UploadedData()
            {
                Name     = user.Name,
                Age      = user.Age,
                Zipcode  = user.Zipcode,
                FilePath = targetFilePath
            };

            return(Json(uploadedData));
        }
Exemple #19
0
 private static bool TryParseInt64(string input, out long value)
 {
     return(HeaderUtilities.TryParseNonNegativeInt64(input, out value));
 }
        public static async Task <FormValueProvider> StreamFile(this HttpRequest request, Func <FileMultipartSection, Stream> createStream)
        {
            if (!MultipartRequestHelper.IsMultipartContentType(request.ContentType))
            {
                throw new Exception($"Expected a multipart request, but got {request.ContentType}");
            }

            // 把 request 中的 Form 依照 Key 及 Value 存到此物件
            var formAccumulator = new KeyValueAccumulator();

            var boundary = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(request.ContentType),
                _defaultFormOptions.MultipartBoundaryLengthLimit);
            var reader = new MultipartReader(boundary, request.Body);

            var section = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                // 把 Form 的欄位內容逐一取出
                ContentDispositionHeaderValue contentDisposition;
                var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out contentDisposition);

                if (hasContentDispositionHeader)
                {
                    if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                    {
                        // 若此欄位是檔案,就寫入至 Stream;
                        using (var targetStream = createStream(section.AsFileSection()))
                        {
                            await section.Body.CopyToAsync(targetStream);
                        }
                    }
                    else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                    {
                        // 若此欄位不是檔案,就把 Key 及 Value 取出,存入 formAccumulator
                        var key      = HeaderUtilities.RemoveQuotes(contentDisposition.Name).Value;
                        var encoding = GetEncoding(section);
                        using (var streamReader = new StreamReader(
                                   section.Body,
                                   encoding,
                                   detectEncodingFromByteOrderMarks: true,
                                   bufferSize: 1024,
                                   leaveOpen: true))
                        {
                            var value = await streamReader.ReadToEndAsync();

                            if (String.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                            {
                                value = String.Empty;
                            }
                            formAccumulator.Append(key, value);

                            if (formAccumulator.ValueCount > _defaultFormOptions.ValueCountLimit)
                            {
                                throw new InvalidDataException($"Form key count limit {_defaultFormOptions.ValueCountLimit} exceeded.");
                            }
                        }
                    }
                }

                // 取得 Form 的下一個欄位
                section = await reader.ReadNextSectionAsync();
            }

            // Bind form data to a model
            var formValueProvider = new FormValueProvider(
                BindingSource.Form,
                new FormCollection(formAccumulator.GetResults()),
                CultureInfo.CurrentCulture);

            return(formValueProvider);
        }
        public virtual bool IsCachedEntryFresh(ResponseCachingContext context)
        {
            var age = context.CachedEntryAge !.Value;
            var cachedCacheControlHeaders  = context.CachedResponseHeaders[HeaderNames.CacheControl];
            var requestCacheControlHeaders = context.HttpContext.Request.Headers.CacheControl;

            // Add min-fresh requirements
            if (HeaderUtilities.TryParseSeconds(requestCacheControlHeaders, CacheControlHeaderValue.MinFreshString, out var minFresh))
            {
                age += minFresh.Value;
                context.Logger.ExpirationMinFreshAdded(minFresh.Value);
            }

            // Validate shared max age, this overrides any max age settings for shared caches
            TimeSpan?cachedSharedMaxAge;

            HeaderUtilities.TryParseSeconds(cachedCacheControlHeaders, CacheControlHeaderValue.SharedMaxAgeString, out cachedSharedMaxAge);

            if (age >= cachedSharedMaxAge)
            {
                // shared max age implies must revalidate
                context.Logger.ExpirationSharedMaxAgeExceeded(age, cachedSharedMaxAge.Value);
                return(false);
            }
            else if (!cachedSharedMaxAge.HasValue)
            {
                TimeSpan?requestMaxAge;
                HeaderUtilities.TryParseSeconds(requestCacheControlHeaders, CacheControlHeaderValue.MaxAgeString, out requestMaxAge);

                TimeSpan?cachedMaxAge;
                HeaderUtilities.TryParseSeconds(cachedCacheControlHeaders, CacheControlHeaderValue.MaxAgeString, out cachedMaxAge);

                var lowestMaxAge = cachedMaxAge < requestMaxAge ? cachedMaxAge : requestMaxAge ?? cachedMaxAge;
                // Validate max age
                if (age >= lowestMaxAge)
                {
                    // Must revalidate or proxy revalidate
                    if (HeaderUtilities.ContainsCacheDirective(cachedCacheControlHeaders, CacheControlHeaderValue.MustRevalidateString) ||
                        HeaderUtilities.ContainsCacheDirective(cachedCacheControlHeaders, CacheControlHeaderValue.ProxyRevalidateString))
                    {
                        context.Logger.ExpirationMustRevalidate(age, lowestMaxAge.Value);
                        return(false);
                    }

                    TimeSpan?requestMaxStale;
                    var      maxStaleExist = HeaderUtilities.ContainsCacheDirective(requestCacheControlHeaders, CacheControlHeaderValue.MaxStaleString);
                    HeaderUtilities.TryParseSeconds(requestCacheControlHeaders, CacheControlHeaderValue.MaxStaleString, out requestMaxStale);

                    // Request allows stale values with no age limit
                    if (maxStaleExist && !requestMaxStale.HasValue)
                    {
                        context.Logger.ExpirationInfiniteMaxStaleSatisfied(age, lowestMaxAge.Value);
                        return(true);
                    }

                    // Request allows stale values with age limit
                    if (requestMaxStale.HasValue && age - lowestMaxAge < requestMaxStale)
                    {
                        context.Logger.ExpirationMaxStaleSatisfied(age, lowestMaxAge.Value, requestMaxStale.Value);
                        return(true);
                    }

                    context.Logger.ExpirationMaxAgeExceeded(age, lowestMaxAge.Value);
                    return(false);
                }
                else if (!cachedMaxAge.HasValue && !requestMaxAge.HasValue)
                {
                    // Validate expiration
                    DateTimeOffset expires;
                    if (HeaderUtilities.TryParseDate(context.CachedResponseHeaders[HeaderNames.Expires].ToString(), out expires) &&
                        context.ResponseTime !.Value >= expires)
                    {
                        context.Logger.ExpirationExpiresExceeded(context.ResponseTime.Value, expires);
                        return(false);
                    }
                }
            }

            return(true);
        }
    private static bool TrySetOptionalTokenList(
        NameValueHeaderValue nameValue,
        ref bool boolField,
        ref ICollection <StringSegment>?destination)
    {
        if (nameValue.Value == null)
        {
            boolField = true;
            return(true);
        }

        // We need the string to be at least 3 chars long: 2x quotes and at least 1 character. Also make sure we
        // have a quoted string. Note that NameValueHeaderValue will never have leading/trailing whitespaces.
        var valueString = nameValue.Value;

        if ((valueString.Length < 3) || (valueString[0] != '\"') || (valueString[valueString.Length - 1] != '\"'))
        {
            return(false);
        }

        // We have a quoted string. Now verify that the string contains a list of valid tokens separated by ','.
        var current            = 1;                      // skip the initial '"' character.
        var maxLength          = valueString.Length - 1; // -1 because we don't want to parse the final '"'.
        var originalValueCount = destination == null ? 0 : destination.Count;

        while (current < maxLength)
        {
            current = HeaderUtilities.GetNextNonEmptyOrWhitespaceIndex(valueString, current, true,
                                                                       out var separatorFound);

            if (current == maxLength)
            {
                break;
            }

            var tokenLength = HttpRuleParser.GetTokenLength(valueString, current);

            if (tokenLength == 0)
            {
                // We already skipped whitespaces and separators. If we don't have a token it must be an invalid
                // character.
                return(false);
            }

            if (destination == null)
            {
                destination = new ObjectCollection <StringSegment>(CheckIsValidTokenAction);
            }

            destination.Add(valueString.Subsegment(current, tokenLength));

            current = current + tokenLength;
        }

        // After parsing a valid token list, we expect to have at least one value
        if ((destination != null) && (destination.Count > originalValueCount))
        {
            boolField = true;
            return(true);
        }

        return(false);
    }
        public virtual bool IsResponseCacheable(ResponseCachingContext context)
        {
            var responseCacheControlHeader = context.HttpContext.Response.Headers.CacheControl;

            // Only cache pages explicitly marked with public
            if (!HeaderUtilities.ContainsCacheDirective(responseCacheControlHeader, CacheControlHeaderValue.PublicString))
            {
                context.Logger.ResponseWithoutPublicNotCacheable();
                return(false);
            }

            // Check response no-store
            if (HeaderUtilities.ContainsCacheDirective(responseCacheControlHeader, CacheControlHeaderValue.NoStoreString))
            {
                context.Logger.ResponseWithNoStoreNotCacheable();
                return(false);
            }

            // Check no-cache
            if (HeaderUtilities.ContainsCacheDirective(responseCacheControlHeader, CacheControlHeaderValue.NoCacheString))
            {
                context.Logger.ResponseWithNoCacheNotCacheable();
                return(false);
            }

            var response = context.HttpContext.Response;

            // Do not cache responses with Set-Cookie headers
            if (!StringValues.IsNullOrEmpty(response.Headers.SetCookie))
            {
                context.Logger.ResponseWithSetCookieNotCacheable();
                return(false);
            }

            // Do not cache responses varying by *
            var varyHeader = response.Headers.Vary;

            if (varyHeader.Count == 1 && string.Equals(varyHeader, "*", StringComparison.OrdinalIgnoreCase))
            {
                context.Logger.ResponseWithVaryStarNotCacheable();
                return(false);
            }

            // Check private
            if (HeaderUtilities.ContainsCacheDirective(responseCacheControlHeader, CacheControlHeaderValue.PrivateString))
            {
                context.Logger.ResponseWithPrivateNotCacheable();
                return(false);
            }

            // Check response code
            if (response.StatusCode != StatusCodes.Status200OK)
            {
                context.Logger.ResponseWithUnsuccessfulStatusCodeNotCacheable(response.StatusCode);
                return(false);
            }

            // Check response freshness
            if (!context.ResponseDate.HasValue)
            {
                if (!context.ResponseSharedMaxAge.HasValue &&
                    !context.ResponseMaxAge.HasValue &&
                    context.ResponseTime !.Value >= context.ResponseExpires)
                {
                    context.Logger.ExpirationExpiresExceeded(context.ResponseTime.Value, context.ResponseExpires.Value);
                    return(false);
                }
            }
            else
            {
                var age = context.ResponseTime !.Value - context.ResponseDate.Value;

                // Validate shared max age
                if (age >= context.ResponseSharedMaxAge)
                {
                    context.Logger.ExpirationSharedMaxAgeExceeded(age, context.ResponseSharedMaxAge.Value);
                    return(false);
                }
                else if (!context.ResponseSharedMaxAge.HasValue)
                {
                    // Validate max age
                    if (age >= context.ResponseMaxAge)
                    {
                        context.Logger.ExpirationMaxAgeExceeded(age, context.ResponseMaxAge.Value);
                        return(false);
                    }
                    else if (!context.ResponseMaxAge.HasValue)
                    {
                        // Validate expiration
                        if (context.ResponseTime.Value >= context.ResponseExpires)
                        {
                            context.Logger.ExpirationExpiresExceeded(context.ResponseTime.Value, context.ResponseExpires.Value);
                            return(false);
                        }
                    }
                }
            }

            return(true);
        }
 private static void CheckIsValidToken(StringSegment item)
 {
     HeaderUtilities.CheckValidToken(item, nameof(item));
 }
Exemple #25
0
        public async Task <IActionResult> UploadDatabase()
        {
            if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
            {
                ModelState.AddModelError("File",
                                         $"The request couldn't be processed (Error 1).");
                // Log error

                return(BadRequest(ModelState));
            }

            // Accumulate the form data key-value pairs in the request (formAccumulator).
            var formAccumulator               = new KeyValueAccumulator();
            var trustedFileNameForDisplay     = string.Empty;
            var untrustedFileNameForStorage   = string.Empty;
            var trustedFilePathStorage        = string.Empty;
            var trustedFileNameForFileStorage = string.Empty;
            var streamedFileContent           = new byte[0];
            var streamedFilePhysicalContent   = new byte[0];

            // List Byte for file storage
            List <byte[]> filesByteStorage         = new List <byte[]>();
            List <string> filesNameStorage         = new List <string>();
            var           fileStoredData           = new Dictionary <string, byte[]>();
            List <string> storedPaths              = new List <string>();
            List <string> storedPathDictionaryKeys = new List <string>();

            // List to Submit
            List <ClamSectionTVShowSubCategorySeasonItem> episodeList = new List <ClamSectionTVShowSubCategorySeasonItem>();

            var boundary = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(Request.ContentType),
                _defaultFormOptions.MultipartBoundaryLengthLimit);
            var reader = new MultipartReader(boundary, HttpContext.Request.Body);

            var section = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                var hasContentDispositionHeader =
                    ContentDispositionHeaderValue.TryParse(
                        section.ContentDisposition, out var contentDisposition);

                if (hasContentDispositionHeader)
                {
                    if (MultipartRequestHelper
                        .HasFileContentDisposition(contentDisposition))
                    {
                        untrustedFileNameForStorage = contentDisposition.FileName.Value;
                        // Don't trust the file name sent by the client. To display
                        // the file name, HTML-encode the value.
                        trustedFileNameForDisplay = WebUtility.HtmlEncode(
                            contentDisposition.FileName.Value);

                        //streamedFileContent =
                        //    await FileHelpers.ProcessStreamedFile(section, contentDisposition,
                        //        ModelState, _permittedExtentions, _fileSizeLimit);

                        streamedFilePhysicalContent = await FileHelpers.ProcessStreamedFile(
                            section, contentDisposition, ModelState,
                            _permittedExtentions, _fileSizeLimit);

                        filesNameStorage.Add(trustedFileNameForDisplay);
                        filesByteStorage.Add(streamedFilePhysicalContent);
                        fileStoredData.Add(trustedFileNameForDisplay, streamedFilePhysicalContent);

                        if (!ModelState.IsValid)
                        {
                            return(BadRequest(ModelState));
                        }
                    }
                    else if (MultipartRequestHelper
                             .HasFormDataContentDisposition(contentDisposition))
                    {
                        // Don't limit the key name length because the
                        // multipart headers length limit is already in effect.
                        var key = HeaderUtilities
                                  .RemoveQuotes(contentDisposition.Name).Value;
                        var encoding = GetEncoding(section);

                        if (encoding == null)
                        {
                            ModelState.AddModelError("File",
                                                     $"The request couldn't be processed (Error 2).");
                            // Log error

                            return(BadRequest(ModelState));
                        }

                        using (var streamReader = new StreamReader(
                                   section.Body,
                                   encoding,
                                   detectEncodingFromByteOrderMarks: true,
                                   bufferSize: 1024,
                                   leaveOpen: true))
                        {
                            // The value length limit is enforced by
                            // MultipartBodyLengthLimit
                            var value = await streamReader.ReadToEndAsync();

                            if (string.Equals(value, "undefined",
                                              StringComparison.OrdinalIgnoreCase))
                            {
                                value = string.Empty;
                            }

                            formAccumulator.Append(key, value);

                            if (formAccumulator.ValueCount >
                                _defaultFormOptions.ValueCountLimit)
                            {
                                // Form key count limit of
                                // _defaultFormOptions.ValueCountLimit
                                // is exceeded.
                                ModelState.AddModelError("File",
                                                         $"The request couldn't be processed (Error 3).");
                                // Log error

                                return(BadRequest(ModelState));
                            }
                        }
                    }
                }

                // Drain any remaining section body that hasn't been consumed and
                // read the headers for the next section.
                section = await reader.ReadNextSectionAsync();
            }

            // Bind form data to the model
            var formData          = new StreamFormData();
            var formValueProvider = new FormValueProvider(
                BindingSource.Form,
                new FormCollection(formAccumulator.GetResults()),
                CultureInfo.CurrentCulture);
            var bindingSuccessful = await TryUpdateModelAsync(formData, prefix : "",
                                                              valueProvider : formValueProvider);

            //trustedFilePathStorage = String.Format("{0}\\{1}\\{2}\\{3}\\{4}",
            //    //_targetFilePath,
            //    _targetFolderPath,
            //    formData.CategoryId,
            //    formData.TVShowId,
            //    formData.SeasonId,
            //    Path.GetRandomFileName());

            if (!bindingSuccessful)
            {
                ModelState.AddModelError("File",
                                         "The request couldn't be processed (Error 5).");
                // Log error

                return(BadRequest(ModelState));
            }

            // **WARNING!**
            // In the following example, the file is saved without
            // scanning the file's contents. In most production
            // scenarios, an anti-virus/anti-malware scanner API
            // is used on the file before making the file available
            // for download or for use by other systems.
            // For more information, see the topic that accompanies
            // this sample app.

            //Directory.CreateDirectory(trustedFilePathStorage);

            //using (var targetStream = System.IO.File.Create(
            //                Path.Combine(trustedFilePathStorage, trustedFileNameForDisplay)))
            //{
            //    await targetStream.WriteAsync(streamedFilePhysicalContent);

            //    _logger.LogInformation(
            //        "Uploaded file '{TrustedFileNameForDisplay}' saved to " +
            //        "'{TargetFilePath}' as {TrustedFileNameForFileStorage}",
            //        trustedFileNameForDisplay, trustedFilePathStorage,
            //        trustedFileNameForDisplay);
            //}
            foreach (var item in fileStoredData)
            {
                trustedFilePathStorage = String.Format("{0}\\{1}\\{2}\\{3}\\{4}",
                                                       //_targetFilePath,
                                                       _targetFolderPath,
                                                       formData.CategoryId,
                                                       formData.TVShowId,
                                                       formData.SeasonId,
                                                       Path.GetRandomFileName());
                Directory.CreateDirectory(trustedFilePathStorage);

                using (var targetStream = System.IO.File.Create(
                           Path.Combine(trustedFilePathStorage, item.Key)))
                {
                    await targetStream.WriteAsync(item.Value);

                    _logger.LogInformation(
                        "Uploaded file '{TrustedFileNameForDisplay}' saved to " +
                        "'{TargetFilePath}' as {TrustedFileNameForFileStorage}",
                        item.Key, trustedFilePathStorage,
                        item.Key);
                }
                //storedPaths.Add(Path.Combine(trustedFilePathStorage, item.Key));
                //storedPathDictionaryKeys.Add(item.Key);
                episodeList.Add(new ClamSectionTVShowSubCategorySeasonItem()
                {
                    ItemPath    = Path.Combine(trustedFilePathStorage, item.Key),
                    ItemTitle   = item.Key,
                    Size        = item.Value.Length,
                    DateCreated = DateTime.Now,
                    CategoryId  = formData.CategoryId,
                    TVShowId    = formData.TVShowId,
                    SeasonId    = formData.SeasonId
                });
            }

            //var file = new ClamSectionTVShowSubCategorySeasonItem()
            //{
            //    ItemPath = Path.Combine(trustedFilePathStorage, trustedFileNameForDisplay),
            //    ItemTitle = untrustedFileNameForStorage,
            //    Size = streamedFilePhysicalContent.Length,
            //    DateCreated = DateTime.Now,
            //    CategoryId = formData.CategoryId,
            //    TVShowId = formData.TVShowId,
            //    SeasonId = formData.SeasonId
            //};
            //_context.Add(file);

            await _context.AddRangeAsync(episodeList);

            await _context.SaveChangesAsync();

            var url = String.Format("{0}/{1}/season/{2}/episodes/{3}",
                                    formData.UrlCategory,
                                    formData.UrlSection,
                                    formData.UrlSubSection,
                                    formData.CategoryId
                                    );

            return(RedirectToAction("Episode", "TVShow", new { id = formData.CategoryId, show = formData.TVShowId, season = formData.SeasonId,
                                                               category = formData.UrlCategory, section = formData.UrlSection, subsection = formData.UrlSubSection }));
        }
        public async Task <IActionResult> UploadDatabase()
        {
            if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
            {
                ModelState.AddModelError("File",
                                         $"The request couldn't be processed (Error 1).");
                // Log error

                return(BadRequest(ModelState));
            }

            // Accumulate the form data key-value pairs in the request (formAccumulator).
            var formAccumulator     = new KeyValueAccumulator();
            var trustedFileName     = string.Empty;
            var streamedFileContent = new byte[0];

            var boundary = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(Request.ContentType),
                _defaultFormOptions.MultipartBoundaryLengthLimit);
            var reader = new MultipartReader(boundary, HttpContext.Request.Body);

            var section = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                var hasContentDispositionHeader =
                    ContentDispositionHeaderValue.TryParse(
                        section.ContentDisposition, out var contentDisposition);

                if (hasContentDispositionHeader)
                {
                    if (MultipartRequestHelper
                        .HasFileContentDisposition(contentDisposition))
                    {
                        // Don't trust the file name sent by the client. Use Linq to
                        // remove invalid characters. Another option is to use
                        // Path.GetRandomFileName to generate a safe random
                        // file name.
                        var invalidFileNameChars = Path.GetInvalidFileNameChars();
                        trustedFileName = invalidFileNameChars.Aggregate(
                            contentDisposition.FileName.Value, (current, c) =>
                            current.Replace(c, '_'));

                        streamedFileContent =
                            await FileHelpers.ProcessStreamedFile(section, contentDisposition,
                                                                  ModelState, _permittedExtensions, _fileSizeLimit);

                        if (!ModelState.IsValid)
                        {
                            return(BadRequest(ModelState));
                        }
                    }
                    else if (MultipartRequestHelper
                             .HasFormDataContentDisposition(contentDisposition))
                    {
                        // Don't limit the key name length because the
                        // multipart headers length limit is already in effect.
                        var key = HeaderUtilities
                                  .RemoveQuotes(contentDisposition.Name).Value;
                        var encoding = GetEncoding(section);

                        if (encoding == null)
                        {
                            ModelState.AddModelError("File",
                                                     $"The request couldn't be processed (Error 2).");
                            // Log error

                            return(BadRequest(ModelState));
                        }

                        using (var streamReader = new StreamReader(
                                   section.Body,
                                   encoding,
                                   detectEncodingFromByteOrderMarks: true,
                                   bufferSize: 1024,
                                   leaveOpen: true))
                        {
                            // The value length limit is enforced by
                            // MultipartBodyLengthLimit
                            var value = await streamReader.ReadToEndAsync();

                            if (String.Equals(value, "undefined",
                                              StringComparison.OrdinalIgnoreCase))
                            {
                                value = String.Empty;
                            }

                            formAccumulator.Append(key, value);

                            if (formAccumulator.ValueCount >
                                _defaultFormOptions.ValueCountLimit)
                            {
                                // Form key count limit of
                                // _defaultFormOptions.ValueCountLimit
                                // is exceeded.
                                ModelState.AddModelError("File",
                                                         $"The request couldn't be processed (Error 3).");
                                // Log error

                                return(BadRequest(ModelState));
                            }
                        }
                    }
                }

                // Drain any remaining section body that hasn't been consumed and
                // read the headers for the next section.
                section = await reader.ReadNextSectionAsync();
            }

            // Bind form data to the model
            var formData          = new FormData();
            var formValueProvider = new FormValueProvider(
                BindingSource.Form,
                new FormCollection(formAccumulator.GetResults()),
                CultureInfo.CurrentCulture);
            var bindingSuccessful = await TryUpdateModelAsync(formData, prefix : "",
                                                              valueProvider : formValueProvider);

            if (!bindingSuccessful)
            {
                ModelState.AddModelError("File",
                                         "The request couldn't be processed (Error 5).");
                // Log error

                return(BadRequest(ModelState));
            }

            var uploadedFormData = new FormData()
            {
                Note = formData.Note,
            };

            // **WARNING!**
            // In the following example, the file is saved without
            // scanning the file's contents. In most production
            // scenarios, an anti-virus/anti-malware scanner API
            // is used on the file before making the file available
            // for download or for use by other systems.
            // For more information, see the topic that accompanies
            // this sample app.

            var file = new AppFile()
            {
                Content  = streamedFileContent,
                Name     = trustedFileName,
                Note     = formData.Note,
                Size     = streamedFileContent.Length,
                UploadDT = DateTime.UtcNow
            };

            _context.File.Add(file);
            await _context.SaveChangesAsync();

            return(Created(nameof(StreamingController), null));
        }
Exemple #27
0
        public async Task <IActionResult> Upload()
        {
            if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
            {
                return(BadRequest("Expected a multipart request, but got " +
                                  Request.ContentType));
            }

            // Used to accumulate all the form url encoded key value pairs in the request.
            var    formAccumulator = new KeyValueAccumulator();
            string targetFilePath  = null;

            var boundary = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(Request.ContentType),
                _defaultFormOptions.MultipartBoundaryLengthLimit);
            var reader = new MultipartReader(boundary, HttpContext.Request.Body);

            var section = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                ContentDispositionHeaderValue contentDisposition;
                var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition,
                                                                                         out contentDisposition);

                if (hasContentDispositionHeader &&
                    MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                {
                    targetFilePath = Path.GetTempFileName();
                    using (var targetStream = System.IO.File.Create(targetFilePath))
                    {
                        await section.Body.CopyToAsync(targetStream);

                        _logger.LogInformation($"Copied the uploaded file '{targetFilePath}'");
                    }
                }
                else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                {
                    // Content-Disposition: form-data; name="key"
                    //
                    // value

                    // Do not limit the key name length here because the multipart headers length
                    // limit is already in effect.
                    var key      = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                    var encoding = GetEncoding(section);
                    using (var streamReader = new StreamReader(
                               section.Body,
                               encoding,
                               detectEncodingFromByteOrderMarks: true,
                               bufferSize: 1024,
                               leaveOpen: true))
                    {
                        // The value length limit is enforced by MultipartBodyLengthLimit
                        var value = await streamReader.ReadToEndAsync();

                        if (String.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                        {
                            value = String.Empty;
                        }
                        formAccumulator.Append(key, value);

                        if (formAccumulator.ValueCount > _defaultFormOptions.ValueCountLimit)
                        {
                            throw new InvalidDataException(
                                      "Form key count limit " + _defaultFormOptions.ValueCountLimit +
                                      " exceeded.");
                        }
                    }
                }

                // Drains any remaining section body that has not been consumed and
                // reads the headers for the next section.
                section = await reader.ReadNextSectionAsync();
            }

            // Bind form data to a model
            var user = new User();
            var formValueProvider = new FormValueProvider(
                BindingSource.Form,
                new FormCollection(formAccumulator.GetResults()),
                CultureInfo.CurrentCulture);

            var bindingSuccessful = await TryUpdateModelAsync(user, prefix : "",
                                                              valueProvider : formValueProvider);

            if (!bindingSuccessful)
            {
                if (!ModelState.IsValid)
                {
                    return(BadRequest(ModelState));
                }
            }

            var uploadedData = new UploadedData()
            {
                Name     = user.Name,
                Age      = user.Age,
                Zipcode  = user.Zipcode,
                FilePath = targetFilePath
            };

            return(Json(uploadedData));
        }
        private async Task <Procedure> ProcessProcedureRequestAsync(string targetPath)
        {
            try
            {
                Procedure result = null;
                if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
                {
                    throw new BadRequestException($"Expected a multipart request, but got {Request.ContentType}");
                }


                // Used to accumulate all the form url encoded key value pairs in the
                // request.
                var formAccumulator = new KeyValueAccumulator();

                var boundary = MultipartRequestHelper.GetBoundary(MediaTypeHeaderValue.Parse(Request.ContentType),
                                                                  _defaultFormOptions.MultipartBoundaryLengthLimit);

                var reader  = new MultipartReader(boundary, HttpContext.Request.Body);
                var section = await reader.ReadNextSectionAsync();

                while (section != null)
                {
                    ContentDispositionHeaderValue contentDisposition;
                    var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out contentDisposition);

                    if (hasContentDispositionHeader)
                    {
                        if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                        {
                            if (section.ContentType == "application/json")
                            {
                                var serializer = new JsonSerializer();

                                using (var sr = new StreamReader(section.Body))
                                    using (var jsonTextReader = new JsonTextReader(sr))
                                        result = serializer.Deserialize <Procedure>(jsonTextReader);
                            }
                            else // is file
                            {
                                using (var targetStream = new FileStream(Path.Combine(targetPath, contentDisposition.FileName.ToString()), FileMode.Create))
                                    await section.Body.CopyToAsync(targetStream);
                            } //end if
                        }     //end if
                        else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                        {
                            // Content-Disposition: form-data; name="key"
                            // Do not limit the key name length here because the
                            // multipart headers length limit is already in effect.
                            var key = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                            using (var streamReader = new StreamReader(section.Body, GetEncoding(section),
                                                                       detectEncodingFromByteOrderMarks: true, bufferSize: 1024, leaveOpen: true))
                            {
                                // The value length limit is enforced by MultipartBodyLengthLimit
                                var value = await streamReader.ReadToEndAsync();

                                if (String.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                                {
                                    value = String.Empty;
                                }
                                if (isJson(value))
                                {
                                    result = JsonConvert.DeserializeObject <Procedure>(value);
                                }
                                else
                                {
                                    formAccumulator.Append(key.ToString(), value);

                                    if (formAccumulator.ValueCount > _defaultFormOptions.ValueCountLimit)
                                    {
                                        throw new InvalidDataException($"Form key count limit {_defaultFormOptions.ValueCountLimit} exceeded.");
                                    }
                                }
                            } //end using
                        }     //endif
                    }
                    // Drains any remaining section body that has not been consumed and
                    // reads the headers for the next section.
                    section = await reader.ReadNextSectionAsync();
                }//next
                if (formAccumulator.HasValues)
                {
                    // Bind form data to a model
                    result = new Procedure();
                    var formValueProvider = new FormValueProvider(
                        BindingSource.Form,
                        new FormCollection(formAccumulator.GetResults()),
                        CultureInfo.CurrentCulture);

                    var bindingSuccessful = await TryUpdateModelAsync(result, prefix : "",
                                                                      valueProvider : formValueProvider);

                    if (!bindingSuccessful)
                    {
                        if (!ModelState.IsValid)
                        {
                            throw new BadRequestException(ModelState.ValidationState.ToString());
                        }
                    }
                }//end if
                return(result);
            }
            catch (Exception)
            {
                throw;
            }
        }
Exemple #29
0
        public async Task <MultiPartRequestDto> HandleMultiPartRequest(HttpRequest request)
        {
            if (!IsMultipartContentType(request.ContentType))
            {
                throw new Exception($"Expected a multipart request, but got {request.ContentType}");
            }

            var formAccumulator = new KeyValueAccumulator();

            var boundary = GetBoundary(
                MediaTypeHeaderValue.Parse(request.ContentType),
                _defaultFormOptions.MultipartBoundaryLengthLimit);
            var reader = new MultipartReader(boundary, request.Body);

            var section = await reader.ReadNextSectionAsync();

            var media = new List <AddFileDto>();

            while (section != null)
            {
                var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);

                if (hasContentDispositionHeader)
                {
                    if (HasFileContentDisposition(contentDisposition))
                    {
                        var processedMedia = await _fileService.ProcessStreamedFileAsync(section, contentDisposition);

                        var mediaDto = new AddFileDto
                        {
                            File          = processedMedia,
                            FileExtension = Path.GetExtension(contentDisposition.FileName.Value),
                        };
                        media.Add(mediaDto);
                    }
                    else if (HasFormDataContentDisposition(contentDisposition))
                    {
                        var key      = HeaderUtilities.RemoveQuotes(contentDisposition.Name).Value;
                        var encoding = GetEncoding(section);

                        using (var streamReader = new StreamReader(section.Body, encoding, detectEncodingFromByteOrderMarks: true, bufferSize: 1024, leaveOpen: true))
                        {
                            var value = await streamReader.ReadToEndAsync();

                            if (string.Equals(value, "undefined",
                                              StringComparison.OrdinalIgnoreCase))
                            {
                                value = string.Empty;
                            }

                            formAccumulator.Append(key, value);

                            if (formAccumulator.ValueCount >
                                int.MaxValue)
                            {
                                throw new InvalidDataException($"Form key count limit {_defaultFormOptions.ValueCountLimit} exceeded.");
                            }
                        }
                    }
                }

                section = await reader.ReadNextSectionAsync();
            }

            //request.Body.Position = 0;

            var formAccumulatorResults = formAccumulator.GetResults();
            var formValueProvider      = new FormValueProvider(
                BindingSource.Form,
                new FormCollection(formAccumulatorResults),
                CultureInfo.CurrentCulture);

            return(new MultiPartRequestDto
            {
                FormValueProvider = formValueProvider,
                File = media,
            });
        }
Exemple #30
0
    // name=value; expires=Sun, 06 Nov 1994 08:49:37 GMT; max-age=86400; domain=domain1; path=path1; secure; samesite={Strict|Lax|None}; httponly
    private static int GetSetCookieLength(StringSegment input, int startIndex, out SetCookieHeaderValue?parsedValue)
    {
        Contract.Requires(startIndex >= 0);
        var offset = startIndex;

        parsedValue = null;

        if (StringSegment.IsNullOrEmpty(input) || (offset >= input.Length))
        {
            return(0);
        }

        var result = new SetCookieHeaderValue();

        // The caller should have already consumed any leading whitespace, commas, etc..

        // Name=value;

        // Name
        var itemLength = HttpRuleParser.GetTokenLength(input, offset);

        if (itemLength == 0)
        {
            return(0);
        }
        result._name = input.Subsegment(offset, itemLength);
        offset      += itemLength;

        // = (no spaces)
        if (!ReadEqualsSign(input, ref offset))
        {
            return(0);
        }

        // value or "quoted value"
        // The value may be empty
        result._value = CookieHeaderParserShared.GetCookieValue(input, ref offset);

        // *(';' SP cookie-av)
        while (offset < input.Length)
        {
            if (input[offset] == ',')
            {
                // Divider between headers
                break;
            }
            if (input[offset] != ';')
            {
                // Expecting a ';' between parameters
                return(0);
            }
            offset++;

            offset += HttpRuleParser.GetWhitespaceLength(input, offset);

            //  cookie-av = expires-av / max-age-av / domain-av / path-av / secure-av / samesite-av / httponly-av / extension-av
            itemLength = HttpRuleParser.GetTokenLength(input, offset);
            if (itemLength == 0)
            {
                // Trailing ';' or leading into garbage. Let the next parser fail.
                break;
            }
            var token = input.Subsegment(offset, itemLength);
            offset += itemLength;

            //  expires-av = "Expires=" sane-cookie-date
            if (StringSegment.Equals(token, ExpiresToken, StringComparison.OrdinalIgnoreCase))
            {
                // = (no spaces)
                if (!ReadEqualsSign(input, ref offset))
                {
                    return(0);
                }
                // We don't want to include comma, becouse date may contain it (eg. Sun, 06 Nov...)
                var            dateString = ReadToSemicolonOrEnd(input, ref offset, includeComma: false);
                DateTimeOffset expirationDate;
                if (!HttpRuleParser.TryStringToDate(dateString, out expirationDate))
                {
                    // Invalid expiration date, abort
                    return(0);
                }
                result.Expires = expirationDate;
            }
            // max-age-av = "Max-Age=" non-zero-digit *DIGIT
            else if (StringSegment.Equals(token, MaxAgeToken, StringComparison.OrdinalIgnoreCase))
            {
                // = (no spaces)
                if (!ReadEqualsSign(input, ref offset))
                {
                    return(0);
                }

                itemLength = HttpRuleParser.GetNumberLength(input, offset, allowDecimal: false);
                if (itemLength == 0)
                {
                    return(0);
                }
                var  numberString = input.Subsegment(offset, itemLength);
                long maxAge;
                if (!HeaderUtilities.TryParseNonNegativeInt64(numberString, out maxAge))
                {
                    // Invalid expiration date, abort
                    return(0);
                }
                result.MaxAge = TimeSpan.FromSeconds(maxAge);
                offset       += itemLength;
            }
            // domain-av = "Domain=" domain-value
            // domain-value = <subdomain> ; defined in [RFC1034], Section 3.5, as enhanced by [RFC1123], Section 2.1
            else if (StringSegment.Equals(token, DomainToken, StringComparison.OrdinalIgnoreCase))
            {
                // = (no spaces)
                if (!ReadEqualsSign(input, ref offset))
                {
                    return(0);
                }
                // We don't do any detailed validation on the domain.
                result.Domain = ReadToSemicolonOrEnd(input, ref offset);
            }
            // path-av = "Path=" path-value
            // path-value = <any CHAR except CTLs or ";">
            else if (StringSegment.Equals(token, PathToken, StringComparison.OrdinalIgnoreCase))
            {
                // = (no spaces)
                if (!ReadEqualsSign(input, ref offset))
                {
                    return(0);
                }
                // We don't do any detailed validation on the path.
                result.Path = ReadToSemicolonOrEnd(input, ref offset);
            }
            // secure-av = "Secure"
            else if (StringSegment.Equals(token, SecureToken, StringComparison.OrdinalIgnoreCase))
            {
                result.Secure = true;
            }
            // samesite-av = "SameSite=" samesite-value
            // samesite-value = "Strict" / "Lax" / "None"
            else if (StringSegment.Equals(token, SameSiteToken, StringComparison.OrdinalIgnoreCase))
            {
                if (!ReadEqualsSign(input, ref offset))
                {
                    result.SameSite = SameSiteMode.Unspecified;
                }
                else
                {
                    var enforcementMode = ReadToSemicolonOrEnd(input, ref offset);

                    if (StringSegment.Equals(enforcementMode, SameSiteStrictToken, StringComparison.OrdinalIgnoreCase))
                    {
                        result.SameSite = SameSiteMode.Strict;
                    }
                    else if (StringSegment.Equals(enforcementMode, SameSiteLaxToken, StringComparison.OrdinalIgnoreCase))
                    {
                        result.SameSite = SameSiteMode.Lax;
                    }
                    else if (StringSegment.Equals(enforcementMode, SameSiteNoneToken, StringComparison.OrdinalIgnoreCase))
                    {
                        result.SameSite = SameSiteMode.None;
                    }
                    else
                    {
                        result.SameSite = SameSiteMode.Unspecified;
                    }
                }
            }
            // httponly-av = "HttpOnly"
            else if (StringSegment.Equals(token, HttpOnlyToken, StringComparison.OrdinalIgnoreCase))
            {
                result.HttpOnly = true;
            }
            // extension-av = <any CHAR except CTLs or ";">
            else
            {
                var tokenStart = offset - itemLength;
                ReadToSemicolonOrEnd(input, ref offset, includeComma: true);
                result.Extensions.Add(input.Subsegment(tokenStart, offset - tokenStart));
            }
        }

        parsedValue = result;
        return(offset - startIndex);
    }