Esempio n. 1
0
        protected bool HandleMessage(Message message)
        {
            lock (Sync) switch (message.Opcode)
                {
                case 1: OnString?.Invoke(Encoding.UTF8.GetString(message.Payload)); return(true);

                case 2: OnBinary?.Invoke(message.Payload); return(true);

                case 8:
                    if (message.Length < 2)
                    {
                        FinishClose(); return(true);
                    }
                    ushort code   = (ushort)(message.Payload[0] * 256 + message.Payload[1]);
                    string reason = Encoding.UTF8.GetString(PrimitiveBuffer.Slice(message.Payload, 2, message.Length));
                    if (RecvClose && message.Length > 2)
                    {
                        return(false);
                    }
                    if (message.Length > 2)
                    {
                        return(FinishClose(code, reason));
                    }
                    return(FinishClose(code));

                case 9: OnPing?.Invoke(message.Payload); return(true);

                case 10: OnPong?.Invoke(message.Payload); return(true);

                default: return(false);
                }
        }
Esempio n. 2
0
 public static byte[] FlipMask(byte[] payload, byte[] mask)
 {
     byte[] copied = PrimitiveBuffer.Slice(payload, 0, (ulong)payload.LongLength);
     for (long i = 0; i < copied.LongLength; i++)
     {
         copied[i] ^= mask[i & 3];
     }
     return(copied);
 }
Esempio n. 3
0
 public virtual bool SendPing(byte[] payload, ushort start, ulong end) => SendPing(PrimitiveBuffer.Slice(payload, start, end));
Esempio n. 4
0
 public virtual bool SendPing(byte[] payload, ushort start) => SendPing(PrimitiveBuffer.Slice(payload, start, (ulong)payload.LongLength));
Esempio n. 5
0
 public virtual bool Write(byte[] source, ulong start, ulong end)
 => Write(PrimitiveBuffer.Slice(source, start, end));
Esempio n. 6
0
 public virtual bool Write(byte[] source, ulong start)
 => Write(PrimitiveBuffer.Slice(source, start, (ulong)source.LongLength));
Esempio n. 7
0
        protected sealed override bool HandleWritable(byte[] source)
        {
            if (Malformed)
            {
                return(false);
            }
            char c = '\0'; ulong length, i = 0, sourceLength = (ulong)source.LongLength;

            for (; i < sourceLength;)
            {
                switch (State)
                {
                case ParseState.Dormant: return(false);

                case ParseState.Binary:
                    ContentLength = EncodedContentLength += sourceLength;
                    if (!WriteChunk(source))
                    {
                        return(false);
                    }
                    if (Type.Value.Length.HasValue && Type.Value.Length == ContentLength)
                    {
                        return(Finish());
                    }
                    return(true);

                case ParseState.Chunked_Length:
                    EncodedContentLength++;
                    c = (char)source[i++];
                    if (c == CR)
                    {
                        State = ParseState.Chunked_LengthLf;
                    }
                    else
                    {
                        ChunkLengthString = ChunkLengthString == null?c.ToString() : ChunkLengthString + c;
                    }
                    break;

                case ParseState.Chunked_LengthLf:
                    EncodedContentLength++;
                    c = (char)source[i++];
                    if (c != LF)
                    {
                        return(!(Malformed = true));
                    }
                    ChunkIndex = 0;
                    if (!ulong.TryParse(ChunkLengthString, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out length))
                    {
                        return(!(Malformed = true));
                    }
                    ChunkLengthString = null;
                    State             = (ChunkLength = length) == 0 ? ParseState.Chunked_Trailer : ParseState.Chunked_ChunkData;
                    break;

                case ParseState.Chunked_ChunkData:
                    length = Math.Min(ChunkLength - ChunkIndex, sourceLength - i);
                    WriteChunk(PrimitiveBuffer.Slice(source, i, i += length));
                    ChunkIndex += length; ContentLength += length; EncodedContentLength += length;
                    if (ChunkIndex >= ChunkLength)
                    {
                        State = ParseState.Chunked_ChunkCr;
                    }
                    break;

                case ParseState.Chunked_ChunkCr:
                    EncodedContentLength++;
                    c = (char)source[i++];
                    if (c != CR)
                    {
                        return(!(Malformed = true));
                    }
                    State = ParseState.Chunked_ChunkLf;
                    break;

                case ParseState.Chunked_ChunkLf:
                    EncodedContentLength++;
                    c = (char)source[i++];
                    if (c != LF)
                    {
                        return(!(Malformed = true));
                    }
                    ChunkIndex = 0;
                    State      = ParseState.Chunked_Length;
                    break;

                case ParseState.Chunked_Trailer:
                    while ((c = (char)source[i++]) != CR)
                    {
                        EncodedContentLength++;
                    }
                    State = ParseState.Chunked_Lf;
                    break;

                case ParseState.Chunked_Lf:
                    EncodedContentLength++;
                    c = (char)source[i++];
                    if (c != LF)
                    {
                        return(!(Malformed = true));
                    }
                    ExcessStore.Write(source, i);
                    return(Finish());
                }
            }
            return(true);
        }
Esempio n. 8
0
        protected override bool HandleWritable(byte[] source)
        {
            if (Malformed)
            {
                return(false);
            }
            ulong i = 0, sourceLength = (ulong)source.LongLength;

            for (char c; i < sourceLength; i++)
            {
                c = (char)source[i];
                switch (State)
                {
                case ParseState.Version:
                    if (c != WS)
                    {
                        IncomingVersion += c;
                    }
                    else
                    {
                        if (!Version.TryParse(IncomingVersion, out Version result))
                        {
                            return(!(Malformed = true));
                        }
                        IncomingVersionValue = result;
                        State = ParseState.StatusCode;
                    }
                    break;

                case ParseState.StatusCode:
                    if (c == WS)
                    {
                        State = ParseState.StatusDescription;
                    }
                    else if (char.IsDigit(c))
                    {
                        IncomingStatusCode += c;
                    }
                    else
                    {
                        return(!(Malformed = true));
                    }
                    break;

                case ParseState.StatusDescription:
                    if (c != CR)
                    {
                        IncomingStatusDescription += c;
                    }
                    else
                    {
                        State = ParseState.FirstLf;
                    }
                    break;

                case ParseState.FirstLf:
                    if (c != LF)
                    {
                        return(!(Malformed = true));
                    }
                    State = ParseState.HeaderName;
                    break;

                case ParseState.HeaderName:
                    if (c == CR)
                    {
                        State = ParseState.Lf;
                    }
                    else if (c != COLON)
                    {
                        IncomingHeaderName += c;
                    }
                    else
                    {
                        State = ParseState.HeaderValue;
                    }
                    break;

                case ParseState.HeaderValue:
                    if (c != CR)
                    {
                        IncomingHeaderValue += c;
                    }
                    else
                    {
                        IncomingHeaders.Add(IncomingHeaderName, IncomingHeaderValue.TrimStart());
                        IncomingHeaderName  = "";
                        IncomingHeaderValue = "";
                        State = ParseState.HeaderLf;
                    }
                    break;

                case ParseState.HeaderLf:
                    if (c != LF)
                    {
                        return(!(Malformed = true));
                    }
                    else
                    {
                        State = ParseState.HeaderName;
                    }
                    break;

                case ParseState.Lf:
                    if (c != LF)
                    {
                        return(!(Malformed = true));
                    }
                    HandleReadable(PrimitiveBuffer.Slice(source, i + 1, sourceLength));
                    Pickup(new ResponseHead(IncomingVersionValue, ushort.Parse(IncomingStatusCode), IncomingStatusDescription, IncomingHeaders));
                    return(Reset());
                }
            }
            return(true);
        }