public void DataRecvHandler(ref SelectControl control, Socket sock, Buf safeBuffer) { Socket otherSocket = (sock == serverSocket) ? clientSocket : serverSocket; int bytesReceived = sock.ReceiveNoThrow(safeBuffer.array, 0, safeBuffer.array.Length, SocketFlags.None); if (bytesReceived <= 0) { if (otherSocket != null) { otherSocket.ShutdownSafe(); } control.RemoveReceiveSocket(sock); return; } if (otherSocket != null) { try { otherSocket.Send(safeBuffer.array, bytesReceived, SocketFlags.None); return; } catch (SocketException) { sock.ShutdownSafe(); control.DisposeAndRemoveReceiveSocket(sock); } } }
public void TcpRecvHandler(ref SelectControl control, Socket sock, Buf safeBuffer) { int bytesReceived = sock.ReceiveNoThrow(safeBuffer.array, 0, safeBuffer.array.Length, SocketFlags.None); if (bytesReceived <= 0) { if (serverSocket != null) { serverSocket.ShutdownSafe(); } control.RemoveReceiveSocket(sock); return; } if (serverSocket != null) { try { serverSocket.Send(safeBuffer.array, bytesReceived, SocketFlags.None); return; } catch (SocketException) { sock.ShutdownSafe(); control.DisposeAndRemoveReceiveSocket(sock); return; } } httpHeaderBuilders.Append(Encoding.ASCII.GetString(safeBuffer.array, 0, bytesReceived)); // // Check if you have received all the headers // Int32 totalLength = httpHeaderBuilders.Length; if (totalLength > 3) { if ( httpHeaderBuilders[totalLength - 1] == '\n' && ( (httpHeaderBuilders[totalLength - 2] == '\n') || (httpHeaderBuilders[totalLength - 2] == '\r' && httpHeaderBuilders[totalLength - 3] == '\n' && httpHeaderBuilders[totalLength - 4] == '\r')) ) { String headers = httpHeaderBuilders.ToString(); httpHeaderBuilders = null; HandleHeaders(ref control, sock, headers); } } }
public void TcpSocketRecvCallback(ref SelectControl control, Socket socket, Buf safeBuffer) { int bytesRead; try { bytesRead = socket.Receive(safeBuffer.array); } catch (SocketException) { bytesRead = -1; } if (bytesRead <= 0) { control.RemoveReceiveSocket(socket); return; } HandleData(socket, safeBuffer.array, 0, (uint)bytesRead); }
public void HeaderRecvHandler(ref SelectControl selectControl, Socket clientSocket, Buf ignore) { builder.EnsureTotalCapacity(builder.contentLength + 128); UInt32 dataOffset; try { dataOffset = Http.ReadHttpHeaders(clientSocket, builder); } catch (Exception e) { if (WebServer.Logger != null) { WebServer.Logger.WriteLine("[{0}] Closed: {1}", clientLogString, e.Message); } selectControl.RemoveReceiveSocket(clientSocket); return; } // // Parse the request // try { UInt32 parseOffset = 0; Slice httpMethod; httpMethod.offset = parseOffset; httpMethod.limit = builder.bytes.IndexOfUInt32(parseOffset, dataOffset, (Byte)' '); if (httpMethod.limit == UInt32.MaxValue) { throw new FormatException("Invalid request: no space after HTTP method"); } parseOffset = (uint)httpMethod.limit + 1; Slice httpResource; httpResource.offset = parseOffset; httpResource.limit = builder.bytes.IndexOfUInt32(parseOffset, dataOffset, (Byte)' '); if (httpResource.limit == UInt32.MaxValue) { throw new FormatException("Invalid request: no space after HTTP resource"); } parseOffset = (uint)httpResource.limit + 1; this.method = httpMethod.Decode(builder.bytes); this.resource = httpResource.Decode(builder.bytes); headerContentLength = Http.GetContentLength(builder.bytes, 0, dataOffset); if (headerContentLength != UInt32.MaxValue) { throw new NotImplementedException(String.Format("Content-Length {0} is not implemented", headerContentLength)); } } catch (Exception e) { if (WebServer.Logger != null) { WebServer.Logger.WriteLine("[{0}] InvalidRequest: {1}", clientLogString, e.Message); } clientSocket.Shutdown(SocketShutdown.Both); clientSocket.Close(); selectControl.RemoveReceiveSocket(clientSocket); return; } if (WebServer.Logger != null) { WebServer.Logger.WriteLine("[{0}] {1} {2}", clientLogString, method, resource); } if (!method.Equals("GET")) { if (WebServer.Logger != null) { WebServer.Logger.WriteLine("[{0}] Unsupported HTTP Method: {1}", clientLogString, method); } clientSocket.Shutdown(SocketShutdown.Both); clientSocket.Close(); selectControl.RemoveReceiveSocket(clientSocket); return; } String filename = WebServer.HttpResourceToFile(resource); if (!File.Exists(filename)) { clientSocket.Send(NotFound404); clientSocket.Shutdown(SocketShutdown.Both); clientSocket.Close(); selectControl.RemoveReceiveSocket(clientSocket); return; } builder.Clear(); FileInfo fileInfo = new FileInfo(filename); Int64 fileLength = fileInfo.Length; builder.AppendAscii("HTTP/1.1 200 OK\r\nContent-Length: "); builder.AppendAscii(fileLength.ToString()); builder.AppendAscii("\r\n\r\n"); using (FileStream fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { UInt32 bufferLeft = (uint)builder.bytes.Length - builder.contentLength; if (fileLength <= bufferLeft) { fileStream.ReadFullSize(builder.bytes, (int)builder.contentLength, (int)fileLength); clientSocket.Send(builder.bytes, 0, (int)(builder.contentLength + fileLength), 0); } else { Int64 fileLeft = fileLength; fileStream.ReadFullSize(builder.bytes, (int)builder.contentLength, (int)bufferLeft); clientSocket.Send(builder.bytes); fileLeft -= bufferLeft; while (fileLeft > builder.bytes.Length) { fileStream.ReadFullSize(builder.bytes, 0, builder.bytes.Length); clientSocket.Send(builder.bytes); fileLeft -= builder.bytes.Length; } if (fileLeft > 0) { fileStream.ReadFullSize(builder.bytes, 0, (int)fileLeft); clientSocket.Send(builder.bytes, 0, (int)fileLeft, 0); } } clientSocket.Close(); selectControl.RemoveReceiveSocket(clientSocket); } }
void GotHeaders(ref SelectControl selectControl, Socket clientSocket, Byte[] headers, UInt32 totalLength) { String serverIPOrHost = null; UInt16 serverPort = 0; try { serverIPOrHost = GetServerFromHeaders(out serverPort, out isConnect, headers, ref headersLength, ref totalLength, clientLogString); } catch (Exception e) { if (AppLayerProxy.ErrorLogger != null) { AppLayerProxy.ErrorLogger.WriteLine("{0} Failed to get server from HTTP Headers: {1}", clientLogString, e); } } if (serverIPOrHost == null) { selectControl.ShutdownDisposeAndRemoveReceiveSocket(clientSocket); return; } this.serverLogString = serverIPOrHost + ":" + serverPort.ToString(); Boolean needToConnect; if (AppLayerProxy.ForwardProxy == null) { // TODO: Fix so this does not block during DNS resolution IPAddress serverIP; try { serverIP = EndPoints.ParseIPOrResolveHost(serverIPOrHost, DnsPriority.IPv4ThenIPv6); } catch (SocketException) { if (AppLayerProxy.ErrorLogger != null) { AppLayerProxy.ErrorLogger.WriteLine("{0} Failed to resolve server hostname '{1}'", clientLogString, serverIPOrHost); } selectControl.ShutdownDisposeAndRemoveReceiveSocket(clientSocket); return; } IPEndPoint serverEndPoint = new IPEndPoint(serverIP, serverPort); serverSocket = new Socket(serverEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); serverSocket.Blocking = false; needToConnect = NonBlockingSocket.ConnectNonBlocking(serverSocket, serverEndPoint); } else { this.serverEndPointForProxy = new StringEndPoint(serverIPOrHost, serverPort); Console.WriteLine("[DEBUG] Connecting to proxy '{0}'", AppLayerProxy.ForwardProxy.host.CreateTargetString()); serverSocket = new Socket(AppLayerProxy.ForwardProxy.host.GetAddressFamilyForTcp(), SocketType.Stream, ProtocolType.Tcp); serverSocket.Blocking = false; throw new NotImplementedException(); //needToConnect = NonBlockingSocket.ConnectNonBlocking(serverSocket, AppLayerProxy.ForwardProxy.endPoint); } //Console.WriteLine("[DEBUG] {0} > {1} Connecting...", clientLogString, serverLogString); if (needToConnect) { selectControl.RemoveReceiveSocket(clientSocket); // Remove the clientSocket from the read list // until the connection gets established or lost selectControl.AddConnectSocket(serverSocket, ServerSocketConnected); // Save Data if (isConnect) { if (totalLength == headersLength) { clientBuffer = null; // Clean up the client buffer (if there is one) } } else { if (clientBuffer == null) { clientBuffer = new ByteBuilder(totalLength); Array.Copy(headers, clientBuffer.bytes, totalLength); clientBuffer.contentLength = totalLength; } else { // Data already in the client buffer } } } else { if (AppLayerProxy.Logger != null) { AppLayerProxy.Logger.WriteLine("{0} > {1} Connection Completed Synchronously (CornerCase)", clientLogString, serverLogString); } if (!clientSocket.Connected) { selectControl.DisposeAndRemoveReceiveSocket(clientSocket); if (serverSocket.Connected) { if (AppLayerProxy.Logger != null) { AppLayerProxy.Logger.WriteLine("{0} > {1} Server Connected but Client Disconnected...Closing Server", clientLogString, serverLogString); } try { serverSocket.Shutdown(SocketShutdown.Both); } catch (Exception) { } } else { if (AppLayerProxy.Logger != null) { AppLayerProxy.Logger.WriteLine("{0} > {1} Client disconnected before server could connect", clientLogString, serverLogString); } } serverSocket.Close(); } else if (!serverSocket.Connected) { if (AppLayerProxy.Logger != null) { AppLayerProxy.Logger.WriteLine("{0} > {1} Failed to connect to server..Closing Client", clientLogString, serverLogString); } selectControl.ShutdownDisposeAndRemoveReceiveSocket(clientSocket); serverSocket.Close(); } else { if (AppLayerProxy.Logger != null) { AppLayerProxy.Logger.WriteLine("{0} > {1} Connected to Server", clientLogString, serverLogString); } if (isConnect) { uint extraChars = totalLength - headersLength; FinishConnection(headers, headersLength, extraChars); } else { FinishConnection(headers, 0, totalLength); } TcpBridge bridge = new TcpBridge(clientLogString, clientSocket, serverLogString, serverSocket); selectControl.UpdateHandler(clientSocket, bridge.ReceiveHandler); selectControl.AddReceiveSocket(serverSocket, bridge.ReceiveHandler); } } }