Callback URL matching logic - c#

I am working on an OAuth type module. In this i have a collection of URLs which are called as Whitelist URLs. I have to check whether the callback URL specified matches with any of these URLs in the collection.
I've written the following code. Please let me know whether i've done it correctly or am i missing some steps. Also, please let me know if i need any kind of refactoring if i want to unit test these methods.
The code is:
public class ValidateURLs
{
public bool MatchRedirectUrl(string requestUrl, IList<string> urlCollection)
{
var requestUri = new Uri(requestUrl);
foreach (var url in urlCollection)
{
var matchUri = new Uri(url);
if (IsDomainMatching(requestUri, matchUri))
{
if (IsPortMatch(requestUri, matchUri))
{
if (IsPathMatch(requestUri, matchUri))
return true;
else
return false;
}
}
}
return false;
}
private bool IsDomainMatching(Uri url1, Uri url2)
{
var result = String.Compare(url1.Host, url2.Host);
if (result == 0)
return true;
else
return false;
}
private bool IsPortMatch(Uri url1, Uri url2)
{
if (url1.Port == url2.Port)
return true;
return false;
}
private bool IsPathMatch(Uri url1, Uri url2)
{
return (url1.PathAndQuery.StartsWith(url2.PathAndQuery) || url2.PathAndQuery.StartsWith(url1.PathAndQuery));
}
}
Thanks in advance.
Regards,
Suyog

Instead of writing all this code, you should look at Uri.Compare
But you also want path.startswith to be part of the comparison. Notice it takes a bitwise enum UriComponents to define which components of the url to compare. So you could replace much of the code with Uri.Compare not comparing path and then have a startsWith path ANDed.
So all your code could be replaced with something like:
Uri.Compare(uri1, uri2, UriComponents.HostAndPort, ...) == 0 &&
(url1.PathAndQueryStartsWith(url2.PathAndQuery) || url.PathAndQueryStartsWith(...));
On a side note, code in this form:
var result = String.Compare(url1.Host, url2.Host);
if (result == 0)
return true;
else
return false;
Can simply be written as:
return String.Compare(url1.Host, url2.Host) == 0;
You should also do case insensitive compares with: StringComparison.OrdinalIgnoreCase

Related

How to return a File in a different method than the main one?

I want to download a file via Results.File(). It works when executing it in the main method (app.MapGet), however returning it in a different method does do nothing. The line where it should send the file is executed in the Debugger, however it does not return, but jumps back to the main method to execute the last return (The one that never should be executed). This last return does indeed return a result.
I have also used several methods like Result.BadRequest(), however nothing is executed when it is not in the main method.
I saw people using IResult as return method but I am not sure whether this is even right.
My guess is maybe the wrong return type or executing a Task or so.
Whole methods:
app.MapGet("/", (HttpContext context) =>
{
if (context.Request.Query.ContainsKey("amount"))
{
if (context.Request.Query["amount"].Count > 1)
{
return Results.BadRequest(new { Error = "The query parameter 'amount' may only be used once." });
}
if (int.TryParse(context.Request.Query["amount"], out int amount))
{
if (amount <= 0)
{
return Results.BadRequest(new { Error = "The specified amount must be greater or equal to 1." });
}
var list = new List<string>();
for (int i = 0; i < amount; i++)
{
list.Add(Ulid.NewUlid().ToString());
}
CheckIfDownload(context, (list, null));
return Results.Json(new { Ulids = list });
}
else
{
return Results.BadRequest(new { Error = "The specified amount is not a valid number." });
}
}
string ulid = Ulid.NewUlid().ToString();
CheckIfDownload(context, (null, ulid));
return Results.Json(new { Ulid = ulid });
});
static IResult? CheckIfDownload(HttpContext context, (List<string>? list, string? single) ulidListOrSingle)
{
if (context.Request.Query.ContainsKey("download"))
{
if (context.Request.Query["download"].Count > 1)
{
return Results.BadRequest(new { Error = "The query parameter 'download' may only be used once." });
}
if (context.Request.Query["download"] == "" || (bool.TryParse(context.Request.Query["download"], out bool download) && download))
{
if (ulidListOrSingle.list != null)
{
return SendJsonFile(JsonSerializer.Serialize(ulidListOrSingle.list));
}
if (ulidListOrSingle.single != null)
{
return SendJsonFile(JsonSerializer.Serialize(ulidListOrSingle.single));
}
return Results.BadRequest(new { Error = "An unknown error occurred." });
}
}
return null;
}
static IResult SendJsonFile(string data)
{
byte[] buffer = Encoding.UTF8.GetBytes(data);
var stream = new MemoryStream(buffer);
return Results.File(stream, "application/json", $"UlidGenerator_{DateTime.Now:MM-dd-yyyy_HH-mm-ss}.json");
}
when you inline an entire method block (not just a single expression), you must return what you want to be the output of the block. In your case you are not capturing the result of SendJsonFile to return it:
app.MapGet("/download", () =>
{
string data = "json data";
var result = SendJsonFile(data);
return result;
});

How to refactor this? ^^

Hi I have a "dumb" question. Here is my problem:
string ct=ctx.Request.ContentType;
if (!string.IsNullOrEmpty(ct))
{
ct=new ContentType(ct).MediaType;
if (!ct.Equals(KnownMimeType.Json, StringComparison.InvariantCultureIgnoreCase) || !ct.Equals(KnownMimeType.Xml, StringComparison.InvariantCultureIgnoreCase))
{
RespondWith(Status.BadRequest, "!json or xml");
return;
}
}
With the conditional Operator when an XML is sent the if body is executed which shouldn't be the case.
This is my current solution but the code with the empty method bodies is horrible. :/
string ct=ctx.Request.ContentType;
if (!string.IsNullOrEmpty(ct))
{
ct=new ContentType(ct).MediaType;
if (ct.Equals(KnownMimeType.Json, StringComparison.InvariantCultureIgnoreCase)) { }
else if (ct.Equals(KnownMimeType.Xml, StringComparison.InvariantCultureIgnoreCase)) { }
else
{
RespondWith(Status.BadRequest, "!json or xml");
return;
}
}
The goal is that every Content Type except JSON and XML should be responded with Status.BadReqeust
What can I do to refactor this?
Thanks from a newbie.
Use this.
if (!(ct.Equals(KnownMimeType.Json, StringComparison.InvariantCultureIgnoreCase) || ct.Equals(KnownMimeType.Xml, StringComparison.InvariantCultureIgnoreCase))) { RespondWith(Status.BadRequest, "!json or xml");
//For the sake of brevity and readable code.This may be your solution
string ct=ctx.Request.ContentType;
if (!string.IsNullOrEmpty(ct))
{
ct=new ContentType(ct).MediaType;
var isJson = ct.Equals(KnownMimeType.Json, StringComparison.InvariantCultureIgnoreCase);
var isXml =ct.Equals(KnownMimeType.Xml, StringComparison.InvariantCultureIgnoreCase);
if(isJson || isXml)
continue;
else
return RespondWith(Status.BadRequest, "!json or xml");
}
else
return RespondWith(Status.BadRequest, "Invalid content type");
//Maybe you can change status code instead of BadRequest for invalid content type
private Result RespondWith(Status status,string message)
{
}
//I assume that you return a dto like this
public class Result
{
public Status Status;
public string Message;
}

Foreach loop only validates first element

I'm validating TextFields with a foreach loop with an if/else statement inside. This all happens inside a public virtual Boolean Method(). Only the first element is validated and I don't know why the rest is not validated.
How do I have to change my method so it will validate all the items in TextFieldList?
This is my method:
public virtual Boolean ValidateTextFields(){
foreach (UITextField item in TextFieldList) {
if (item.Text == "") {
item.AttributedPlaceholder = new NSAttributedString (item.Placeholder, foregroundColor: UIColor.Red);
return false;
} else {
return true;
}
}
return true;
}
EDIT:
I got it working but now I have another issue, I have multiple methods like ValidateTextFields and I check them like this:
if (ValidateTextFields() && ValidateEmail() ) {
Console.WriteLine ("CONTINUE TO NEXT SCREEN");
} else {
Console.WriteLine ("ERRORRRRRR");
}
Now if ValidateTextFields() is false then ValidateEmail() is never called so the EmailTextFields won't be validated. Only after ValidateTextFields() is true I can validate ValidateEmail(). Is there a way to call both methods at the same time and check if they are true?
Try this:
If have any invalid field the Method returns false, else if all fields is valid returns true.
public virtual Boolean ValidateTextFields(){
foreach (UITextField item in TextFieldList) {
if (item.Text == "") {
item.AttributedPlaceholder = new NSAttributedString (item.Placeholder, foregroundColor: UIColor.Red);
return false;
}
}
return true;
}
Or you can valid all itens to put a attributedplaceholder for each item and returns if has any invalid, like this:
public virtual Boolean ValidateTextFields(){
bool hasInvalidFields = false;
foreach (UITextField item in TextFieldList) {
if (item.Text == "") {
item.AttributedPlaceholder = new NSAttributedString (item.Placeholder, foregroundColor: UIColor.Red);
hasInvalidFields = true;
}
}
return !hasInvalidFields;
}
For your edit, to call all validates you can:
bool validTextFields = ValidateTextFields();
bool validEmails = ValidateEmail();
if ( validTextFields && validEmails) {
Console.WriteLine ("CONTINUE TO NEXT SCREEN");
} else {
Console.WriteLine ("ERRORRRRRR");
}
Your code will always return after the first element has been processed, whether it's valid or not.
What you probably want instead is to validate all elements and return afterwards:
var result = true;
foreach (UITextField item in TextFieldList) {
if (item.Text == "") {
item.AttributedPlaceholder =
new NSAttributedString (item.Placeholder, foregroundColor: UIColor.Red);
result = false;
}
}
return result;
You simply need to remember what to return in the end instead of returning immediately.

How to read cookies4.dat file using c#?

I want to display the list of cookies, i am unable to read this file. can anyone please guide me on reading data from this file(cookies4.dat).
It is from opera browser.
Thanks in Advance.
Have you tried the documentation?
This CodeProject article shows details on reading cookies for the major browsers, including Opera. Unfortunately it doesn't give much details on how the magic is done but you should be able to download the code and check it out.
A couple of methods included:
private static string GetOperaCookiePath()
{
string s = Environment.GetFolderPath(
Environment.SpecialFolder.ApplicationData);
s += #"\Opera\Opera\cookies4.dat";
if (!File.Exists(s))
return string.Empty;
return s;
}
private static bool GetCookie_Opera(string strHost, string strField, ref string Value)
{
Value = "";
bool fRtn = false;
string strPath;
// Check to see if Opera Installed
strPath = GetOperaCookiePath();
if (string.Empty == strPath) // Nope, perhaps another browser
return false;
try
{
OpraCookieJar cookieJar = new OpraCookieJar(strPath);
List<O4Cookie> cookies = cookieJar.GetCookies(strHost);
if (null != cookies)
{
foreach (O4Cookie cookie in cookies)
{
if (cookie.Name.ToUpper().Equals(strField.ToUpper()))
{
Value = cookie.Value;
fRtn = true;
break;
}
}
}
}
catch (Exception)
{
Value = string.Empty;
fRtn = false;
}
return fRtn;
}
http://www.opera.com/docs/operafiles/#cookies

Reduce casting and better styling

Consider the following (nasty) code:
/// <summary>
/// Calls matching process error code on response.Code
/// </summary>
/// <param name="response">Actually will be of type Response or extend it</param>
/// <returns>true for successful response, false otherwise</returns>
private static bool ProcessErrorCode(object response)
{
bool isOkay = false;
const string unknown = "UNKNOWN";
string errCode = unknown;
if (response.GetType() == typeof(Response<AResponseCode>))
{
AResponseCode code = ((Response<AResponseCode>)response).Code;
isOkay = code == AResponseCode.Ok;
errCode = code.ToString();
}
if (response.GetType() == typeof(Response<BResponseCode>))
{
BResponseCode code = ((Response<BResponseCode>)response).Code;
isOkay = code == BResponseCode.Ok;
errCode = code.ToString();
}
if (response.GetType() == typeof(DataResponse<CResponseCode,string>))
{
CResponseCode code = ((DataResponse<CResponseCode, string>)response).Code;
isOkay = code == CResponseCode.Ok;
errCode = code.ToString();
}
if (isOkay)
{
return true;
}
string msg = "Operation resulted in error code:" + errCode;
LogErrorCode(msg);
return false;
}
I am trying to figure out a way to reduce castings and imrove the method style.
I have no code ownership on Response<TResponseCode>, DataResponse<TResponseCode,string>, AResponseCode, BResponseCode, CResponseCode
response parameter will be of type Response<TResponseCode> or inherit from it (DataResponse<TResponseCode,string> : Response<TResponseCode>)
All *ResponseCode are Enums and they all have an *ResponseCode.Ok entry
You could use a generic subroutine for this:
// Mocking your classes, just to check if it compiles. You don't need this.
class Response<T> {
public T Code { get { return default(T); } }
}
enum AResponseCode { Ok }
enum BResponseCode { Ok }
enum CResponseCode { Ok }
static void LogErrorCode(string msg) { }
private static bool ProcessErrorCode(object response)
{
bool isOkay;
string errCode;
if (!TryProcessErrorCode(response, AResponseCode.Ok, out isOkay, out errCode))
if (!TryProcessErrorCode(response, BResponseCode.Ok, out isOkay, out errCode))
TryProcessErrorCode(response, CResponseCode.Ok, out isOkay, out errCode);
if (isOkay)
{
return true;
}
string msg = "Operation resulted in error code:" + errCode;
LogErrorCode(msg);
return false;
}
// TResponseCode is automatically inferred by passing the okCode
private static bool TryProcessErrorCode<TResponseCode>(
object response, TResponseCode okCode,
out bool isOkay, out string errCode)
{
var resp = response as Response<TResponseCode>;
if (resp == null)
{
isOkay = false;
errCode = "UNKNOWN";
return false;
}
else
{
isOkay = okCode.Equals(resp.Code);
errCode = resp.Code.ToString();
return true;
}
}
Ideally, you'd give Response<TResponseCode> a common interface with an 'OK' function on it. Seeing as you can't, your solution is going to look a bit hacky.
Given that constraint, I'd extract a couple of methods - static bool IsResponseOk(object response) and static string GetResponseError(object response) - which would result in easier to read code, but still not brilliant.
You can get a slightly cleaner solution using generics:
private static void TestErrorCode<TCode>(object response, TCode ok, ref bool isOkay, ref string errCode)
{
Response<TCode> responseTyped = response as Response<TCode>;
if (responseTyped == null)
{
return;
}
TCode code = responseTyped.Code;
isOkay = code.Equals(ok);
errCode = code.ToString();
return;
}
private static bool ProcessErrorCode(object response)
{
bool isOkay = false;
string errCode = "UNKNOWN";
TestErrorCode(response, AResponseCode.Ok, ref isOkay, ref errCode);
TestErrorCode(response, BResponseCode.Ok, ref isOkay, ref errCode);
TestErrorCode(response, CResponseCode.Ok, ref isOkay, ref errCode);
if (isOkay)
{
return true;
}
LogErrorCode("Operation resulted in error code:" + errCode);
return false;
}
I'd swap a switch statement for all the ifs.
From a performance perspective, I'd replace .GetType() == typeof() with the is operator, eg:
if( response is DataResponse<CResponseCode,string> )
The following benchmark shows a performance improvement of roughly 3x on my machine:
var f = new List<string>();
var dummy = 0;
Stopwatch sw = new Stopwatch();
sw.Start();
for(int i=0; i< REPS; i++)
if(f.GetType() == typeof( List<string> )) dummy++;
sw.Stop();
Console.WriteLine(sw.Elapsed);
sw.Reset();
sw.Start();
for(int i=0; i< REPS; i++)
if(f is List<string> ) dummy++;
sw.Stop();
Console.WriteLine(sw.Elapsed);
// Outputs
00:00:00.0750046
00:00:00.0261598
I can't imagine to do something with this without finding person responsible for writing this XResponseZZZ.
Maybe others are smarter than me. But im convinced that you should find the guy and presuade to him that it should be XResponse responsibility to known if specified code is okay and what error message should be thrown. This is C coding style and it is done bad.
I looked at the Heinzi or Daniel generic solutions and I like them most.
Here's a solution with dynamic (can be edited to use reflection instead), untested and not recommended, but short.
It should work identically to your original function:
Since you rely on response.GetType() == typeof(XXX), which is not the same as response is XXX (inheritance is excluded), types.Contains(response.GetType()) is equivalent.
Since you guarantee that all these types have a property Code which is (presumably) an enum type that contains a value Ok, the dynamic portion should always succeed.
The fact that only the eligible types are included means that 'coincidences' cannot happen.
Cons:
Performance?
If the underlying types change, you will not be protected at compile-time.
private static bool ProcessErrorCode(object response)
{
var types = new[] { typeof(Response<AResponseCode>), typeof(Response<BResponseCode>), typeof(DataResponse<CResponseCode, string>)};
var errCode = !types.Contains(response.GetType())
?"UNKNOWN"
:(string)(((dynamic)response).Code.ToString());
if(errCode == "Ok") return true;
LogErrorCode("Operation resulted in error code:" + errCode);
return false;
}
This replaces my old answer as it clearly bombed :) (them's the breaks)
I don't expect this'll do any better - but you might find the approach interesting.
The basic idea is to define a result type that contains your IsOkay and ErrCode values, and then define a dictionary of delegates (keyed by the type of the object that they handle) that you consult. To add new handlers you simply add another delegate to the dictionary.
public class ResponseResult{
public bool IsOkay;
public string ErrCode;
}
public static class ResponseExtracter
{
//STARTING OFF HERE WITH THE NEW VERSION OF YOUR METHOD
public static bool ProcessErrorCode(object response)
{
Func<object, ResponseResult> processor = null;
ResponseResult result = new ResponseResult()
{
IsOkay = false, ErrCode = "UNKNOWN"
};
//try to get processor based on object's type
//then invoke it if we find one.
if (_processors.TryGetValue(response.GetType(), out processor))
result = processor(response);
if (result.IsOkay)
return true;
string msg = "Operation resulted in error code:" + result.ErrCode;
LogErrorCode(msg);
return false;
}
//A lot better no?
//NOW FOR THE INFRASTRUCTURE
static Dictionary<Type, Func<object, ResponseResult>> _processors
= new Dictionary<Type, Func<object, ResponseResult>>();
static ResponseExtracter()
{
//this can be replaced with self-reflection over methods
//with attributes that reference the supported type for
//each method.
_processors.Add(typeof(Response<AResponseCode>), (o) =>
{
AResponseCode code = ((Response<AResponseCode>)o).Code;
return new ResponseResult
{
IsOkay = code == AResponseCode.Ok,
ErrCode = code.ToString()
};
});
_processors.Add(typeof(Response<BResponseCode>), (o) =>
{
BResponseCode code = ((Response<BResponseCode>)o).Code;
return new ResponseResult
{
IsOkay = code == BResponseCode.Ok,
ErrCode = code.ToString()
};
});
_processors.Add(typeof(DataResponse<CResponseCode, string>),
(o) =>
{
CResponseCode code = ((DataResponse<CResponseCode, string>)o).Code;
return new ResponseResult
{
IsOkay = code == CResponseCode.Ok,
ErrCode = code.ToString()
};
});
}
}
Performance-wise it's better than it looks because the Dictionary<Type, TValue> is actually hashing on the integer value that underpins the type's TypeHandle. This is in fact an Int64 - so only the first 32 bits are used, but in practise it's highly unlikely that two types share the same first 32 bits of their handle.
I would be inclined to try to get the main body of code quite simple like this:
/// <summary>
/// Calls matching process error code on response.Code
/// </summary>
/// <param name="response">Actually will be of type Response or extend it</param>
/// <returns>true for successful response, false otherwise</returns>
private static bool ProcessErrorCode(object response)
{
Func<Type, Func<object, string>> process = ...;
var errCode = process(response.GetType())(response);
if (errCode != "Ok")
{
LogErrorCode("Operation resulted in error code:" + errCode);
}
return errCode == "Ok";
}
Then it just becomes a matter of defining the Func<Type, Func<object, string>>. This could be done using a separate method or by dependency injection.
The separate method would look like this:
private static Func<Type, Func<object, string>> _process = null;
private static Func<Type, Func<object, string>> GetProcessFunc()
{
if (_process == null)
{
var d = new Dictionary<Type, Func<object, string>>()
{
{ typeof(Response<AResponseCode>), r => ((Response<AResponseCode>)r).Code.ToString() },
{ typeof(Response<BResponseCode>), r => ((Response<BResponseCode>)r).Code.ToString() },
{ typeof(DataResponse<CResponseCode,string>), r => ((DataResponse<CResponseCode,string>)r).Code.ToString() },
};
_process = t =>
{
if (d.Contains(t))
{
return o => d[t];
}
return o => "UNKNOWN";
};
}
return _process;
}
This still has the same code, per se, but it is now better separated and can be replaced with a dependency injection approach more easily. :-)
Refactored thus, and I'd have been faster if IE hadn't freaked out and reloaded the page spontaneously. :(
I agree with others that this ideally should be gutted and mocked/encapsulated/extended to get where you want, but working within the method as a point of least impact and as an instructional:
bool isOkay = false;
string errCode; // you don't need to default this to anything because it won't be empty if you need to use it
if (response is Response<AResponseCode>) // "is" is a faster and more expressive test
{
var code = (response as Response<AResponseCode>).Code; // "as" is a faster conversion
isOkay = (code == AResponseCode.Ok); // Readability is awesome!
errCode = code.ToString(); // This still sucks
}
else if (response is Response<BResponseCode>) // elsif logically exclusive tests
{
var code = (response as Response<BResponseCode>).Code;
isOkay = code == BResponseCode.Ok;
errCode = code.ToString();
}
else if (response is DataResponse<CResponseCode,string>)
{
var code = (response as DataResponse<CResponseCode, string>).Code;
isOkay = (code == CResponseCode.Ok);
errCode = code.ToString();
}
// Test what you mean to express, i.e. if this isn't ok I need to log it
if (!isOkay)
{
// you don't need a temp variable here...
// and why aren't you just throwing an exception here? Is not being ok a regular unexceptional event, but one you still need to log? Really?
LogErrorCode("Operation resulted in error code:" + errCode);
}
// And try not to return bool literals, it's again unexpressive
return isOkay;

Categories

Resources