Skip to content

Instantly share code, notes, and snippets.

@FreekPaans
Created June 27, 2013 11:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FreekPaans/5875769 to your computer and use it in GitHub Desktop.
Save FreekPaans/5875769 to your computer and use it in GitHub Desktop.
record http requests
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Web;
namespace MvcApplication9.Modules {
public class TrackHttpRequest:IHttpModule {
public void Dispose() {
//throw new NotImplementedException();
}
static ZMQ.Context ZMQContext = new ZMQ.Context();
[ThreadStatic]
static ZMQ.Socket _socket;
static ZMQ.Socket Socket {
get {
if(_socket == null) {
AssertReceiverSenderRunning();
_socket = ZMQContext.Socket(ZMQ.SocketType.PUSH);
_socket.Connect(SocketAddr);
}
return _socket;
}
}
readonly static object _lock = new object();
static volatile bool _receiverSenderStarted =false;
private static void AssertReceiverSenderRunning() {
if(_receiverSenderStarted) {
return;
}
lock(_lock) {
if(_receiverSenderStarted) {
return;
}
var receiverSender = new Thread(()=> {
var socket = ZMQContext.Socket(ZMQ.SocketType.PULL);
socket.Bind(SocketAddr);
var senderSocket = ZMQContext.Socket(ZMQ.SocketType.REQ);
senderSocket.Bind(RemoteSocketAddr);
_receiverSenderStarted = true;
while(true) {
var received = socket.Recv();
senderSocket.Send(received);
senderSocket.Recv();
}
});
receiverSender.Start();
while(!_receiverSenderStarted){}
}
}
const string SocketAddr = "inproc://queuedhttprequests";
readonly static string RemoteSocketAddr = ConfigurationManager.AppSettings["ZMQ_HttpRequestsSocketAddress"];
public void Init(HttpApplication context) {
context.BeginRequest+=(s,o) => {
var request = GetHttpRequest(new HttpRequestWrapper(HttpContext.Current.Request));
//var httpRequest = GetHttpRequest(request);
Socket.Send(PrependHeader(request));
};
}
private byte[] PrependHeader(byte[] httpRequest) {
using(var ms = new MemoryStream()) {
var writer = new StreamWriter(ms);
writer.Write("{0}|{1}\r\n", DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss.fff"), Thread.CurrentThread.ManagedThreadId);
writer.Flush();
using(var input = new MemoryStream(httpRequest)) {
input.CopyTo(ms);
}
return ms.ToArray();
}
}
static byte[] GetHttpRequest(HttpRequestBase request) {
using(var stream = new MemoryStream()) {
var writer = new StreamWriter(stream);
writer.Write(request.HttpMethod + " " + request.Path);
var queryStringText = GetRawQueryString(request);
if(!string.IsNullOrEmpty(queryStringText)) {
writer.Write("?"+queryStringText);
}
writer.Write(" "+request.ServerVariables["SERVER_PROTOCOL"]+"\r\n");
writer.Write(request.ServerVariables["ALL_RAW"]);
writer.Write("\r\n");
writer.Flush();
var pos = request.InputStream.Position;
try {
request.InputStream.Position = 0;
request.InputStream.CopyTo(stream);
return stream.ToArray();
}
finally {
request.InputStream.Position = pos;
}
}
}
readonly static FieldInfo _httpRequestField = typeof(HttpRequestWrapper).GetField("_httpRequest",BindingFlags.NonPublic|BindingFlags.Instance);
readonly static PropertyInfo _httpRequestQueryStringProperty = typeof(HttpRequest).GetProperty("QueryStringText",BindingFlags.NonPublic|BindingFlags.Instance);
private static string GetRawQueryString(HttpRequestBase request) {
var requestObject = (HttpRequest)_httpRequestField.GetValue(request);
var queryStringText= (string)_httpRequestQueryStringProperty.GetValue(requestObject,null);
return queryStringText;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment