/// <summary> /// Initiates an asynchronous HTTP query to the connected server. /// </summary> /// <param name="query">The query request.</param> /// <param name="ttd">The expiration time (time-to-die) for the query (SYS).</param> /// <param name="callback">The delegate to call when the operation completes (or <c>null</c>).</param> /// <param name="state">Application state.</param> /// <returns>The async result used to track the operation.</returns> /// <remarks> /// <para> /// Pass ttd as the time (SYS) when the query should be considered to /// have timed-out. Connections will be perodically polled for timed out /// connections by the HttpStack class. Connections with active queries that /// have exceeded this time will be closed and the query operation will /// throw a TimeoutException. /// </para> /// <para> /// Pass ttd=DateTime.MaxValue to disable timeout checking. /// </para> /// </remarks> public IAsyncResult BeginQuery(HttpRequest query, DateTime ttd, AsyncCallback callback, object state) { HttpAsyncResult httpAR; BlockArray blocks; using (TimedLock.Lock(this)) { if (sock == null || !sock.IsOpen) { throw new InvalidOperationException(NotConnectedMsg); } if (queryPending) { throw new InvalidOperationException(QueryPendingMsg); } blocks = query.Serialize(HttpStack.BlockSize); if (perfBytesSent != null) { perfBytesSent.IncrementBy(blocks.Size); } httpAR = new HttpAsyncResult(this, callback, state); httpAR.Started(); sock.BeginSendAll(blocks, SocketFlags.None, onRequestSent, httpAR); this.queryPending = true; this.TTD = ttd; return(httpAR); } }
/// <summary> /// Handles completion of the response reception. /// </summary> /// <param name="ar">The async result.</param> private void OnResponseReceived(IAsyncResult ar) { var httpAR = (HttpAsyncResult)ar.AsyncState; int cbRecv; using (TimedLock.Lock(this)) { try { // Pump the received data into the response parser, // signalling completion when we have the entire message. cbRecv = sock.EndReceive(ar); if (perfBytesRecv != null) { perfBytesRecv.IncrementBy(cbRecv); } if (httpAR.Response.Parse(httpAR.Buffer, cbRecv)) { httpAR.Response.EndParse(); httpAR.Notify(); return; } if (cbRecv == 0) { sock.ShutdownAndClose(); return; } // Continue receiving response data httpAR.Buffer = new byte[HttpStack.BlockSize]; sock.BeginReceive(httpAR.Buffer, 0, HttpStack.BlockSize, SocketFlags.None, onResponseRecv, httpAR); } catch (Exception e) { httpAR.Notify(e); } } }
public void PerfCounterSet_Related() { PerfCounterSet counters = new PerfCounterSet(false, true, "Test_Related", "Test Help"); PerfCounter A, B, C; try { A = new PerfCounter("A", "A Help", PerformanceCounterType.NumberOfItems32); A.RelatedCounters = new string[] { "C" }; counters.Add(A); B = new PerfCounter("B", "B Help", PerformanceCounterType.NumberOfItems32); B.RelatedCounters = new string[] { "C" }; counters.Add(B); counters.Add(new PerfCounter("C", "C Help", PerformanceCounterType.NumberOfItems32)); counters.Install(); A = counters["A"]; B = counters["B"]; C = counters["C"]; Assert.AreEqual(0, C.RawValue); A.Increment(); Assert.AreEqual(1, C.RawValue); B.IncrementBy(5); Assert.AreEqual(6, C.RawValue); A.Decrement(); Assert.AreEqual(5, C.RawValue); } finally { counters.Uninstall(); } }
/// <summary> /// Handles socket receive completions. /// </summary> /// <param name="ar"></param> private void OnReceive(IAsyncResult ar) { HttpAsyncState httpState = (HttpAsyncState)ar.AsyncState; HttpRequest request = httpState.Request; EnhancedSocket sock = httpState.Socket; byte[] recvBuf = httpState.Buffer; int cbRecv; HttpResponse response; bool closeCon; bool close; bool firstRequest; try { cbRecv = sock.EndReceive(ar); } catch { using (TimedLock.Lock(syncLock)) connections.Remove(sock); sock.Close(); return; } if (cbRecv == 0) { using (TimedLock.Lock(syncLock)) connections.Remove(sock); sock.ShutdownAndClose(); return; } if (perfBytesRecv != null) { perfBytesRecv.IncrementBy(cbRecv); } httpState.RecvSize += cbRecv; if (httpState.RecvSize > cbQueryMax) { // The request is too large so respond with a HttpStatus.RequestEntityTooLarge // and close the socket. response = new HttpResponse(HttpStatus.RequestEntityTooLarge); sock.AsyncSendClose(response.Serialize(SendBlockSize)); using (TimedLock.Lock(syncLock)) connections.Remove(sock); return; } if (!request.Parse(recvBuf, cbRecv)) { recvBuf = new byte[RecvBlockSize]; httpState.Buffer = recvBuf; sock.BeginReceive(recvBuf, 0, recvBuf.Length, SocketFlags.None, onRecv, httpState); return; } // We have a complete request so process it. request.EndParse(); firstRequest = httpState.FirstRequest; httpState.FirstRequest = false; try { sock.AppState = this; // Indicate that we're processing a request closeCon = false; for (int i = 0; i < modules.Length; i++) { response = modules[i].OnRequest(this, request, firstRequest, out close); closeCon = closeCon || close; if (response != null) { BlockArray blocks; // Make sure the response version is reasonable if (request.HttpVersion < response.HttpVersion) { response.HttpVersion = request.HttpVersion; } // Truncate any content data for HEAD requests if (request.Method == "HEAD") { response.Content = null; if (response["Content-Length"] != null) { response["Content-Length"] = "0"; } } blocks = response.Serialize(SendBlockSize); if (perfBytesSent != null) { perfBytesSent.IncrementBy(blocks.Size); } if (closeCon) { sock.AsyncSendClose(blocks); using (TimedLock.Lock(syncLock)) connections.Remove(sock); } else { sock.BeginSendAll(blocks, SocketFlags.None, onSend, httpState); } break; } } } finally { sock.AppState = null; // Indicate that we're done processing the request } }