سؤال

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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top