I'm handling local requests by using FiddlerCore. All sessions are queued in Queue<Session>
and processed by a BackgroundWorker
. After the process is done, I would like to send a response, indicating the success or failure of the processing, by using the processed session. The problem is that I'm getting the Too late, we're already talking to the server error.
This is the FiddlerCore function:
private static void FiddlerApplication_BeforeRequest(Session session)
{
if (session.hostname.ToLower() == "localhost")
{
LogHelper.WriteFormat("Local request {0} enqueued", session.id);
sessionsQueue.Enqueue(session);
if (!sessionWorker.IsBusy)
sessionWorker.RunWorkerAsync();
}
}
This is the thread function:
private static void sessionWorker_DoWork(object sender, DoWorkEventArgs e)
{
while (sessionsQueue.Count > 0)
{
if (sessionWorker.CancellationPending)
{
e.Cancel = true;
sessionsQueue.Clear();
LogHelper.Write("Shutting down, all requests canceled");
break;
}
currentSession = sessionsQueue.Dequeue();
LogHelper.WriteFormat("Processing request ID {0}", currentSession.id);
ProcessSession();
}
}
This is the code at the end of the ProcessSession
function:
{
...
currentSession.bBufferResponse = true;
currentSession.utilCreateResponseAndBypassServer();
currentSession.oResponse.headers.HTTPResponseStatus = "200 OK";
currentSession.oResponse["Content-Type"] = "text/html; charset=UTF-8";
currentSession.oResponse["Cache-Control"] = "private, max-age=0";
currentSession.utilSetResponseBody(responseBody);
}
I've tried to tamper with the session's timers and state, but without success.
The exception in question occurs when you call utilCreateResponseAndBypassServer
after having already sent the request to the server. If you want to use the utilCreateResponseAndBypassServer
method, you must do so inside the BeforeRequest
handler, not at some future time. Similarly, setting bBufferResponse
after having already connected to the server is pointless.
Based on your later remarks, you have a misunderstanding about how threading works with FiddlerCore. FiddlerCore processes Sessions on background threadpool threads.
When BeforeRequest
fires, your code has a chance to run. If you call utilCreateResponseAndBypassServer
inside that method, then the response you generate is immediately returned to the client.
If you don't call utilCreateResponseAndBypassServer
inside BeforeRequest
, the request is immediately sent to the server by FiddlerCore, and the response is returned to the client when it's available.
To achieve what you're describing, you should NOT try to do your own threading-- instead do all of your work on the thread that goes into the BeforeRequest method and don't leave that method without generating the desired response. You don't need to worry about hanging the UI or anything like that, because BeforeRequest
is running on a background thread. The only thing you must do is the Invoke
methods if any of your code needs to interact with any UI owned by the UI thread.