/// <summary> /// Removes the specified output stream from the list of connected /// streams. /// </summary> /// <param name="clientStream">The stream to remove.</param> internal void RemoveClientStream(OutputNetworkStreamWrapper clientStream) { lock (m_ClientStreams) { for (int i = 0; i < m_ClientStreams.Count; i++) { if (clientStream == m_ClientStreams[i]) { m_ClientStreams.RemoveAt(i); break; } } } }
/// <summary> /// Closes the stream attached to this listener context. /// </summary> public void Close(int lingerValue) { try { // Close the underlying stream if (m_clientOutputStream != null) { m_clientOutputStream.m_Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, lingerValue); m_clientOutputStream.Dispose(); m_clientOutputStream = null; } if (m_clientInputStream != null) { m_clientInputStream.Dispose(); m_clientInputStream = null; } } catch { } }
/// <summary> /// Closes the stream attached to this listener context. /// </summary> public void Close(int lingerValue) { try { if (this.m_clientOutputStream != null) { try { if (this.m_clientOutputStream.m_Socket != null) { this.m_clientOutputStream.m_Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, lingerValue); } } catch {} } if (this.m_ResponseToClient != null) { this.m_ResponseToClient.Close(); this.m_ResponseToClient = null; } // Close the underlying stream if (this.m_clientOutputStream != null) { this.m_clientOutputStream.Dispose(); this.m_clientOutputStream = null; } if (this.m_clientInputStream != null) { this.m_clientInputStream.Dispose(); this.m_clientInputStream = null; } } catch { } }
/// <summary> /// Waits for an incoming request and returns when one is received. /// </summary> /// <returns> /// An <see cref="System.Net.HttpListenerContext"/> object that /// represents a client request. /// </returns> /// <exception cref="SocketException">A socket call failed. Check the /// exception's ErrorCode property to determine the cause of the exception.</exception> /// <exception cref="InvalidOperationException">This object has not been started or is /// currently stopped or The HttpListener does not have any Uniform Resource Identifier /// (URI) prefixes to respond to.</exception> /// <exception cref="ObjectDisposedException">This object is closed.</exception> /// <example>This example shows how to call the /// <itemref>GetContext</itemref> method. /// <code> /// HttpListener myListener = new HttpListener("http", -1); /// myListener.Start(); /// while (true) /// { /// HttpListenerResponse response = null; /// try /// { /// Debug.Print("Waiting for requests"); /// HttpListenerContext context = myListener.GetContext(); /// </code> /// </example> public HttpListenerContext GetContext() { // Protects access for simulteneous call for GetContext and Close or Stop. lock (this) { if (m_Closed) { throw new ObjectDisposedException(); } if (!m_ServiceRunning) { throw new InvalidOperationException(); } } // Try to get context until service is running. while (m_ServiceRunning) { // Before waiting for event we need to look for pending connections. lock (m_InputStreamsQueue) { if (m_InputStreamsQueue.Count > 0) { OutputNetworkStreamWrapper outputStreamWrap = m_InputStreamsQueue.Dequeue() as OutputNetworkStreamWrapper; if (outputStreamWrap != null) { return(new HttpListenerContext(outputStreamWrap, this)); } } } // Waits for new connection to arrive on new or existing socket. m_RequestArrived.WaitOne(); } return(null); }
/// <summary> /// Internal constructor, used each time client connects. /// </summary> /// <param name="clientStream">The stream that is connected to the client. A stream is needed, to /// provide information about the connected client. /// See also the <see cref="System.Net.HttpListenerRequest"/> class. /// </param> /// <param name="httpListener">TBD</param> internal HttpListenerContext(OutputNetworkStreamWrapper clientStream, HttpListener httpListener) { // Saves the stream. m_clientOutputStream = clientStream; // Input stream does not own socket. m_clientInputStream = new InputNetworkStreamWrapper(clientStream.m_Stream, clientStream.m_Socket, false, null); // Constructs request and response classes. m_ClientRequest = new HttpListenerRequest(m_clientInputStream, httpListener.m_maxResponseHeadersLen); // Closing reponse to client causes removal from clientSocketsList. // Thus we need to pass clientSocketsList to client response. m_ResponseToClient = new HttpListenerResponse(m_clientOutputStream, httpListener); // There is incoming connection HTTP connection. Add new Socket to the list of connected sockets // The socket is removed from this array after correponding HttpListenerResponse is closed. httpListener.AddClientStream(m_clientOutputStream); // Set flag that HTTP request was not parsed yet. // It will be parsed on first access to m_ClientRequest or m_ResponseToClient m_IsHTTPRequestParsed = false; }
/// <summary> /// Waits for new data from the client. /// </summary> private void WaitingConnectionThreadFunc(OutputNetworkStreamWrapper outputStream) { try { // This is a blocking call waiting for more data. outputStream.m_Socket.Poll(DefaultKeepAliveMilliseconds * 1000, SelectMode.SelectRead); if (outputStream.m_Socket.Available > 0) { // Add this connected stream to the list. lock (this.m_InputStreamsQueue) { this.m_InputStreamsQueue.Enqueue(outputStream); } // Set event that client stream or exception is added to the queue. this.m_RequestArrived.Set(); } else // If no data available - means connection was close on other side or timed out. { outputStream.Dispose(); } } catch { } }
/// <summary> /// Waits for new data from the client. /// </summary> private void WaitingConnectionThreadFunc(OutputNetworkStreamWrapper outputStream) { try { // This is a blocking call waiting for more data. outputStream.m_Socket.Poll(DefaultKeepAliveMilliseconds * 1000, SelectMode.SelectRead); if (outputStream.m_Socket.Available > 0) { // Add this connected stream to the list. lock (m_InputStreamsQueue) { m_InputStreamsQueue.Enqueue(outputStream); } // Set event that client stream or exception is added to the queue. m_RequestArrived.Set(); } else // If no data available - means connection was close on other side or timed out. { outputStream.Dispose(); } } catch { } }
internal void AddToWaitingConnections(OutputNetworkStreamWrapper outputStream) { // Create a thread that blocks onsocket.Poll - basically waits for new data from client. HttpListernerAndStream listAndSock = new HttpListernerAndStream(this, outputStream); // Creates new thread to wait on data Thread thWaitData = new Thread(listAndSock.AddToWaitingConnections); thWaitData.Start(); }
internal HttpListernerAndStream(HttpListener listener, OutputNetworkStreamWrapper outputStream) { m_listener = listener; m_outStream = outputStream; }
/// <summary> /// Removes the specified output stream from the list of connected /// streams. /// </summary> /// <param name="clientStream">The stream to remove.</param> internal void RemoveClientStream(OutputNetworkStreamWrapper clientStream) { lock(m_ClientStreams) { for (int i = 0; i < m_ClientStreams.Count; i++) { if (clientStream == m_ClientStreams[i]) { m_ClientStreams.RemoveAt(i); break; } } } }
/// <summary> /// Adds a new output stream to the list of connected streams. /// </summary> /// <remarks>This is an internal function, not visible to the user. /// </remarks> /// <param name="clientStream">The stream to add.</param> internal void AddClientStream(OutputNetworkStreamWrapper clientStream) { lock(m_ClientStreams) { m_ClientStreams.Add(clientStream); } }
/// <summary> /// HttpListenerResponse is created by HttpListenerContext /// </summary> /// <param name="clientStream">Network stream to the client</param> /// <param name="httpListener">TBD</param> internal HttpListenerResponse(OutputNetworkStreamWrapper clientStream, HttpListener httpListener) { // Sets the delegate, so SendHeaders will be called on first write. clientStream.HeadersDelegate = new OutputNetworkStreamWrapper.SendHeadersDelegate(SendHeaders); // Saves network stream as member. m_clientStream = clientStream; // Saves list of client streams. m_clientStream is removed from clientStreamsList during Close(). m_Listener = httpListener; }
internal HttpListernerAndStream(HttpListener listener, OutputNetworkStreamWrapper outputStream) { this.m_listener = listener; this.m_outStream = outputStream; }
/// <summary> /// Adds a new output stream to the list of connected streams. /// </summary> /// <remarks>This is an internal function, not visible to the user. /// </remarks> /// <param name="clientStream">The stream to add.</param> internal void AddClientStream(OutputNetworkStreamWrapper clientStream) { lock (this.m_ClientStreams) { this.m_ClientStreams.Add(clientStream); } }