예제 #1
0
        private static void HttpListener_RequestReceived(object sender, RequestEventArgs e)
        {
            IHttpRequest       request = e.Request;
            IHttpClientContext context = sender as IHttpClientContext;

            foreach (var module in Modules)
            {
                if (module.Execute(request.Uri.AbsolutePath, request, out string result))
                {
                    context.Respond(result ?? string.Empty);
                    return;
                }
            }
            context.Respond(string.Empty);
        }
예제 #2
0
        public void SendResponse(List <LLEventQueueEvent> eventsToSend)
        {
            if (Request == null || Response == null)
            {
                ConnectionOpen = false;
                m_log.Warn("Cannot send response, connection is closed");
                return;
            }

            Response.Connection = Request.Connection;

            if (eventsToSend != null)
            {
                OSDArray responseArray = new OSDArray(eventsToSend.Count);

                // Put all of the events in an array
                for (int i = 0; i < eventsToSend.Count; i++)
                {
                    LLEventQueueEvent currentEvent = eventsToSend[i];

                    OSDMap eventMap = new OSDMap(2);
                    eventMap.Add("message", OSD.FromString(currentEvent.Name));
                    eventMap.Add("body", currentEvent.Body);
                    responseArray.Add(eventMap);
                }

                // Create a map containing the events array and the id of this response
                OSDMap responseMap = new OSDMap(2);
                responseMap.Add("events", responseArray);
                responseMap.Add("id", OSD.FromInteger(CurrentID++));

                // Serialize the events and send the response
                string responseBody = OSDParser.SerializeLLSDXmlString(responseMap);

                m_log.Debug("Sending " + responseArray.Count + " events over the event queue");
                Context.Respond(HttpHelper.HTTP11, HttpStatusCode.OK, "OK", responseBody, "application/xml");
            }
            else
            {
                //m_log.Debug("Sending a timeout response over the event queue");

                // The 502 response started as a bug in the LL event queue server implementation,
                // but is now hardcoded into the protocol as the code to use for a timeout
                Context.Respond(HttpHelper.HTTP10, HttpStatusCode.BadGateway, "Upstream error:", "Upstream error:", null);
            }

            ConnectionOpen = false;
        }
        private void OnIncomingRequest(object source, RequestEventArgs args)
        {
            IHttpClientContext client  = (IHttpClientContext)source;
            IHttpRequest       request = args.Request;

            client.Respond("Hello world!");
            ++_currentThreadCount;
            _testEvent.Set();
        }
예제 #4
0
        protected void HandleHTTPRequest(IHttpClientContext context, IHttpRequest request)
        {
            Uri    uri          = request.Uri;
            string hostName     = uri.Host;
            string pathAndQuery = uri.PathAndQuery;

            try
            {
                // Handle different HTTP methods here
                if (request.Method == "NOTIFY")
                {
                    foreach (DeviceConnection connection in _connectedDevices.Values)
                    {
                        if (!NetworkHelper.HostNamesEqual(hostName,
                                                          NetworkHelper.IPAddrToHostName(connection.GENAClientController.EventNotificationEndpoint.Address)))
                        {
                            continue;
                        }
                        if (pathAndQuery == connection.GENAClientController.EventNotificationPath)
                        {
                            IHttpResponse response = request.CreateResponse(context);
                            response.Status = connection.GENAClientController.HandleUnicastEventNotification(request);
                            response.Send();
                            return;
                        }
                    }
                }
                else
                {
                    context.Respond(HttpHelper.HTTP11, HttpStatusCode.MethodNotAllowed, null);
                    return;
                }
                // Url didn't match
                context.Respond(HttpHelper.HTTP11, HttpStatusCode.NotFound, null);
                return;
            }
            catch (Exception) // Don't log the exception here - we don't care about not being able to send the return value to the client
            {
                IHttpResponse response = request.CreateResponse(context);
                response.Status = HttpStatusCode.InternalServerError;
                response.Send();
                return;
            }
        }
예제 #5
0
        void SendResponse(IHttpClientContext context, IHttpRequest request, IHttpResponse response, List <EventQueueEvent> eventsToSend)
        {
            response.Connection = request.Connection;

            if (eventsToSend != null)
            {
                OSDArray responseArray = new OSDArray(eventsToSend.Count);

                // Put all of the events in an array
                for (int i = 0; i < eventsToSend.Count; i++)
                {
                    EventQueueEvent currentEvent = eventsToSend[i];

                    OSDMap eventMap = new OSDMap(2);
                    eventMap.Add("message", OSD.FromString(currentEvent.Name));
                    eventMap.Add("body", currentEvent.Body);
                    responseArray.Add(eventMap);
                }

                // Create a map containing the events array and the id of this response
                OSDMap responseMap = new OSDMap(2);
                responseMap.Add("events", responseArray);
                responseMap.Add("id", OSD.FromInteger(currentID++));

                // Serialize the events and send the response
                string responseBody = OSDParser.SerializeLLSDXmlString(responseMap);

                Logger.Log.Debug("[EventQueue] Sending " + responseArray.Count + " events over the event queue");
                context.Respond(HttpHelper.HTTP11, HttpStatusCode.OK, "OK", responseBody, "application/xml");
            }
            else
            {
                //Logger.Log.Debug("[EventQueue] Sending a timeout response over the event queue");

                // The 502 response started as a bug in the LL event queue server implementation,
                // but is now hardcoded into the protocol as the code to use for a timeout
                context.Respond(HttpHelper.HTTP10, HttpStatusCode.BadGateway, "Upstream error:", "Upstream error:", null);
            }
        }
예제 #6
0
        private void OnRequest(object source, RequestEventArgs args)
        {
            IHttpClientContext context = (IHttpClientContext)source;
            IHttpRequest       request = args.Request;

            // Respond is a small convenience function that let's you send one string to the browser.
            // you can also use the Send, SendHeader and SendBody methods to have total control.
            if (request.Uri.AbsolutePath == "/hello")
            {
                context.Respond("Hello to you too!");
            }

            else if (request.UriParts.Length == 1 && request.UriParts[0] == "goodbye")
            {
                IHttpResponse response = request.CreateResponse(context);
                StreamWriter  writer   = new StreamWriter(response.Body);
                writer.WriteLine("Goodbye to you too!");
                writer.Flush();
                response.Send();
            }
        }
예제 #7
0
        /// <summary>
        /// Received from a <see cref="IHttpClientContext"/> when a request have been parsed successfully.
        /// </summary>
        /// <param name="source"><see cref="IHttpClientContext"/> that received the request.</param>
        /// <param name="args">The request.</param>
        private void OnRequest(object source, RequestEventArgs args)
        {
            _current = this;
            IHttpClientContext context = (IHttpClientContext)source;
            IHttpRequest       request = args.Request;

            if (_requestQueue.ShouldQueue)
            {
                // Do not use unfinished _requestQueue:
                //_requestQueue.Enqueue(context, request);

                context.Respond("HTTP/1.0", HttpStatusCode.ServiceUnavailable, HttpStatusCode.ServiceUnavailable.ToString(), "Request Queue is full", "text/plain");
                return;
            }

            ProcessRequestWrapper(context, request);

            // no need to lock, if all threads are busy,
            // someone is bound to trigger the thread correctly =)
            // Update: Trigger body does not (yet) have any implementation.
            //_requestQueue.Trigger();
        }
예제 #8
0
		private void ProcessRequest(IHttpClientContext context, IHttpRequest request)
		{
			IHttpResponse response = request.CreateResponse(context);
			try
			{
				foreach (IRule rule in _rules)
				{
					if (!rule.Process(request, response))
						continue;
					response.Send();
					return;
				}

				// load cookies if the exist.
				RequestCookies cookies = request.Headers["cookie"] != null
											 ? new RequestCookies(request.Headers["cookie"])
											 : new RequestCookies(string.Empty);

				request.SetCookies(cookies);

				IHttpSession session;
				if (cookies[_sessionCookieName] != null)
				{
					string sessionCookie = cookies[_sessionCookieName].Value;

					// there's a bug somewhere which messes up headers which can render the session cookie useless.
					// therefore let's consider the session cookie as not set if that have happened.
					if (sessionCookie.Length > 40)
					{
						_logWriter.Write(this, LogPrio.Error, "Session cookie is invalid: " + sessionCookie);
						cookies.Remove(_sessionCookieName);
						_sessionStore.Remove(sessionCookie); // free the session cookie (and thus generating a new one).
						session = _sessionStore.Create();
					}
					else
						session = _sessionStore.Load(sessionCookie) ??
								  _sessionStore.Create(sessionCookie);
				}
				else
					session = _sessionStore.Create();

				HandleRequest(context, request, response, session);
			}
			catch (Exception err)
			{
				if (_exceptionHandler == null)
#if DEBUG
					throw;
#else
				{
					WriteLog(LogPrio.Fatal, err.Message);
					return;
				}
#endif
				_exceptionHandler(this, err);

				Exception e = err;
				while (e != null)
				{
					if (e is SocketException)
						return;

					e = e.InnerException;
				}

				try
				{
#if DEBUG
					context.Respond("HTTP/1.0", HttpStatusCode.InternalServerError, "Internal server error", err.ToString(), "text/plain");
#else
					context.Respond("HTTP/1.0", HttpStatusCode.InternalServerError, "Internal server error");
#endif
				}
				catch (Exception err2)
				{
					LogWriter.Write(this, LogPrio.Fatal, "Failed to respond on message with Internal Server Error: " + err2);
				}


			}
		}
예제 #9
0
        private void ProcessRequest(IHttpClientContext context, IHttpRequest request)
        {
            IHttpResponse response = request.CreateResponse(context);

            try
            {
                foreach (IRule rule in _rules)
                {
                    if (!rule.Process(request, response))
                    {
                        continue;
                    }
                    response.Send();
                    return;
                }

                // load cookies if the exist.
                RequestCookies cookies = request.Headers["cookie"] != null
                                                                                         ? new RequestCookies(request.Headers["cookie"])
                                                                                         : new RequestCookies(string.Empty);

                request.SetCookies(cookies);

                IHttpSession session;
                if (cookies[_sessionCookieName] != null)
                {
                    string sessionCookie = cookies[_sessionCookieName].Value;

                    // there's a bug somewhere which f***s up headers which can render the session cookie useless.
                    // therefore let's consider the session cookie as not set if that have happened.
                    if (sessionCookie.Length > 40)
                    {
                        LogWriter.Write(this, LogPrio.Error, "Session cookie is invalid: " + sessionCookie);
                        cookies.Remove(_sessionCookieName);
                        _sessionStore.Remove(sessionCookie);                         // free the session cookie (and thus generating a new one).
                        session = _sessionStore.Create();
                    }
                    else
                    {
                        session = _sessionStore.Load(sessionCookie) ??
                                  _sessionStore.Create(sessionCookie);
                    }
                }
                else
                {
                    session = _sessionStore.Create();
                }

                HandleRequest(context, request, response, session);
            }
            catch (Exception err)
            {
                if (_exceptionHandler == null)
#if DEBUG
                { throw; }
#else
                {
                    WriteLog(LogPrio.Fatal, err.Message);
                    return;
                }
#endif
                _exceptionHandler(this, err);

                Exception e = err;
                while (e != null)
                {
                    if (e is SocketException)
                    {
                        return;
                    }

                    e = e.InnerException;
                }

                try
                {
#if DEBUG
                    context.Respond("HTTP/1.0", HttpStatusCode.InternalServerError, "Internal server error", err.ToString(), "text/plain");
#else
                    context.Respond("HTTP/1.0", HttpStatusCode.InternalServerError, "Internal server error");
#endif
                }
                catch (Exception err2)
                {
                    LogWriter.Write(this, LogPrio.Fatal, "Failed to respond on message with Internal Server Error: " + err2);
                }
            }
        }
예제 #10
0
    /// <summary>
    /// Handles all kinds of HTTP over TCP requests - Description, Control and Event subscriptions.
    /// </summary>
    /// <param name="context">HTTP client context of the current request.</param>
    /// <param name="request">HTTP request to handle.</param>
    protected void HandleHTTPRequest_NoLock(IHttpClientContext context, IHttpRequest request)
    {
      Uri uri = request.Uri;
      string hostName = uri.Host;
      string pathAndQuery = uri.LocalPath; // Unfortunately, Uri.PathAndQuery doesn't decode characters like '{' and '}', so we use the Uri.LocalPath property
      try
      {
        DvService service;
        ICollection<EndpointConfiguration> endpoints;
        lock (_serverData.SyncObj)
          endpoints = _serverData.UPnPEndPoints;
        foreach (EndpointConfiguration config in endpoints)
        {
          if (!NetworkHelper.HostNamesEqual(hostName, NetworkHelper.IPAddrToHostName(config.EndPointIPAddress)))
            continue;

          // Common check for supported encodings
          string acceptEncoding = request.Headers.Get("ACCEPT-ENCODING") ?? string.Empty;

          // Handle different HTTP methods here
          if (request.Method == "GET")
          { // GET of descriptions
            if (pathAndQuery.StartsWith(config.DescriptionPathBase))
            {
              string acceptLanguage = request.Headers.Get("ACCEPT-LANGUAGE");
              CultureInfo culture = GetFirstCultureOrDefault(acceptLanguage, CultureInfo.InvariantCulture);

              string description = null;
              DvDevice rootDevice;
              lock (_serverData.SyncObj)
                if (config.RootDeviceDescriptionPathsToRootDevices.TryGetValue(pathAndQuery, out rootDevice))
                  description = rootDevice.BuildRootDeviceDescription(_serverData, config, culture);
                else if (config.SCPDPathsToServices.TryGetValue(pathAndQuery, out service))
                  description = service.BuildSCPDDocument(config, _serverData);
              if (description != null)
              {
                IHttpResponse response = request.CreateResponse(context);
                response.Status = HttpStatusCode.OK;
                response.ContentType = "text/xml; charset=utf-8";
                if (!string.IsNullOrEmpty(acceptLanguage))
                  response.AddHeader("CONTENT-LANGUAGE", culture.ToString());
                using (MemoryStream responseStream = new MemoryStream(UPnPConsts.UTF8_NO_BOM.GetBytes(description)))
                  CompressionHelper.WriteCompressedStream(acceptEncoding, response, responseStream);
                SafeSendResponse(response);
                return;
              }
            }
          }
          else if (request.Method == "POST")
          { // POST of control messages
            if (config.ControlPathsToServices.TryGetValue(pathAndQuery, out service))
            {
              string contentType = request.Headers.Get("CONTENT-TYPE");
              string userAgentStr = request.Headers.Get("USER-AGENT");
              IHttpResponse response = request.CreateResponse(context);
              int minorVersion;
              if (string.IsNullOrEmpty(userAgentStr))
                minorVersion = 0;
              else if (!ParserHelper.ParseUserAgentUPnP1MinorVersion(userAgentStr, out minorVersion))
              {
                response.Status = HttpStatusCode.BadRequest;
                SafeSendResponse(response);
                return;
              }
              string mediaType;
              Encoding encoding;
              if (!EncodingUtils.TryParseContentTypeEncoding(contentType, Encoding.UTF8, out mediaType, out encoding))
                throw new ArgumentException("Unable to parse content type");
              if (mediaType != "text/xml")
              { // As specified in (DevArch), 3.2.1
                response.Status = HttpStatusCode.UnsupportedMediaType;
                SafeSendResponse(response);
                return;
              }
              response.AddHeader("DATE", DateTime.Now.ToUniversalTime().ToString("R"));
              response.AddHeader("SERVER", UPnPConfiguration.UPnPMachineInfoHeader);
              response.AddHeader("CONTENT-TYPE", "text/xml; charset=\"utf-8\"");
              string result;
              HttpStatusCode status;
              try
              {
                CallContext callContext = new CallContext(request, context, config);
                status = SOAPHandler.HandleRequest(service, request.Body, encoding, minorVersion >= 1, callContext, out result);
              }
              catch (Exception e)
              {
                UPnPConfiguration.LOGGER.Warn("Action invocation failed", e);
                result = SOAPHandler.CreateFaultDocument(501, "Action failed");
                status = HttpStatusCode.InternalServerError;
              }
              response.Status = status;
              using (MemoryStream responseStream = new MemoryStream(encoding.GetBytes(result)))
                CompressionHelper.WriteCompressedStream(acceptEncoding, response, responseStream);
              SafeSendResponse(response);
              return;
            }
          }
          else if (request.Method == "SUBSCRIBE" || request.Method == "UNSUBSCRIBE")
          {
            GENAServerController gsc;
            lock (_serverData.SyncObj)
              gsc = _serverData.GENAController;
            if (gsc.HandleHTTPRequest(request, context, config))
              return;
          }
          else
          {
            context.Respond(HttpHelper.HTTP11, HttpStatusCode.MethodNotAllowed, null);
            return;
          }
        }
        // Url didn't match
        context.Respond(HttpHelper.HTTP11, HttpStatusCode.NotFound, null);
      }
      catch (Exception e)
      {
        UPnPConfiguration.LOGGER.Error("UPnPServer: Error handling HTTP request '{0}'", e, uri);
        IHttpResponse response = request.CreateResponse(context);
        response.Status = HttpStatusCode.InternalServerError;
        SafeSendResponse(response);
      }
    }
예제 #11
0
        void SendResponse(IHttpClientContext context, IHttpRequest request, IHttpResponse response, List<EventQueueEvent> eventsToSend)
        {
            response.Connection = request.Connection;

            if (eventsToSend != null)
            {
                OSDArray responseArray = new OSDArray(eventsToSend.Count);

                // Put all of the events in an array
                for (int i = 0; i < eventsToSend.Count; i++)
                {
                    EventQueueEvent currentEvent = eventsToSend[i];

                    OSDMap eventMap = new OSDMap(2);
                    eventMap.Add("message", OSD.FromString(currentEvent.Name));
                    eventMap.Add("body", currentEvent.Body);
                    responseArray.Add(eventMap);
                }

                // Create a map containing the events array and the id of this response
                OSDMap responseMap = new OSDMap(2);
                responseMap.Add("events", responseArray);
                responseMap.Add("id", OSD.FromInteger(currentID++));

                // Serialize the events and send the response
                string responseBody = OSDParser.SerializeLLSDXmlString(responseMap);

                Logger.Log.Debug("[EventQueue] Sending " + responseArray.Count + " events over the event queue");
                context.Respond(HttpHelper.HTTP11, HttpStatusCode.OK, "OK", responseBody, "application/xml");
            }
            else
            {
                //Logger.Log.Debug("[EventQueue] Sending a timeout response over the event queue");

                // The 502 response started as a bug in the LL event queue server implementation,
                // but is now hardcoded into the protocol as the code to use for a timeout
                context.Respond(HttpHelper.HTTP10, HttpStatusCode.BadGateway, "Upstream error:", "Upstream error:", null);
            }
        }
예제 #12
0
 protected void HandleHTTPRequest(IHttpClientContext context, IHttpRequest request)
 {
   Uri uri = request.Uri;
   string hostName = uri.Host;
   string pathAndQuery = uri.PathAndQuery;
   try
   {
     // Handle different HTTP methods here
     if (request.Method == "NOTIFY")
     {
       foreach (DeviceConnection connection in _connectedDevices.Values)
       {
         if (!NetworkHelper.HostNamesEqual(hostName,
             NetworkHelper.IPAddrToHostName(connection.GENAClientController.EventNotificationEndpoint.Address)))
           continue;
         if (pathAndQuery == connection.GENAClientController.EventNotificationPath)
         {
           IHttpResponse response = request.CreateResponse(context);
           response.Status = connection.GENAClientController.HandleUnicastEventNotification(request);
           response.Send();
           return;
         }
       }
     }
     else
     {
       context.Respond(HttpHelper.HTTP11, HttpStatusCode.MethodNotAllowed, null);
       return;
     }
     // Url didn't match
     context.Respond(HttpHelper.HTTP11, HttpStatusCode.NotFound, null);
   }
   catch (Exception) // Don't log the exception here - we don't care about not being able to send the return value to the client
   {
     IHttpResponse response = request.CreateResponse(context);
     response.Status = HttpStatusCode.InternalServerError;
     response.Send();
   }
 }
예제 #13
0
        /// <summary>
        /// Handles all kinds of HTTP over TCP requests - Description, Control and Event subscriptions.
        /// </summary>
        /// <param name="context">HTTP client context of the current request.</param>
        /// <param name="request">HTTP request to handle.</param>
        protected void HandleHTTPRequest_NoLock(IHttpClientContext context, IHttpRequest request)
        {
            Uri    uri          = request.Uri;
            string hostName     = uri.Host;
            string pathAndQuery = uri.LocalPath; // Unfortunately, Uri.PathAndQuery doesn't decode characters like '{' and '}', so we use the Uri.LocalPath property

            try
            {
                DvService service;
                ICollection <EndpointConfiguration> endpoints;
                lock (_serverData.SyncObj)
                    endpoints = _serverData.UPnPEndPoints;
                foreach (EndpointConfiguration config in endpoints)
                {
                    if (!NetworkHelper.HostNamesEqual(hostName, NetworkHelper.IPAddrToHostName(config.EndPointIPAddress)))
                    {
                        continue;
                    }

                    // Common check for supported encodings
                    string acceptEncoding = request.Headers.Get("ACCEPT-ENCODING") ?? string.Empty;

                    // Handle different HTTP methods here
                    if (request.Method == "GET")
                    { // GET of descriptions
                        if (pathAndQuery.StartsWith(config.DescriptionPathBase))
                        {
                            string      acceptLanguage = request.Headers.Get("ACCEPT-LANGUAGE");
                            CultureInfo culture        = GetFirstCultureOrDefault(acceptLanguage, CultureInfo.InvariantCulture);

                            string   description = null;
                            DvDevice rootDevice;
                            lock (_serverData.SyncObj)
                                if (config.RootDeviceDescriptionPathsToRootDevices.TryGetValue(pathAndQuery, out rootDevice))
                                {
                                    description = rootDevice.BuildRootDeviceDescription(_serverData, config, culture);
                                }
                                else if (config.SCPDPathsToServices.TryGetValue(pathAndQuery, out service))
                                {
                                    description = service.BuildSCPDDocument(config, _serverData);
                                }
                            if (description != null)
                            {
                                IHttpResponse response = request.CreateResponse(context);
                                response.Status      = HttpStatusCode.OK;
                                response.ContentType = "text/xml; charset=utf-8";
                                if (!string.IsNullOrEmpty(acceptLanguage))
                                {
                                    response.AddHeader("CONTENT-LANGUAGE", culture.ToString());
                                }
                                using (MemoryStream responseStream = new MemoryStream(UPnPConsts.UTF8_NO_BOM.GetBytes(description)))
                                    CompressionHelper.WriteCompressedStream(acceptEncoding, response, responseStream);
                                SafeSendResponse(response);
                                return;
                            }
                        }
                    }
                    else if (request.Method == "POST")
                    { // POST of control messages
                        if (config.ControlPathsToServices.TryGetValue(pathAndQuery, out service))
                        {
                            string        contentType  = request.Headers.Get("CONTENT-TYPE");
                            string        userAgentStr = request.Headers.Get("USER-AGENT");
                            IHttpResponse response     = request.CreateResponse(context);
                            int           minorVersion;
                            if (string.IsNullOrEmpty(userAgentStr))
                            {
                                minorVersion = 0;
                            }
                            else if (!ParserHelper.ParseUserAgentUPnP1MinorVersion(userAgentStr, out minorVersion))
                            {
                                response.Status = HttpStatusCode.BadRequest;
                                SafeSendResponse(response);
                                return;
                            }
                            string   mediaType;
                            Encoding encoding;
                            if (!EncodingUtils.TryParseContentTypeEncoding(contentType, Encoding.UTF8, out mediaType, out encoding))
                            {
                                throw new ArgumentException("Unable to parse content type");
                            }
                            if (mediaType != "text/xml")
                            { // As specified in (DevArch), 3.2.1
                                response.Status = HttpStatusCode.UnsupportedMediaType;
                                SafeSendResponse(response);
                                return;
                            }
                            response.AddHeader("DATE", DateTime.Now.ToUniversalTime().ToString("R"));
                            response.AddHeader("SERVER", UPnPConfiguration.UPnPMachineInfoHeader);
                            response.AddHeader("CONTENT-TYPE", "text/xml; charset=\"utf-8\"");
                            string         result;
                            HttpStatusCode status;
                            try
                            {
                                CallContext callContext = new CallContext(request, context, config);
                                status = SOAPHandler.HandleRequest(service, request.Body, encoding, minorVersion >= 1, callContext, out result);
                            }
                            catch (Exception e)
                            {
                                UPnPConfiguration.LOGGER.Warn("Action invocation failed", e);
                                result = SOAPHandler.CreateFaultDocument(501, "Action failed");
                                status = HttpStatusCode.InternalServerError;
                            }
                            response.Status = status;
                            using (MemoryStream responseStream = new MemoryStream(encoding.GetBytes(result)))
                                CompressionHelper.WriteCompressedStream(acceptEncoding, response, responseStream);
                            SafeSendResponse(response);
                            return;
                        }
                    }
                    else if (request.Method == "SUBSCRIBE" || request.Method == "UNSUBSCRIBE")
                    {
                        GENAServerController gsc;
                        lock (_serverData.SyncObj)
                            gsc = _serverData.GENAController;
                        if (gsc.HandleHTTPRequest(request, context, config))
                        {
                            return;
                        }
                    }
                    else
                    {
                        context.Respond(HttpHelper.HTTP11, HttpStatusCode.MethodNotAllowed, null);
                        return;
                    }
                }
                // Url didn't match
                context.Respond(HttpHelper.HTTP11, HttpStatusCode.NotFound, null);
            }
            catch (Exception e)
            {
                UPnPConfiguration.LOGGER.Error("UPnPServer: Error handling HTTP request '{0}'", e, uri);
                IHttpResponse response = request.CreateResponse(context);
                response.Status = HttpStatusCode.InternalServerError;
                SafeSendResponse(response);
            }
        }
예제 #14
0
        void ProcessRequest(IHttpClientContext context, IHttpRequest request)
        {
            LogWriter.Write(this, LogPrio.Trace, "Processing request...");

            IHttpResponse response = request.CreateResponse(context);

            try
            {
                // load cookies if they exist.
                RequestCookies cookies = request.Headers["cookie"] != null
                                             ? new RequestCookies(request.Headers["cookie"])
                                             : new RequestCookies(string.Empty);
                request.SetCookies(cookies);

                // Create a request signature
                HttpRequestSignature signature = new HttpRequestSignature(request);

                // Look for a signature match in our handlers
                bool found = false;
                for (int i = 0; i < _requestHandlers.Length; i++)
                {
                    HttpRequestHandler handler = _requestHandlers[i];

                    if (signature == handler.Signature)
                    {
                        FireRequestCallback(context, request, response, handler.Callback);
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    // No registered handler matched this request's signature
                    if (_notFoundHandler != null)
                    {
                        FireRequestCallback(context, request, response, _notFoundHandler);
                    }
                    else
                    {
                        // Send a default 404 response
                        try
                        {
                            response.Status = HttpStatusCode.NotFound;
                            response.Reason = String.Format("No request handler registered for Method=\"{0}\", Content-Type=\"{1}\", Path=\"{2}\"",
                                                            signature.Method, signature.ContentType, signature.Path);
                            string notFoundResponse = "<html><head><title>Page Not Found</title></head><body><h3>" + response.Reason + "</h3></body></html>";
                            byte[] buffer           = System.Text.Encoding.UTF8.GetBytes(notFoundResponse);
                            response.Body.Write(buffer, 0, buffer.Length);
                            response.Send();
                        }
                        catch (Exception) { }
                    }
                }
            }
            catch (Exception err)
            {
                ThrowException(err);

                bool errorResponse = true;

                Exception e = err;
                while (e != null)
                {
                    if (e is SocketException)
                    {
                        errorResponse = false;
                        break;
                    }

                    e = e.InnerException;
                }

                if (errorResponse)
                {
                    try
                    {
#if DEBUG
                        context.Respond(HttpHelper.HTTP11, HttpStatusCode.InternalServerError, "Internal server error", err.ToString(), "text/plain");
#else
                        context.Respond(HttpHelper.HTTP10, HttpStatusCode.InternalServerError, "Internal server error");
#endif
                    }
                    catch (Exception err2)
                    {
                        LogWriter.Write(this, LogPrio.Fatal, "Failed to respond on message with Internal Server Error: " + err2);
                    }
                }
            }

            request.Clear();
            LogWriter.Write(this, LogPrio.Trace, "...done processing request.");
        }