Ejemplo n.º 1
0
            public void Work(object state)
            {
                HttpListenerContext context = (HttpListenerContext)state;

                try {
                    // Get the credentials if specified,
                    if (context.User != null)
                    {
                        HttpListenerBasicIdentity identity = (HttpListenerBasicIdentity)context.User.Identity;
                        if (identity != null)
                        {
                            string userName = identity.Name;
                            string password = identity.Password;

                            //TODO: verify if they're allowed ...
                        }
                    }

                    // The main command dispatch loop for this connection,
                    while (true)
                    {
                        IPAddress ipAddress = context.Request.RemoteEndPoint.Address;

                        // Read the command destination,
                        string serviceTypeString = context.Request.Headers["Service-Type"];
                        if (String.IsNullOrEmpty(serviceTypeString) ||
                            String.Compare(serviceTypeString, "Error", true) == 0)
                        {
                            return;
                        }

                        ServiceType serviceType = (ServiceType)Enum.Parse(typeof(ServiceType), serviceTypeString, true);

                        // Read the message stream object
                        IMessageSerializer serializer = service.Connector.MessageSerializer;

                        MemoryStream deserStream = new MemoryStream(1024);
                        Stream       input       = context.Request.InputStream;

                        byte[] buffer = new byte[32768];
                        int    read;
                        while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            deserStream.Write(buffer, 0, read);
                        }

                        try {
                            input.Close();
                        } catch (Exception e) {
                            service.Logger.Error("Error while closing the input stream of the connection.", e);
                        }

                        deserStream.Seek(0, SeekOrigin.Begin);
                        if (deserStream.Length == 0)
                        {
                            service.Logger.Warning("An empty request was received: ignoring");
                            return;
                        }

                        RequestMessage requestMessage = (RequestMessage)serializer.Deserialize(deserStream, MessageType.Request);

                        Message responseMessage;

                        service.OnClientRequest(serviceType, ipAddress.ToString(), requestMessage);

                        // For analytics
                        DateTime benchmarkStart = DateTime.Now;

                        // Destined for the administration module,
                        if (serviceType == ServiceType.Admin)
                        {
                            responseMessage = service.Processor.Process(requestMessage);
                        }
                        // For a block service in this machine
                        else if (serviceType == ServiceType.Block)
                        {
                            if (service.Block == null)
                            {
                                responseMessage = NoServiceError(requestMessage);
                            }
                            else
                            {
                                responseMessage = service.Block.Processor.Process(requestMessage);
                            }
                        }
                        // For a manager service in this machine
                        else if (serviceType == ServiceType.Manager)
                        {
                            if (service.Manager == null)
                            {
                                responseMessage = NoServiceError(requestMessage);
                            }
                            else
                            {
                                responseMessage = service.Manager.Processor.Process(requestMessage);
                            }
                        }
                        // For a root service in this machine
                        else if (serviceType == ServiceType.Root)
                        {
                            if (service.Root == null)
                            {
                                responseMessage = NoServiceError(requestMessage);
                            }
                            else
                            {
                                responseMessage = service.Root.Processor.Process(requestMessage);
                            }
                        }
                        else
                        {
                            throw new InvalidOperationException("Invalid destination service.");
                        }

                        service.OnClientResponse(ipAddress.ToString(), responseMessage);

                        // Update the stats
                        DateTime benchmarkEnd = DateTime.Now;
                        TimeSpan timeTook     = benchmarkEnd - benchmarkStart;
                        service.Analytics.AddEvent(benchmarkEnd, timeTook);

                        // Write and flush the output message,
                        context.Response.StatusCode = (int)HttpStatusCode.OK;
                        if (serializer is ITextMessageSerializer)
                        {
                            ITextMessageSerializer textSerializer = (ITextMessageSerializer)serializer;
                            context.Response.ContentEncoding = Encoding.GetEncoding(textSerializer.ContentEncoding);
                            context.Response.ContentType     = textSerializer.ContentType;
                        }
                        serializer.Serialize(responseMessage, context.Response.OutputStream);
                        context.Response.OutputStream.Flush();
                        context.Response.Close();

                        service.OnClientDisconnect(ipAddress.ToString());
                    }                     // while (true)
                } catch (IOException e) {
                    if (e is EndOfStreamException)
                    {
                        // Ignore this one also,
                    }
                    else
                    {
                        //TODO: ERROR log ...
                    }
                }  finally {
                    // Make sure the socket is closed before we return from the thread,
                    try {
                        context.Response.Close();
                    } catch (IOException e) {
                        //TODO: ERROR log ...
                    }
                }
            }