How to Capture HTTP Request of Static Files Deployed on IIS

When you release a JavaScript library, such as jQuery, online, you may need to collect some status information for analytics. If you deploy your website on IIS, you can use HTTP Module to capture HTTP requests of HTML, JS and CSS files. My goal is to make a statistic of how many times dynamsoft.webtwain.min.js is called.

Prerequisites

Capturing HTTP Request Event with HTTP Module

Create an empty wet site project in Visual Studio.

csharp website

Add dynamsoft.webtwain.min.js file to the project.

add js file

Create a Class file in App_Code folder which is automatically generated.

http module

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;

/// <summary>
/// Summary description for HttpModuleManager
/// </summary>
public class HttpModuleManager : IHttpModule
{
    private FileHelper mFileHelper;

    public void Dispose()
    {
        
    }

    public void Init(HttpApplication context)
    {
        string dir = Path.Combine(context.Context.Server.MapPath("."), "data");
        string logFile = null;
        if (!Directory.Exists(dir))
        {
            Directory.CreateDirectory(dir);
        }

        // Write record to text file.
        logFile = Path.Combine(dir, "log.txt");
        mFileHelper = new FileHelper(logFile, false);

        context.LogRequest += new EventHandler(OnLogRequest);
    }

    public void OnLogRequest(Object source, EventArgs e)
    {
        HttpApplication application = (HttpApplication)source;
        HttpContext context = application.Context;
        string url = context.Request.Url.AbsoluteUri.ToLower();

        if (url.Contains("dynamsoft.webtwain.min.js"))
        {
            // Write record to text file.
            mFileHelper.WriteLog(context.Request.UserHostAddress);
        }
    }
}

Add the configuration to the web.config file.

<system.webServer>
    <modules>
      <add name="HttpModuleManager" type="HttpModuleManager" />
    </modules>
  </system.webServer>

Right-click the project root to publish the website. To build .cs files to a DLL file, check the following option.

precompile

The publish method is File System.

publish website

Deploy the project to IIS with 80 port.

Create an index.htm file for scanning documents. This file is deployed on another web server:

<!DOCTYPE html>
<html>
<head>
    <title>Hello World</title>
    <script type="text/javascript" src="http://192.168.8.84/dynamsoft.webtwain.min.js"> </script>
</head>

<body>
    <input type="button" value="Scan" onclick="AcquireImage();" />
    <div id="dwtcontrolContainer"></div>

    <script type="text/javascript">
    function AcquireImage() {
        var DWObject = Dynamsoft.WebTwainEnv.GetWebTwain('dwtcontrolContainer');
        DWObject.IfDisableSourceAfterAcquire = true;
        var bSelected = DWObject.SelectSource();

        if(bSelected) {
            var OnAcquireImageSuccess, OnAcquireImageFailure;
            OnAcquireImageSuccess = OnAcquireImageFailure = function () {
            DWObject.CloseSource();
        };

        DWObject.OpenSource();
        DWObject.AcquireImage(OnAcquireImageSuccess, OnAcquireImageFailure);
        }
    }
    </script>
</body>
</html>

When someone visits the page in a web browser, there is a record generated on IIS.

Note: because of the cache mechanism, the JS file will not be reloaded unless you press Ctrl+F5 (Windows) or Command+Shift+R (macOS) in Chrome.

Using SQLite to Record Information of HTTP Request

A database is a better way of storing data than a text file. Let’s try SQLite.

Create a table:

SQLiteConnection.CreateFile(strPath);
            string connectionString = "Data Source=" + strPath + ";Version=3;";
            m_dbConnection = new SQLiteConnection(connectionString);
            try
            {
                m_dbConnection.Open();
                string sql = "create table record (content text)";
                SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection);
                int number = command.ExecuteNonQuery();
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }

Insert a record:

string sql = "insert into record (content) values ('" + content + "')";
            SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection);
            int number = command.ExecuteNonQuery();

When running the website, I got the System.BadImageFormatException error.
BadImageFormatException

The workaround is to use the 64-bit version of IIS Express.

IIS 64 bit

To view the recorded data, use DB browser.

sqlite HTTP request

Source Code

https://github.com/yushulx/csharp-http-module