Example #1
0
        private async void OnMessageAdcget(ADCGETMessage adcgetMessage)
        {
            var reqItem = new ContentItem();

            if (adcgetMessage.Type == ADCGETType.Tthl)
            {
                SendMessageAsync(new ErrorMessage {
                    Error = "File Not Available"
                }.Raw);
                return;
            }

            if (adcgetMessage.Type == ADCGETType.File)
            {
                if (adcgetMessage.Request.StartsWith("TTH/"))
                {
                    reqItem.Magnet = new Magnet {
                        TTH = adcgetMessage.Request.Remove(0, 4)
                    };
                }
                else
                {
                    reqItem.Magnet = new Magnet {
                        FileName = adcgetMessage.Request
                    };
                }
            }

            _requests.Update(1);
            _isResponding = true;

            if (!SlotUsed)
            {
                var ea = new CancelEventArgs();
                OnSlotRequest(ea);

                if (ea.Cancel)
                {
                    Logger.Info("Can't start upload to {0}, no slots available", Source);
                    SendMessageAsync(new MaxedOutMessage().Raw);
                    return;
                }

                SlotUsed = true;
            }

            if (UploadItem == null || UploadItem.Content.Magnet.TTH != reqItem.Magnet.TTH)
            {
                var ea = new UploadItemEventArgs {
                    Transfer = this, Content = reqItem
                };
                OnUploadItemNeeded(ea);

                if (UploadItem != null)
                {
                    var uea = new UploadItemEventArgs();
                    OnUploadItemDispose(uea);
                    if (!uea.Handled)
                    {
                        UploadItem.Dispose();
                    }
                }

                UploadItem = ea.UploadItem;
                if (ea.UploadItem == null)
                {
                    SendMessageAsync(new ErrorMessage {
                        Error = "File Not Available"
                    }.Raw);
                    return;
                }
            }

            if (adcgetMessage.Start >= UploadItem.Content.Magnet.Size)
            {
                SendMessageAsync(new ErrorMessage {
                    Error = "File Not Available"
                }.Raw);
                return;
            }

            if (adcgetMessage.Start + adcgetMessage.Length > UploadItem.Content.Magnet.Size)
            {
                Logger.Warn("Trim ADCGET length to file actual length {0}/{1}",
                            adcgetMessage.Start + adcgetMessage.Length, UploadItem.Content.Magnet.Size);
                adcgetMessage.Length = UploadItem.Content.Magnet.Size - adcgetMessage.Start;
            }


            var uploadItem = UploadItem;

            if (_disposed || uploadItem == null)
            {
                return;
            }

            var sw = PerfTimer.StartNew();

            await SendAsync(new ADCSNDMessage
            {
                Type    = ADCGETType.File,
                Request = adcgetMessage.Request,
                Start   = adcgetMessage.Start,
                Length  = adcgetMessage.Length
            }.Raw + "|").ConfigureAwait(false);

            try
            {
                if (_disposed)
                {
                    return;
                }

                await uploadItem.SendChunkAsync(this, adcgetMessage.Start, (int)adcgetMessage.Length).ConfigureAwait(false);

                Stream.Flush();
                sw.Stop();
                _isResponding = false;
                ServiceTime.Update((int)sw.ElapsedMilliseconds);
            }
            catch (Exception x)
            {
                Logger.Error("Upload read error {0} (L:{1}) {2} {3} ms",
                             x.Message,
                             adcgetMessage.Length,
                             uploadItem.Content.SystemPath,
                             sw.ElapsedMilliseconds);
                Dispose();
            }
        }
Example #2
0
        protected override void ParseRaw(byte[] buffer, int offset, int length)
        {
            if (_disposed)
            {
                return;
            }

            if (_tail != null)
            {
                var newBuffer = new byte[_tail.Length + length];

                Buffer.BlockCopy(_tail, 0, newBuffer, 0, _tail.Length);
                Buffer.BlockCopy(buffer, offset, newBuffer, _tail.Length, length);

                length = length + _tail.Length;
                buffer = newBuffer;
                offset = 0;
                _tail  = null;
            }

            if (_binaryMode)
            {
                ParseBinary(buffer, offset, length);
                return;
            }

            int cmdEndIndex = offset;

            while (true)
            {
                var prevPos = cmdEndIndex == offset ? offset : cmdEndIndex + 1;
                cmdEndIndex = Array.IndexOf(buffer, (byte)'|', prevPos, length - (cmdEndIndex - offset));

                if (cmdEndIndex == -1)
                {
                    if (prevPos < length)
                    {
                        _tail = new byte[length - prevPos];
                        Buffer.BlockCopy(buffer, prevPos, _tail, 0, _tail.Length);
                    }

                    break;
                }

                var command = _encoding.GetString(buffer, prevPos, cmdEndIndex - prevPos);

                if (IncomingMessage != null)
                {
                    OnIncomingMessage(new MessageEventArgs {
                        Message = command
                    });
                }

                if (command.Length > 0 && command[0] == '$')
                {
                    // command
                    var spaceIndex = command.IndexOf(' ');
                    var cmdName    = spaceIndex == -1 ? command : command.Substring(0, spaceIndex);

                    switch (cmdName)
                    {
                    case "$MyNick":
                    {
                        var arg = MyNickMessage.Parse(command);
                        OnMessageMyNick(ref arg);
                    }
                    break;

                    case "$Supports":
                    {
                        var arg = SupportsMessage.Parse(command);
                        OnMessageSupports(ref arg);
                    }
                    break;

                    case "$Lock":
                    {
                        var arg = LockMessage.Parse(command);
                        OnMessageLock(ref arg);
                    }
                    break;

                    case "$Direction":
                    {
                        var arg = DirectionMessage.Parse(command);
                        OnMessageDirection(ref arg);
                    }
                    break;

                    case "$Error":
                    {
                        var arg = ErrorMessage.Parse(command);
                        OnMessageError(ref arg);
                    }
                    break;

                    case "$Key":
                    {
                        var arg = KeyMessage.Parse(command);
                        OnMessageKey(ref arg);
                    }
                    break;

                    case "$ADCSND":
                    {
                        var arg = ADCSNDMessage.Parse(command);
                        if (OnMessageAdcsnd(ref arg))
                        {
                            prevPos = cmdEndIndex + 1;
                            if (prevPos < length + offset)
                            {
                                _tail = new byte[length - (prevPos - offset)];
                                Buffer.BlockCopy(buffer, prevPos, _tail, 0, _tail.Length);
                            }

                            _binaryMode = true;
                            return;
                        }

                        Dispose();
                    }
                    break;

                    case "$ADCGET":
                    {
                        var arg = ADCGETMessage.Parse(command);
                        OnMessageAdcget(arg);
                    }
                    break;
                    }
                }
            }
        }