public Task Invoke(IDictionary<string, object> environment) { if (!environment.ContainsKey("owin.RequestPath")) { throw new ApplicationException("Invalid OWIN request. Expected owin.RequestPath, but not present."); } var path = Uri.UnescapeDataString((string)environment["owin.RequestPath"]); if (statelessAuthOptions != null) { foreach (var ignorePath in statelessAuthOptions.IgnorePaths) { var mm = new Minimatcher(ignorePath, new Options(){IgnoreCase = true}); if (mm.IsMatch(path)) { return nextFunc(environment); } } } var requestHeaders = (IDictionary<string, string[]>)environment["owin.RequestHeaders"]; if (!requestHeaders.ContainsKey("Authorization")) { SetResponseStatusCodeAndHeader(environment); return ReturnCompletedTask(); } var token = requestHeaders["Authorization"].FirstOrDefault(); if (string.IsNullOrWhiteSpace(token)) { SetResponseStatusCodeAndHeader(environment); return ReturnCompletedTask(); } var validatedUser = tokenValidator.ValidateUser(token); if (validatedUser == null) { SetResponseStatusCodeAndHeader(environment); return ReturnCompletedTask(); } if (environment.ContainsKey(ServerUser)) { environment[ServerUser] = validatedUser; } else { environment.Add(ServerUser, validatedUser); } return nextFunc(environment); }
///<summary>Filters a list of inputs against a single pattern.</summary> ///<remarks>This function reparses this input on each invocation. For performance, avoid this function and reuse a Minimatcher instance instead.</remarks> public static IEnumerable <string> Filter(IEnumerable <string> list, string pattern, Options?options = null) { var mm = new Minimatcher(pattern, options); list = list.Where(mm.IsMatch); if (options != null && options.NoNull) { list = list.DefaultIfEmpty(pattern); } return(list); }
///<summary>Creates a filter function that tests input against a pattern.</summary> public static Func <string, bool> CreateFilter(string pattern, Options?options = null) { if (pattern == null) { throw new ArgumentNullException("pattern"); } // "" only matches "" if (string.IsNullOrWhiteSpace(pattern)) { return(string.IsNullOrEmpty); } var m = new Minimatcher(pattern, options); return(m.IsMatch); }
public static bool TestWEIgnore(string sourcePath, string serviceToken, string serviceName) { string ignoreFile = GetIgnoreFile(Path.GetDirectoryName(sourcePath), ".weignore"); if (string.IsNullOrEmpty(ignoreFile)) return false; string searchPattern; using (StreamReader reader = File.OpenText(ignoreFile)) { while ((searchPattern = reader.ReadLine()) != null) { searchPattern = searchPattern.Trim(); if (string.IsNullOrEmpty(searchPattern) || searchPattern[0] == '!') // Negated pattern continue; int index = searchPattern.LastIndexOf('\t'); if (index > 0) { string[] subparts = searchPattern.Substring(++index, searchPattern.Length - index).Split(',') .Select(p => p.Trim().ToLowerInvariant()).ToArray(); if (!(subparts.Contains(serviceToken) || subparts.Contains(serviceName)) && (subparts.Contains("!" + serviceToken) || subparts.Contains("!" + serviceName) || !subparts.Any(s => s[0] == '!'))) continue; searchPattern = searchPattern.Substring(0, index).Trim('\t'); } Minimatcher miniMatcher = new Minimatcher(searchPattern, new Options { AllowWindowsPaths = true }); if (miniMatcher.IsMatch(sourcePath)) return true; } } return false; }
/// <inheritdoc/> public override async Task<FtpResponse> Process(FtpCommand command, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(command.Argument)) { var taskStates = Server.GetBackgroundTaskStates(); var statusMessage = new StringBuilder(); statusMessage.AppendFormat("Server functional, {0} open connections", Server.Statistics.ActiveConnections); if (taskStates.Count != 0) statusMessage.AppendFormat(", {0} active background transfers", taskStates.Count); return new FtpResponse(211, statusMessage.ToString()); } var mask = command.Argument; if (!mask.EndsWith("*")) mask += "*"; var mmOptions = new Options() { IgnoreCase = Data.FileSystem.FileSystemEntryComparer.Equals("a", "A"), NoGlobStar = true, Dot = true, }; var mm = new Minimatcher(mask, mmOptions); var formatter = new LongListFormatter(); await Connection.WriteAsync($"211-STAT {command.Argument}", cancellationToken); foreach (var entry in (await Data.FileSystem.GetEntriesAsync(Data.CurrentDirectory, cancellationToken)).Where(x => mm.IsMatch(x.Name))) { var line = formatter.Format(entry); Connection.Log?.Debug(line); await Connection.WriteAsync($" {line}", cancellationToken); } return new FtpResponse(211, "STAT"); }
public string GetSchemaFor(string fileLocation) { foreach (string url in _schemas.Keys) { try { if (_schemas[url] == null) continue; foreach (string file in _schemas[url]) { var pattern = "**/" + file.TrimStart('*', '/'); var matche = new Minimatcher(pattern, _options); if (matche.IsMatch(fileLocation)) return url; } } catch { Logger.Log("JSON Schema: Couldn't parse " + _schemas[url] + " as a valid regex."); } } return null; }
/// <inheritdoc/> public override async Task<FtpResponse> Process(FtpCommand command, CancellationToken cancellationToken) { await Connection.WriteAsync(new FtpResponse(150, "Opening data connection."), cancellationToken); ITcpSocketClient responseSocket; try { responseSocket = await Connection.CreateResponseSocket(); } catch (Exception) { return new FtpResponse(425, "Can't open data connection."); } try { // Parse arguments in a way that's compatible with broken FTP clients var argument = new ListArguments(command.Argument); var showHidden = argument.All; // Instantiate the formatter IListFormatter formatter; if (string.Equals(command.Name, "NLST", StringComparison.OrdinalIgnoreCase)) { formatter = new ShortListFormatter(); } else if (string.Equals(command.Name, "LS", StringComparison.OrdinalIgnoreCase)) { formatter = new LongListFormatter(); } else { formatter = new LongListFormatter(); } // Parse the given path to determine the mask (e.g. when information about a file was requested) var directoriesToProcess = new Queue<DirectoryQueueItem>(); // Use braces to avoid the definition of mask and path in the following parts // of this function. { var mask = "*"; var path = Data.Path.Clone(); if (!string.IsNullOrEmpty(argument.Path)) { var foundEntry = await Data.FileSystem.SearchEntryAsync(path, argument.Path, cancellationToken); if (foundEntry?.Directory == null) return new FtpResponse(550, "File system entry not found."); var dirEntry = foundEntry.Entry as IUnixDirectoryEntry; if (dirEntry == null) { mask = foundEntry.FileName; } else if (!dirEntry.IsRoot) { path.Push(dirEntry); } } directoriesToProcess.Enqueue(new DirectoryQueueItem(path, mask)); } var encoding = Data.NlstEncoding ?? Connection.Encoding; using (var stream = await Connection.CreateEncryptedStream(responseSocket.WriteStream)) { using (var writer = new StreamWriter(stream, encoding, 4096, true) { NewLine = "\r\n", }) { while (directoriesToProcess.Count != 0) { var queueItem = directoriesToProcess.Dequeue(); var currentPath = queueItem.Path; var mask = queueItem.Mask; var currentDirEntry = currentPath.Count != 0 ? currentPath.Peek() : Data.FileSystem.Root; if (argument.Recursive) { var line = currentPath.ToDisplayString() + ":"; Connection.Log?.Debug(line); await writer.WriteLineAsync(line); } var mmOptions = new Options() { IgnoreCase = Data.FileSystem.FileSystemEntryComparer.Equals("a", "A"), NoGlobStar = true, Dot = true, }; var mm = new Minimatcher(mask, mmOptions); var entries = await Data.FileSystem.GetEntriesAsync(currentDirEntry, cancellationToken); var enumerator = new DirectoryListingEnumerator(entries, Data.FileSystem, currentPath, true); while (enumerator.MoveNext()) { var name = enumerator.Name; if (!enumerator.IsDotEntry) { if (!mm.IsMatch(name)) continue; if (name.StartsWith(".") && !showHidden) continue; } var entry = enumerator.Entry; if (argument.Recursive && !enumerator.IsDotEntry) { var dirEntry = entry as IUnixDirectoryEntry; if (dirEntry != null) { var subDirPath = currentPath.Clone(); subDirPath.Push(dirEntry); directoriesToProcess.Enqueue(new DirectoryQueueItem(subDirPath, "*")); } } var line = formatter.Format(entry, name); Connection.Log?.Debug(line); await writer.WriteLineAsync(line); } } } } } finally { responseSocket.Dispose(); } // Use 250 when the connection stays open. return new FtpResponse(250, "Closing data connection."); }
/// <inheritdoc/> public override async Task<FtpResponse> Process(FtpCommand command, CancellationToken cancellationToken) { await Connection.WriteAsync(new FtpResponse(150, "Opening data connection."), cancellationToken); ITcpSocketClient responseSocket; try { responseSocket = await Connection.CreateResponseSocket(); } catch (Exception) { return new FtpResponse(425, "Can't open data connection."); } try { var argument = command.Argument; IListFormatter formatter; if (string.Equals(command.Name, "NLST", StringComparison.OrdinalIgnoreCase)) { formatter = new ShortListFormatter(); } else { formatter = new LongListFormatter(); } var mask = (string.IsNullOrEmpty(argument) || argument.StartsWith("-")) ? "*" : argument; var encoding = Data.NlstEncoding ?? Connection.Encoding; using (var stream = await Connection.CreateEncryptedStream(responseSocket.WriteStream)) { using (var writer = new StreamWriter(stream, encoding, 4096, true) { NewLine = "\r\n", }) { foreach (var line in formatter.GetPrefix(Data.CurrentDirectory)) { Connection.Log?.Debug(line); await writer.WriteLineAsync(line); } var mmOptions = new Options() { IgnoreCase = Data.FileSystem.FileSystemEntryComparer.Equals("a", "A"), NoGlobStar = true, Dot = true, }; var mm = new Minimatcher(mask, mmOptions); foreach (var entry in (await Data.FileSystem.GetEntriesAsync(Data.CurrentDirectory, cancellationToken)).Where(x => mm.IsMatch(x.Name))) { var line = formatter.Format(entry); Connection.Log?.Debug(line); await writer.WriteLineAsync(line); } foreach (var line in formatter.GetSuffix(Data.CurrentDirectory)) { Connection.Log?.Debug(line); await writer.WriteLineAsync(line); } } } } finally { responseSocket.Dispose(); } // Use 250 when the connection stays open. return new FtpResponse(250, "Closing data connection."); }
///<summary>Filters a list of inputs against a single pattern.</summary> ///<remarks>This function reparses this input on each invocation. For performance, avoid this function and reuse a Minimatcher instance instead.</remarks> public static IEnumerable<string> Filter(IEnumerable<string> list, string pattern, Options options = null) { var mm = new Minimatcher(pattern, options); list = list.Where(mm.IsMatch); if (options != null && options.NoNull) list = list.DefaultIfEmpty(pattern); return list; }
///<summary>Creates a filter function that tests input against a pattern.</summary> public static Func<string, bool> CreateFilter(string pattern, Options options = null) { if (pattern == null) throw new ArgumentNullException("pattern"); // "" only matches "" if (String.IsNullOrWhiteSpace(pattern)) return String.IsNullOrEmpty; var m = new Minimatcher(pattern, options); return m.IsMatch; }
public void Pattern(string pattern) { bool not = pattern.StartsWith("!", StringComparison.Ordinal); if (not) { pattern = pattern.Substring(1); } pattern = _absolutePattern(_cwd, pattern); var f = pattern.IndexOfAny(new char[] { '*', '?', '[', '(', '{', '+' }); if (f < 0) { if (!not) { if (File.Exists(pattern.Replace('/', '\\'))) { var key = pattern.ToLowerInvariant(); if (!_files.ContainsKey(key)) { _files.Add(key, pattern); } } } else { var key = pattern.ToLowerInvariant(); if (_files.ContainsKey(key)) { _files.Remove(key); } } } else { f = pattern.LastIndexOf('/', f); if (f < 0) { throw new FormatException("Can't deterim root."); } var root = pattern.Substring(0, f); var matcher = new Minimatch.Minimatcher(pattern.Substring(f + 1)); if (!not) { foreach (var filename in Directory.EnumerateFiles(root.Replace('/', '\\'), "*", SearchOption.AllDirectories)) { var key = filename.Replace('\\', '/').ToLowerInvariant(); if (!_files.ContainsKey(key) && matcher.IsMatch(key.Substring(f + 1))) { _files.Add(key, filename); } } } else { root = (root + '/').ToLowerInvariant(); var toremove = new List <string>(); foreach (var key in _files.Keys) { if (key.StartsWith(root, StringComparison.Ordinal)) { if (matcher.IsMatch(key.Substring(f + 1))) { toremove.Add(key); } } } foreach (var key in toremove) { _files.Remove(key); } } } // var glob = Glob.Parse(); }