public void Send(SipMessage message) { using (TimedLock.Lock(transport)) { if (sendPending) { sendQueue.Enqueue(message); return; } try { var packet = message.ToArray(); sock.BeginSendAll(packet, 0, packet.Length, SocketFlags.None, onSend, null); sendPending = true; } catch (SocketException) { CloseAndRemove(); } catch (Exception e) { SysLog.LogException(e); } } }
/// <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); } }
public void HttpServer_MaxQuerySize() { HttpServer server; HttpRequest request; HttpResponse response; BlockArray blocks; byte[] buf; int cb; EnhancedSocket sock; IAsyncResult ar; server = new HttpServer(new IPEndPoint[] { new IPEndPoint(IPAddress.Any, ServerPort) }, new IHttpModule[] { new TestModule() }, 5, 100, 200); server.Start(); try { request = new HttpRequest("PUT", "/foo.htm", null); request.Content = new BlockArray(500); request["Response"] = "abcd"; request["Close"] = "yes"; request["Content-Length"] = request.Content.Size.ToString(); blocks = request.Serialize(4096); sock = new EnhancedSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); sock.Connect("localhost", ServerPort); Thread.Sleep(100); Assert.AreEqual(1, server.ConnectionCount); try { ar = sock.BeginSendAll(blocks, SocketFlags.None, null, null); sock.EndSendAll(ar); } catch { } response = new HttpResponse(); response.BeginParse(); buf = new byte[4096]; cb = sock.Receive(buf, buf.Length, SocketFlags.None); Assert.IsTrue(response.Parse(buf, cb)); response.EndParse(); Assert.AreEqual(HttpStatus.RequestEntityTooLarge, response.Status); sock.Close(); } finally { server.Stop(); } }
public void HttpServer_QueryResponse_Close() { HttpServer server; HttpRequest request; HttpResponse response; BlockArray blocks; byte[] buf; int cb; EnhancedSocket sock; IAsyncResult ar; server = new HttpServer(new IPEndPoint[] { new IPEndPoint(IPAddress.Any, ServerPort) }, new IHttpModule[] { new TestModule() }, 5, 100, int.MaxValue); server.Start(); try { request = new HttpRequest("GET", "/foo.htm", null); request.Content = new BlockArray(Encoding.ASCII.GetBytes("abcd")); request["Close"] = "yes"; blocks = request.Serialize(4096); sock = new EnhancedSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); sock.Connect("localhost", ServerPort); Thread.Sleep(100); Assert.AreEqual(1, server.ConnectionCount); ar = sock.BeginSendAll(blocks, SocketFlags.None, null, null); sock.EndSendAll(ar); response = new HttpResponse(); response.BeginParse(); buf = new byte[4096]; cb = sock.Receive(buf, buf.Length, SocketFlags.None); Assert.IsTrue(response.Parse(buf, cb)); response.EndParse(); CollectionAssert.AreEqual(Encoding.ASCII.GetBytes("abcd"), response.Content.ToByteArray()); buf = new byte[4096]; cb = sock.Receive(buf, buf.Length, SocketFlags.None); Assert.AreEqual(0, cb); sock.Close(); } finally { server.Stop(); } }
/// <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 } }