How to block ip Ranges using http modules? - c#

How to block Ip ranges using http modules with c# . I have a simple solution but its for single Ip and How can I read IPs from xml file in http modules so that if an IP is there in that file it will be blocked .Here is my code
public class MyHandler :IHttpModule
{
public MyHandler(){}
public bool IsReusable
{
get { return false; }
}
public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(Application_BeginRequest);
}
private void Application_BeginRequest(object source, EventArgs e)
{
HttpContext context = (source as HttpApplication).Context;
List<string> BlackListIp = new List<string>();
BlackListIp.Add("127.0.0.1");
if (BlackListIp.Contains(context.Request.UserHostAddress))
{
context.Response.Write("<h1 style='color:red;'>Your IP is Blocked</h1>");
}
}
public void Dispose()
{
}
}

Just add the xml file inside app_data folder and read it using XDocument.
You can event use Cache with FileDependency to improve performance.

Related

Windows service file listener only listens when debugging

First the code:
public partial class Watcher : ServiceBase
{
private const string PathToFolder = #"D:\print\";
public Watcher()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
}
protected override void OnStop()
{
}
private void fileWatcher_Changed(object sender, FileSystemEventArgs e)
{
if (e.Name != "test.txt")
{
return;
}
using (var r = new StreamReader(e.FullPath))
{
var json = r.ReadToEnd();
dynamic tempTest = JsonConvert.DeserializeObject(json);
const string filename = PathToFolder + "textParsed.txt";
if (File.Exists(filename))
{
File.Delete(filename);
}
using (var file = File.CreateText(filename))
{
file.WriteLine(tempTest.Name.ToString());
}
}
}
}
If there are changes to the text.txt file I'm suppose to parse the content of that text file and create another file. If I attach VS to the service and debug the service, the event gets fired, but when running normally, nothing happens.
The installer has LocalSystem privileges and that's pretty much all the changes I've made... Should be pretty straight forward, but somehow isn't.

How can I grab the response text of web page via IIS Module?

I'm working on an IIS module that, when a web page request is made, it looks over the data being passed back to the browser and replaces certain keywords with approved keywords. I realize there are multiple ways to do this, but for our purposes an IIS module will work best.
How can I read the stream of data being send back to the browser into a string so that I can convert keywords as needed?
Any help would be GREATLY appreciated!
Here's the code:
namespace MyNamespace
{
class MyModule : IHttpModule
{
private HttpContext _current = null;
#region IHttpModule Members
public void Dispose()
{
throw new Exception("Not implemented");
}
public void Init(HttpApplication context)
{
_current = context.Context;
context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);
}
#endregion
public void context_PreRequestHandlerExecute(Object source, EventArgs e)
{
HttpApplication app = (HttpApplication)source;
HttpRequest request = app.Context.Request;
}
}
There are two ways:
Using Response Filters
https://web.archive.org/web/20211029043851/https://www.4guysfromrolla.com/articles/120308-1.aspx
Handle the PreRequestHandlerExecute event of the application as it is run just before the IHttpHandler processes the page itself:
public class NoIndexHttpModule : IHttpModule
{
public void Dispose() { }
public void Init(HttpApplication context)
{
context.PreRequestHandlerExecute += AttachNoIndexMeta;
}
private void AttachNoIndexMeta(object sender, EventArgs e)
{
var page = HttpContext.Current.CurrentHandler as Page;
if (page != null && page.Header != null)
{
page.Header.Controls.Add(new LiteralControl("<meta name=\"robots\" value=\"noindex, follow\" />"));
}
}
}

http module: Request is not available

I'm creating an http module where I want to check if a request is coming from an authenticated user and redirect to the login page if it's not.
I registered the module in the web.config file and I have the following code that's throwing an exception:
public class IsAuthModule : IHttpModule
{
public void Dispose() { }
public void Init(HttpApplication TheApp)
{
var TheRequest = TheApp.Request;
}
}
It throwing an exception that says "Request is not available in this context"
What am I doing wrong?
In the Init stage you have no request in progress. You have to subscribe the event for beginning of a request:
public void Init(HttpApplication TheApp)
{
TheApp.BeginRequest += Application_BeginRequest;
// End Request handler
//application.EndRequest += Application_EndRequest;
}
private void Application_BeginRequest(Object source, EventArgs e)
{
// do something
}

HTTP module session not being set in extensionless page

I have a HTTP module that I have written that needs to access the session. I have done the following:
Module is registered in web.config
Module attaches my method call to the PostAcquireRequestState event
The module implement IRequiresSessionState
However, when my page doesn't have an extension (i.e. as when htp://www.mywebsite.com) the session is not available and my code fails. If the page does have an aspx extension then all is ok.
You need to have an item that is processed by ASP.NET in order for your module to be part of the request life-cycle. Serving a page like index.html won't accomplish that. An ASPX page will.
The code from the following thread does the trick (1):
public class Module : IHttpModule, IRequiresSessionState
{
public void Dispose()
{
}
void OnPostMapRequestHandler(object source, EventArgs e)
{
HttpApplication app = (HttpApplication)source;
if (app.Context.Handler is IReadOnlySessionState || app.Context.Handler is IRequiresSessionState)
return;
app.Context.Handler = new MyHttpHandler(app.Context.Handler);
}
void OnPostAcquireRequestState(object source, EventArgs e)
{
HttpApplication app = (HttpApplication)source;
MyHttpHandler resourceHttpHandler = HttpContext.Current.Handler as MyHttpHandler;
if (resourceHttpHandler != null)
HttpContext.Current.Handler = resourceHttpHandler.OriginalHandler;
}
public void Init(HttpApplication httpApp)
{
httpApp.PostAcquireRequestState += new EventHandler(OnPostAcquireRequestState);
httpApp.PostMapRequestHandler += new EventHandler(OnPostMapRequestHandler);
}
public class MyHttpHandler : IHttpHandler, IRequiresSessionState
{
internal readonly IHttpHandler OriginalHandler;
public void ProcessRequest(HttpContext context)
{
throw new InvalidOperationException("MyHttpHandler cannot process requests.");
}
public MyHttpHandler(IHttpHandler originalHandler)
{
OriginalHandler = originalHandler;
}
public bool IsReusable
{
get { return false; }
}
}
}
It turns out its an II7 issue, see here:
http://forum.umbraco.org/yaf_postst9997_ContextSession-always-null-on-top-umbraco-page.aspx

Any efficient/reliable way to expose one event?

Any efficient/reliable way to expose one event?
I have a class, MultipleDocumentCopier that copies multiple documents thru an instance of SingleDocumentCopier.
SingleDocumentCopier exposes an event CopyCompleted that is fired when a file is copied.
Suppose that, I am copying 10 files, instead of raising SingleDocumentCopier.CopyCompleted 10 times,
I would like to expose an event, MultipleDocumentCopier.MultipleCopyCompleted.
But is there a standard way/technique to combine multiple events and fire it once?
I would like to raise MultipleDocumentCopier.MultipleCopyCompleted only once
within 'MultipleDocumentCopier.singleDocumentCopier_CopyCompleted', instead of 10 times.
Here is the sample code
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace CombineEvents
{
public class Program
{
public static void Main(string[] args)
{
var copier = new MultipleDocumentCopier();
copier.MultipleCopyCompleted += MultipleDocumentCopyCompleted;
copier.CopyDocuments(new[] {"File1", "File2", "File3"});
}
private static void MultipleDocumentCopyCompleted(
object sender, FileNameEventArgs e)
{
Debug.Print("Following documents have been copied");
foreach (var fileName in e.FileNames)
{
Debug.Print("\t\t\"{0}\"", fileName);
}
}
}
internal class SingleDocumentCopier
{
public event EventHandler CopyCompleted;
protected virtual void OnCopyCompleted()
{
if (CopyCompleted != null) CopyCompleted(this, EventArgs.Empty);
}
public void Copy(string fileName)
{
Debug.Print("Copying = '{0}'", fileName);
OnCopyCompleted();
}
}
public class MultipleDocumentCopier
{
public event EventHandler<FileNameEventArgs> MultipleCopyCompleted;
protected virtual void OnCopyCompleted(FileNameEventArgs e)
{
EventHandler<FileNameEventArgs> completed = MultipleCopyCompleted;
if (completed != null) completed(this, e);
}
public void CopyDocuments(IEnumerable<string> fileNames)
{
var copier = new SingleDocumentCopier();
copier.CopyCompleted += singleDocumentCopier_CopyCompleted;
foreach (var fileName in fileNames)
{
copier.Copy(fileName);
}
}
public static void singleDocumentCopier_CopyCompleted(
object sender, EventArgs e)
{
// I want to raise "MultipleDocumentCopier.MultipleCopyCompleted" when
// all files, `fileNames` in "CopyDocuments" have been copied,
// not for every file being copied.
}
}
public class FileNameEventArgs : EventArgs
{
private readonly List<string> _FileNames;
public List<string> FileNames
{
get { return _FileNames; }
}
public FileNameEventArgs(IEnumerable<string> fileNames)
{
_FileNames = fileNames.ToList();
}
}
}
Why not call MultipleDocumentCopier.OnCopyCompleted from the end of CopyDocuments, and forget singleDocumentCopier_CopyCompleted entirely?
Or maybe this is pseudocode, and your real code is more complicated? Maybe you could keep a collection of outstanding file names inside MultipleDocumentCopier, and each time the singleDocumentCopier_CopyCompleted is raised, you remove one document from the collection. Once the collection becomes empty you call MultipleDocumentCopier.OnCopyCompleted.
Edit: Re 'is there a standard way?' -- not that I'm aware of in C#; F# has an interesting set of mechanisms for combining events like this, but I assume a change in programming language isn't an option.

Categories