Generate url from regex into other in C# - c#

I want to generate an url which uses regular expression like (currentUrlRegex:
currentUrlRegex = #"https://www.website.com/[a-z]{2})-[a-z]{2})/file/(.*)";
and will be redirected to:
toUrlRegex = #"https://www.website.com/$1-$2/file/system/$3";
If someone access like: https://www.website.com/en-en/file/123.png then redirects to https://www.website.com/en-en/file/system/123.png
I want to match current url from request (in ASP.NET MVC) with currentUrlRegex. If match then redirect to an url matched in toUrlRegex with transformation.
I have those regex urls in a file which is managed from CMS (can be added, deleted, renamed, etc)
I created an HTTP module:
public void Init(HttpApplication context)
{
_context = context;
context.PostResolveRequestCache += ContextOnPostResolveRequestCache;
}
private void ContextOnPostResolveRequestCache(object sender, EventArgs eventArgs)
{
string currentUrl = _context.Request.Url.GetLeftPart(UriPartial.Path).TrimEnd('/');
// read all kind of regex urls from a file into a list of RedirectModel
string redirectUrl = string.Empty;
foreach (RedirectModel redirectModel in list) {
try {
string url = new Uri(redirectModel.FromUrl).GetLeftPart(UriPartial.Path).TrimEnd('/');
if (url.Equals(currentUrl, StringComparison.InvariantCultureIgnoreCase)) {
redirectUrl = redirectModel.ToUrl;
break;
}
} catch {
// use regex here when Uri is invalid (contains *,),(, etc)
}
}
if (!string.IsNullOrWhiteSpace(redirectUrl)) {
_context.Response.RedirectPermanent(redirectUrl);
}
}
and RedirectModel has two simple properties of string type: FromUrl and ToUrl.
Can you help me how to achieve regex side ? For simple url I managed

Use Regex.Replace and the strings mostly as you provided them, just with corrected parenthesis in the search pattern.
var input = #"https://www.website.com/en-en/file/123.png";
var output = Regex.Replace(
input,
#"https://www.website.com/([a-z]{2})-([a-z]{2})/file/(.*)",
#"https://www.website.com/$1-$2/file/system/$3");

The URL conversion may look something like this
var input = #"https://www.website.com/en-en/file/123.png";
Regex rgx = new Regex(#"https://www.website.com/([a-z]{2})-([a-z]{2})\/file\/(.*)");
MatchCollection m = rgx.Matches(input);
if (m.Count > 0 && m.Count == 1)
{
var matchGroup = m[0].Groups;
var redirecturl = string.Format("https://www.website.com/{0}-{1}/file/system/{2}", matchGroup[1].Value, matchGroup[2].Value, matchGroup[3].Value);
}

Related

How to check if Parse(args) is true or false

I have code that is not throwing any error. I have used NDesk option set and added 2 string Parameters. I can see it has pulled correct names in args. But when I uses parse(args) it is not throwing an error. So I am assuming it is working.
I am trying to check if p(args) is true or false. But I can not use bool expressions to List<string>.
Any help how I can accomplish that. I want execute function if parse has correct arguments.
My code is like this
private static Regex fileNamePattern = new Regex(#"^[A-Z0-9]{8}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{12}[.]pdf$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
//missing method name
{
string inputFile;
string outputFile;
var p = new OptionSet() {
{"i"," pdf file",v=>inputFile=v},{"o","index file with kws",v=>outputFile=v},
};
Console.WriteLine($"args length: {args.Length}");
Console.WriteLine($"args 0: {args[0]}");
Console.WriteLine($"args 1: {args[1]}");
p.Parse(args); //I would like to use this if(parse(args))
{
}
//
}
private static void UpdateImportIndexFile(string inputFile, string outputFile)
{
using (var dip = File.CreateText(outputFile))
{
var match = fileNamePattern.Match(Path.GetFileName(MainFilePath));
if (match.Success)
{
//create text file (outputfile);
}
}
}
Since p is an instance of a class and the parse method does not support a return to emulate in a sense the functionality of a TryParse wrap your parse in a try block
try{
val = p.Parse(args);
}catch(OptionException e){
//if false
}
For more information http://www.ndesk.org/doc/ndesk-options/NDesk.Options/OptionSet.html#M:NDesk.Options.OptionSet.Parse(System.Collections.Generic.IEnumerable{System.String})

Visual Studio Load Test redirect URL from Siteminder

I have a security application called Siteminder. It creates unique URLS for every authentication. HTTPS://SITE/idp/**RANDOMURLSTRING**/resumeSAML20/idp/startSSO.ping
How can i capture the Unique URL and have the test continue to login.
A webtest assumes the next URL in the process. It does not support[Or I don't know how] a unique redirect to a random URL. Does anyone know of a way to handle this case?
EDIT:
My Solution -- Replace the SessionID with {{SessionID}} in all the URLS and use this extraction rule
public class ExtractSiteMinderCustomUrl : ExtractionRule
{
public string SiteMinderSessionID { get; private set; }
// The Extract method. The parameter e contains the web performance test context.
//---------------------------------------------------------------------
public override void Extract(object sender, ExtractionEventArgs e)
{
//look for anchor tags with URLS
Regex regex = new Regex("<a\\s+(?:[^>]*?\\s+)?href=\"([^\"]+\\?[^\"]+)\"");
MatchCollection match = regex.Matches(e.Response.BodyString);
if (match.Count > 0)
{
foreach (Match ItemMatch in match)
{
if (ItemMatch.ToString().Contains("/idp/"))
{
//start and ends string from the sitemindersession is in the link on the page
e.WebTest.Context.Add(this.ContextParameterName, GetStringBetween(ItemMatch.ToString(), "/idp/", "/resume"));
e.Success = true;
return;
}
}
e.Success = false;
e.Message = String.Format(CultureInfo.CurrentCulture, "Not Found in Link : /idp/");
}
else
{
e.Success = false;
e.Message = String.Format(CultureInfo.CurrentCulture, "No href tags found");
}
}
public static string GetStringBetween(string token, string first, string second)
{
if (!token.Contains(first)) return "";
var afterFirst = token.Split(new[] { first }, StringSplitOptions.None)[1];
if (!afterFirst.Contains(second)) return "";
var result = afterFirst.Split(new[] { second }, StringSplitOptions.None)[0];
return result;
}
}
The simple answer is to have use extraction rule that gets the **RANDOMURLSTRING** then change the URLs in the requests to be, for example, HTTPS://SITE/idp/{{TheRandomString}}/resumeSAML20/idp/startSSO.ping where TheRandomString is the context parameter that holds the extracted value. Note the doubled curly braces ({{ and }}) around the context parameter.
Suppose a value returned by the first redirection needs to be captured but a normal web test would redirect again and so the response is not seen by the extraction rules. In this case need to handle the redirect explicitly. Set the Follow redirects property of the initial request to false then add extraction rule(s) to gather the wanted values. Add a new request after the initial request and use the extracted values in it as necessary. It is possible to extract the entire redirected url and set the Url field to the extracted value.

Intercept the OData "query"

I would like to "intercept"/alter the OData query that's generated when using OData with the Web API.. but I'm not entirely sure of how to "extract" the generated query.. I assume that the OData filter,expands and more some how gets generated to some sort of expression tree or some sort of query.. and if that's the case, then that's the type of query I would like to be able to alter before its sent to the database as an SQL-command.
I have searched the net for some way of extracting the generated expression tree.. but hasn't be able to find sufficient information, so I was sort of hoping that someone here has some more insight of how the whole OData-"framework" works..
Any ideas of where to start?
You can alter Odata url before it is executed. Inherit from EnableQueryAttribute class and change url. Following is a real case to change guid string format to hexadecimal string format before it's sent to oracle.
public class EnableQueryForGuid : EnableQueryAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
var url = actionContext.Request.RequestUri.OriginalString;
var newUrl = ModifyUrl(url);
actionContext.Request.RequestUri = new Uri(newUrl);
base.OnActionExecuting(actionContext);
}
private string ModifyUrl(string url)
{
Regex regex = new Regex(#"%27([A-Za-z0-9]{32})%27");
var res = regex.Matches(url);
if (res.Count > 0)
{
var guidPart = res[0].Value.Remove(0, 3);
guidPart = guidPart.Remove(guidPart.Length - 3, 3);
var guidValue = new Guid(BitConverter.ToString((new Guid(guidPart)).ToByteArray()).Replace("-", ""));
url = url.Replace(res[0].Value, guidValue.ToString());
}
return url;
}
}
then use this new attribute on your controller method:
[HttpGet]
[EnableQueryForGuid]
[ODataRoute("GetSomething")]
public IHttpActionResult GetSomething()
{
....
}
original query:
OData/GetSomething?&$filter=MyGuid%20eq%20%272C3C7BC0EC7FA248B0DEE3DAA371EE73%27
altered query:
OData/GetSomething?&$filter=MyGuid%20eq%20e5794d6a-5db1-475a-8c49-0f91a8f53c8a

Remove additional slashes from URL

In ASP.Net it is posible to get same content from almost equal pages by URLs like
localhost:9000/Index.aspx and localhost:9000//Index.aspx or even localhost:9000///Index.aspx
But it isn't looks good for me.
How can i remove this additional slashes before user go to some page and in what place?
Use this :
url = Regex.Replace(url , #"/+", #"/");
it will support n times
see
https://stackoverflow.com/a/19689870
https://msdn.microsoft.com/en-us/library/9hst1w91.aspx#Examples
You need to specify a base Uri and a relative path to get the canonized behavior.
Uri baseUri = new Uri("http://www.contoso.com");
Uri myUri = new Uri(baseUri, "catalog/shownew.htm");
Console.WriteLine(myUri.ToString());
This solution is not that pretty but very easy
do
{
url = url.Replace("//", "/");
}
while(url.Contains("//"));
This will work for many slashes in your url but the runtime is not that great.
Remove them, for example:
url = url.Replace("///", "/").Replace("//", "/");
Regex.Replace("http://localhost:3000///////asdasd/as///asdasda///asdasdasd//", #"/+", #"/").Replace(":/", "://")
Here is the code snippets for combining URL segments, with the ability of removing the duplicate slashes:
public class PathUtils
{
public static string UrlCombine(params string[] components)
{
var isUnixPath = Path.DirectorySeparatorChar == '/';
for (var i = 1; i < components.Length; i++)
{
if (Path.IsPathRooted(components[i])) components[i] = components[i].TrimStart('/', '\\');
}
var url = Path.Combine(components);
if (!isUnixPath)
{
url = url.Replace(Path.DirectorySeparatorChar, '/');
}
return Regex.Replace(url, #"(?<!(http:|https:))//", #"/");
}
}

Redirect in a Sitecore solution Noob

Here What I am trying to do, my employer want to be able to be able do 301 redirect with regex expression with the alias in Sitecore so the way I am trying to implement this is like this!
a singleline text field
with a checkbox to tell sitecore it will be a regex expression I am a noob in .NET and Sitecore how can I implement this ? here a exemple http://postimg.org/image/lwr524hkn/
I need help the exemple of redirect I want handle is like this, this is a exemple of the redirect I want to do it could be product at the place of solution.
exemple.com/en/solution/platform-features to
exemple.com/en/platform-features
I base the code from http://www.cmssource.co.uk/blog/2011/December/modifying-sitecore-alias-to-append-custom-query-strings-via-301-redirect this is for query string I want to use regex expression.
namespace helloworld.Website.SC.Common
{
public class AliasResolver : Sitecore.Pipelines.HttpRequest.AliasResolver
{
// Beginning of the Methods
public new void Process(HttpRequestArgs args)
{
Assert.ArgumentNotNull(args, "args");
if (!Settings.AliasesActive)
{
Tracer.Warning("Aliases in AliasResolver are not active.");
}
else
{
Sitecore.Data.Database database = Context.Database;
if (database == null)
{
Tracer.Warning("There is no context in the AliasResolver.");
}
else
{
{
Profiler.StartOperation("Resolve virgin alias pipeline.");
Item item = ItemManager.GetItem(FileUtil.MakePath("/sitecore/system/aliases", args.LocalPath, '/'), Language.Current, Sitecore.Data.Version.First, database, SecurityCheck.Disable);
if (item != null)
{
//Alias existis (now we have the alias item)
if (item.Fields["Regular Expressions"] != null)
{
if (!String.IsNullOrEmpty(item.Fields["Regular Expressions"].Value) && !args.Url.QueryString.Contains("aproc"))
{
var reg = new Regex(#"(?<Begin>([^/]*/){2})[^/]*/(?<End>.*)");
var match = reg.Match(#"exemple.com/en/solution/platform-features");
var result = match.Groups["Begin"].Value + match.Groups["End"].Value;
}
}
}
Profiler.EndOperation();
}
catch (Exception ex)
{
Log.Error("Had a problem in the VirginAliasResolver. Error: " + ex.Message, this);
}
}
}
}
///<summary>
/// Once a match is found and we have a Sitecore Item, we can send the 301 response.
///</summary>
private static void SendResponse(string redirectToUrl, HttpRequestArgs args)
{
args.Context.Response.Status = "301 Moved Permanently";
args.Context.Response.StatusCode = 301;
args.Context.Response.AddHeader("Location", redirectToUrl);
args.Context.Response.End();
}
}
}
PS: I know they have module for this but my employer want it done that way and I am reaching for help since it's been a week I'm trying to add this feature
So if I understand correctly, you do not want to select an Alias by path:
Item item = ItemManager.GetItem(FileUtil.MakePath("/sitecore/system/aliases", args.LocalPath, '/'), Language.Current, Sitecore.Data.Version.First, database, SecurityCheck.Disable);
But rather find an Alias comparing a Regex field to the Url. I have not tested this, but it could be someting like:
var originalUrl = HttpContext.Current.Request.Url;
var allAliases = Sitecore.Context.Database.SelectItems("/sitecore/system/aliases//*");
var foundAlias = allAliases.FirstOrDefault( alias =>
!string.IsNullOrEmpty(alias["Regular Expressions"]) &&
Regex.IsMatch(HttpContext.Current.Request.Url.ToString(), alias["Regular Expressions"]));
Then, if foundAlias != null, you can retrieve the url and redirect like you do in your private SendResponse function.
var linkField = (LinkField)foundAlias.Fields["linked item"];
var targetUrl = linkField.Url;
using (new SecurityDisabler())
{
if (string.IsNullOrEmpty(targetUrl) && linkField.TargetItem != null)
targetUrl = LinkManager.GetItemUrl(linkField.TargetItem);
}
SendResponse(targetUrl, args);
Again, I have not tested this so don't shoot me if it needs some corrections, but this should help you get on your way.

Categories