public void LogDataAToB(Byte[] buffer, Int32 offset, Int32 length)
 {
     Byte[] header = Encoding.UTF8.GetBytes(
         String.Format(logPrefixFormatString, logNameAToB, logNameBToA, DateTime.Now.ToString("HH:mm:ss tt")));
     lock (dataLogger)
     {
         dataLogger.LogData(header, 0, header.Length);
         dataLogger.LogData(buffer, 0, length);
     }
 }
 public void LogDataAToB(Byte[] buffer, Int32 offset, Int32 length)
 {
     Byte[] header = Encoding.UTF8.GetBytes(
         String.Format("\n[  <<======  Socket {0}: {1} to {2} at {3}]\n", socketID, logNameAToB, logNameBToA, DateTime.Now.ToString("HH:mm:ss tt")));
     lock (dataLogger)
     {
         dataLogger.LogData(header, 0, header.Length);
         dataLogger.LogData(buffer, 0, length);
     }
 }
        public void Run()
        {
            byte[]        buffer          = new byte[4096];
            StringBuilder responseBuilder = new StringBuilder();

            responseBuilder.Append("220 localhost FTP Service ready.\r\n");

            Byte[] resposeBytes = Encoding.UTF8.GetBytes(responseBuilder.ToString());
            dataLogger.LogData(resposeBytes, 0, resposeBytes.Length);
            stream.Write(resposeBytes, 0, resposeBytes.Length);
            responseBuilder.Length = 0;

            while (true)
            {
                int bytesRead;
                int offset = 0;

                while (true)
                {
                    messageLogger.Log("Waiting for command...");
                    bytesRead = stream.Read(buffer, offset, buffer.Length);

                    if (bytesRead <= 0)
                    {
                        messageLogger.Log("Connection Closed");
                        return;
                    }

                    messageLogger.Log("Got {0} bytes", bytesRead);

                    int limit = offset + bytesRead;
                    while (offset < limit)
                    {
                        if (buffer[offset] == (byte)'\n')
                        {
                            goto FOUND_NEWLINE;
                        }
                        offset++;
                    }

                    if (offset >= buffer.Length)
                    {
                        throw new InvalidOperationException("buffer not big enough");
                    }
                }

FOUND_NEWLINE:

                offset++;
                if (bytesRead > offset)
                {
                    throw new NotImplementedException("I need to shift the rest of the bytes here");
                }

                int commandEnd = (offset > 1 && buffer[offset - 2] == '\r') ? offset - 2 : offset - 1;

                String command = Encoding.UTF8.GetString(buffer, 0, commandEnd);

                String commandUpperCase = null;
                String commandArgs      = null;

                Int32 spaceIndex = command.IndexOf(' ');

                if (spaceIndex < 0)
                {
                    commandUpperCase = command.ToUpper();
                }
                else
                {
                    commandUpperCase = command.Remove(spaceIndex).ToUpper();
                    if (spaceIndex + 1 <= command.Length)
                    {
                        commandArgs = command.Substring(spaceIndex + 1);
                    }
                }
                messageLogger.Log("Got Command '{0}'{1}", commandUpperCase, (commandArgs == null)?"":String.Format(" args='{0}'", commandArgs));

                handler.HandleCommand(responseBuilder, commandUpperCase, commandArgs);

                String responseString = "500 Command was not handled correctly.\r\n";
                if (responseBuilder.Length > 0)
                {
                    responseString         = responseBuilder.ToString();
                    responseBuilder.Length = 0;
                }
                else
                {
                    messageLogger.Log("Command '{0}' was not handled", command);
                }

                resposeBytes = Encoding.UTF8.GetBytes(responseString);
                stream.Write(resposeBytes, 0, resposeBytes.Length);
                dataLogger.LogData(resposeBytes, 0, resposeBytes.Length);
            }
        }
        public ParsedHttpRequest(NetworkStream stream, MessageLogger messageLogger, IDataLogger dataLogger)
        {
            int bytesRead;

            byte[] readBuffer = new byte[2048];

            parserState = RequestParserState.Method;

            StringBuilder stringBuilder = new StringBuilder(InitialCapacityForMethod);
            String        hValue        = String.Empty;
            String        hKey          = String.Empty;
            String        temp;
            Int32         bodyIndex = 0;

            do
            {
                switch (parserState)
                {
                case RequestParserState.Method:
                    messageLogger.Log("Reading Request");
                    break;

                case RequestParserState.Body:
                    messageLogger.Log("Waiting for {0} bytes for the body", body.Length - bodyIndex);
                    break;

                default:
                    messageLogger.Log("Waiting for more data (ParserState={0})...", parserState);
                    break;
                }
                bytesRead = stream.Read(readBuffer, 0, readBuffer.Length);
                if (bytesRead <= 0)
                {
                    break;
                }

                if (dataLogger != null)
                {
                    dataLogger.LogData(readBuffer, 0, bytesRead);
                }

                int offset = 0;
                do
                {
                    switch (parserState)
                    {
                    case RequestParserState.Method:
                        if (readBuffer[offset] != ' ')
                        {
                            stringBuilder.Append((char)readBuffer[offset]);
                        }
                        else
                        {
                            method        = stringBuilder.ToString();
                            stringBuilder = new StringBuilder(InitialCapacityForUrl);
                            parserState   = RequestParserState.Url;
                        }
                        offset++;
                        break;

                    case RequestParserState.Url:
                        if (readBuffer[offset] == '?')
                        {
                            url = Http.UrlDecode(stringBuilder.ToString());

                            hKey         = String.Empty;
                            urlArguments = new Dictionary <String, String>();
                            parserState  = RequestParserState.UrlParam;
                        }
                        else if (readBuffer[offset] != ' ')
                        {
                            stringBuilder.Append((char)readBuffer[offset]);
                        }
                        else
                        {
                            url         = Http.UrlDecode(stringBuilder.ToString());
                            parserState = RequestParserState.Version;
                        }
                        offset++;
                        break;

                    case RequestParserState.UrlParam:
                        if (readBuffer[offset] == '=')
                        {
                            offset++;
                            hValue      = String.Empty;
                            parserState = RequestParserState.UrlParamValue;
                        }
                        else if (readBuffer[offset] == ' ')
                        {
                            offset++;

                            url         = Http.UrlDecode(url);
                            parserState = RequestParserState.Version;
                        }
                        else
                        {
                            hKey += (char)readBuffer[offset++];
                        }
                        break;

                    case RequestParserState.UrlParamValue:
                        if (readBuffer[offset] == '&')
                        {
                            offset++;
                            hKey   = Http.UrlDecode(hKey);
                            hValue = Http.UrlDecode(hValue);
                            if (urlArguments.TryGetValue(hKey, out temp))
                            {
                                urlArguments[hKey] = String.Format("{0},{1}", temp, hValue);
                            }
                            else
                            {
                                urlArguments[hKey] = hValue;
                            }

                            hKey        = String.Empty;
                            parserState = RequestParserState.UrlParam;
                        }
                        else if (readBuffer[offset] == ' ')
                        {
                            offset++;
                            hKey   = Http.UrlDecode(hKey);
                            hValue = Http.UrlDecode(hValue);
                            if (urlArguments.TryGetValue(hKey, out temp))
                            {
                                urlArguments[hKey] = String.Format("{0},{1}", temp, hValue);
                            }
                            else
                            {
                                urlArguments[hKey] = hValue;
                            }

                            parserState = RequestParserState.Version;
                        }
                        else
                        {
                            hValue += (char)readBuffer[offset++];
                        }
                        break;

                    case RequestParserState.Version:
                        if (readBuffer[offset] == '\r')
                        {
                            offset++;
                        }

                        if (readBuffer[offset] != '\n')
                        {
                            httpVersion += (char)readBuffer[offset++];
                        }
                        else
                        {
                            offset++;
                            hKey        = String.Empty;
                            headers     = new Dictionary <String, String>();
                            parserState = RequestParserState.HeaderKey;
                        }
                        break;

                    case RequestParserState.HeaderKey:
                        if (readBuffer[offset] == '\r')
                        {
                            offset++;
                        }

                        if (readBuffer[offset] == '\n')
                        {
                            offset++;
                            if (headers.TryGetValue("Content-Length", out temp))
                            {
                                body        = new byte[Int32.Parse(temp)];
                                parserState = RequestParserState.Body;
                            }
                            else
                            {
                                parserState = RequestParserState.Done;
                            }
                        }
                        else if (readBuffer[offset] == ':')
                        {
                            offset++;
                        }
                        else if (readBuffer[offset] != ' ')
                        {
                            hKey += (char)readBuffer[offset++];
                        }
                        else
                        {
                            offset++;
                            hValue      = "";
                            parserState = RequestParserState.HeaderValue;
                        }
                        break;

                    case RequestParserState.HeaderValue:
                        if (readBuffer[offset] == '\r')
                        {
                            offset++;
                        }

                        if (readBuffer[offset] == '\n')
                        {
                            offset++;
                            headers.Add(hKey, hValue);
                            hKey        = String.Empty;
                            parserState = RequestParserState.HeaderKey;
                        }
                        else
                        {
                            hValue += (char)readBuffer[offset++];
                        }
                        break;

                    case RequestParserState.Body:
                        // Append to request BodyData
                        Array.Copy(readBuffer, offset, body, bodyIndex, bytesRead - offset);
                        bodyIndex += bytesRead - offset;
                        offset     = bytesRead;
                        if (bodyIndex >= ((body == null) ? 0 : body.Length))
                        {
                            parserState = RequestParserState.Done;
                        }
                        break;

                    default:
                        throw new InvalidOperationException(String.Format("Unrecognized Parser State '{0}' ({1})", parserState, (int)parserState));
                    }
                }while (offset < bytesRead);
            } while ((parserState != RequestParserState.Done) && stream.DataAvailable);
        }
        public void Run()
        {
            try
            {
                byte[] buffer = new byte[readBufferSize];

                while (keepRunning)
                {
                    if (messageLogger != null)
                    {
                        messageLogger.Log("Reading");
                    }

                    Int32 bytesRead = inputSocket.Receive(buffer, SocketFlags.None);

                    if (bytesRead <= 0)
                    {
                        if (messageLogger != null)
                        {
                            messageLogger.Log("Got End of Stream");
                        }
                        break;
                    }

                    if (messageLogger != null)
                    {
                        messageLogger.Log("Read {0} bytes", bytesRead);
                    }
                    if (dataLogger != null)
                    {
                        dataLogger.LogData(buffer, 0, bytesRead);
                    }

                    if (!keepRunning)
                    {
                        break;
                    }

                    if (messageLogger != null)
                    {
                        messageLogger.Log("Sending {0} bytes", bytesRead);
                    }
                    outputSocket.Send(buffer, 0, bytesRead, SocketFlags.None);
                }
            }
            catch (SocketException se)
            {
                messageLogger.Log("SocketException: {0}", se.Message);
            }
            catch (ObjectDisposedException ode)
            {
                messageLogger.Log("ObjectDisposedException: {0}", ode.Message);
            }
            finally
            {
                this.keepRunning = false;
                if (callback != null)
                {
                    callback.TunnelClosed(this);
                }
            }
        }
 public void LogDataAToB(Byte[] buffer, Int32 offset, Int32 length)
 {
     loggerAToB.LogData(buffer, offset, length);
 }