Package net.pms.external

Examples of net.pms.external.StartStopListenerDelegate


    hdr.add("Accept-Ranges", "bytes");
    hdr.add("Server", PMS.get().getServerName());
    hdr.add("Connection", "keep-alive");
    t.sendResponseHeaders(200, 0);
    OutputStream os = t.getResponseBody();
    StartStopListenerDelegate startStop = new StartStopListenerDelegate(t.getRemoteAddress().getHostString());
    PMS.get().getFrame().setStatusLine("Serving " + dlna.getName());
    startStop.start(dlna);
    RemoteUtil.dump(in, os, startStop);
    PMS.get().getFrame().setStatusLine("");
  }
View Full Code Here


  }

  @Override
  public void run() {
    Request request = null;
    StartStopListenerDelegate startStopListenerDelegate = new StartStopListenerDelegate(socket.getInetAddress().getHostAddress());

    try {
      int receivedContentLength = -1;
      String userAgentString = null;
      StringBuilder unknownHeaders = new StringBuilder();
      String separator = "";
      RendererConfiguration renderer = null;

      InetSocketAddress remoteAddress = (InetSocketAddress) socket.getRemoteSocketAddress();
      InetAddress ia = remoteAddress.getAddress();

      // Apply the IP filter
      if (filterIp(ia)) {
        throw new IOException("Access denied for address " + ia + " based on IP filter");
      }

      LOGGER.trace("Opened request handler on socket " + socket);
      PMS.get().getRegistry().disableGoToSleep();

      // The handler makes a couple of attempts to recognize a renderer from its requests.
      // IP address matches from previous requests are preferred, when that fails request
      // header matches are attempted and if those fail as well we're stuck with the
      // default renderer.

      // Attempt 1: try to recognize the renderer by its socket address from previous requests
      renderer = RendererConfiguration.getRendererConfigurationBySocketAddress(ia);
      ArrayList<String> headerLines = new ArrayList<>();
      RendererConfiguration.SortedHeaderMap sortedHeaders = renderer == null ? new RendererConfiguration.SortedHeaderMap() : null;

      // Gather all the headers
      String line = br.readLine();
      while (line != null && line.length() > 0) {
        headerLines.add(line);
        if (renderer == null) {
          sortedHeaders.put(line);
        }
        line = br.readLine();
      }

      if (renderer == null) {
        // Attempt 2: try to recognize the renderer by matching headers
        renderer = RendererConfiguration.getRendererConfigurationByHeaders(sortedHeaders);
      }

      if (renderer != null) {
        renderer.associateIP(ia);
        PMS.get().setRendererFound(renderer);
      }

      for (String headerLine : headerLines) {
        LOGGER.trace("Received on socket: " + headerLine);

        // The request object is created inside the while loop.
        if (request != null && request.getMediaRenderer() == null && renderer != null) {
          request.setMediaRenderer(renderer);
        }
        if (headerLine.toUpperCase().startsWith("USER-AGENT")) {
          userAgentString = headerLine.substring(headerLine.indexOf(':') + 1).trim();
        }

        try {
          StringTokenizer s = new StringTokenizer(headerLine);
          String temp = s.nextToken();
          if (temp.equals("SUBSCRIBE") || temp.equals("GET") || temp.equals("POST") || temp.equals("HEAD")) {
            request = new Request(temp, s.nextToken().substring(1));
            if (s.hasMoreTokens() && s.nextToken().equals("HTTP/1.0")) {
              request.setHttp10(true);
            }
          } else if (request != null && temp.toUpperCase().equals("CALLBACK:")) {
            request.setSoapaction(s.nextToken());
          } else if (request != null && temp.toUpperCase().equals("SOAPACTION:")) {
            request.setSoapaction(s.nextToken());
          } else if (headerLine.toUpperCase().contains("CONTENT-LENGTH:")) {
            receivedContentLength = Integer.parseInt(headerLine.substring(headerLine.toUpperCase().indexOf("CONTENT-LENGTH: ") + 16));
          } else if (headerLine.toUpperCase().contains("RANGE: BYTES=")) {
            String nums = headerLine.substring(headerLine.toUpperCase().indexOf("RANGE: BYTES=") + 13).trim();
            StringTokenizer st = new StringTokenizer(nums, "-");
            if (!nums.startsWith("-")) {
              request.setLowRange(Long.parseLong(st.nextToken()));
            }
            if (!nums.startsWith("-") && !nums.endsWith("-")) {
              request.setHighRange(Long.parseLong(st.nextToken()));
            } else {
              request.setHighRange(-1);
            }
          } else if (headerLine.toLowerCase().contains("transfermode.dlna.org:")) {
            request.setTransferMode(headerLine.substring(headerLine.toLowerCase().indexOf("transfermode.dlna.org:") + 22).trim());
          } else if (headerLine.toLowerCase().contains("getcontentfeatures.dlna.org:")) {
            request.setContentFeatures(headerLine.substring(headerLine.toLowerCase().indexOf("getcontentfeatures.dlna.org:") + 28).trim());
          } else if (headerLine.toUpperCase().contains("TIMESEEKRANGE.DLNA.ORG: NPT=")) { // firmware 2.50+
            String timeseek = headerLine.substring(headerLine.toUpperCase().indexOf("TIMESEEKRANGE.DLNA.ORG: NPT=") + 28);
            if (timeseek.endsWith("-")) {
              timeseek = timeseek.substring(0, timeseek.length() - 1);
            } else if (timeseek.indexOf('-') > -1) {
              timeseek = timeseek.substring(0, timeseek.indexOf('-'));
            }
            request.setTimeseek(convertStringToTime(timeseek));
          } else if (headerLine.toUpperCase().contains("TIMESEEKRANGE.DLNA.ORG : NPT=")) { // firmware 2.40
            String timeseek = headerLine.substring(headerLine.toUpperCase().indexOf("TIMESEEKRANGE.DLNA.ORG : NPT=") + 29);
            if (timeseek.endsWith("-")) {
              timeseek = timeseek.substring(0, timeseek.length() - 1);
            } else if (timeseek.indexOf('-') > -1) {
              timeseek = timeseek.substring(0, timeseek.indexOf('-'));
            }
            request.setTimeseek(convertStringToTime(timeseek));
          } else {
            /*
             * If we made it to here, none of the previous header checks matched.
             * Unknown headers make interesting logging info when we cannot recognize
             * the media renderer, so keep track of the truly unknown ones.
             */
            boolean isKnown = false;

            // Try to match possible known headers.
            String lowerCaseHeaderLine = headerLine.toLowerCase();
            for (String knownHeaderString : KNOWN_HEADERS) {
              if (lowerCaseHeaderLine.startsWith(knownHeaderString.toLowerCase())) {
                isKnown = true;
                break;
              }
            }

            // It may be unusual but already known
            if (renderer != null) {
              String additionalHeader = renderer.getUserAgentAdditionalHttpHeader();
              if (StringUtils.isNotBlank(additionalHeader) && lowerCaseHeaderLine.startsWith(additionalHeader)) {
                isKnown = true;
              }
            }

            if (!isKnown) {
              // Truly unknown header, therefore interesting. Save for later use.
              unknownHeaders.append(separator).append(headerLine);
              separator = ", ";
            }
          }
        } catch (IllegalArgumentException e) {
          LOGGER.error("Error in parsing HTTP headers", e);
        }
      }

      if (request != null) {
        // Still no media renderer recognized?
        if (request.getMediaRenderer() == null) {
          // Attempt 4: Not really an attempt; all other attempts to recognize
          // the renderer have failed. The only option left is to assume the
          // default renderer.
          request.setMediaRenderer(RendererConfiguration.getDefaultConf());
          LOGGER.trace("Using default media renderer: " + request.getMediaRenderer().getRendererName());

          if (userAgentString != null && !userAgentString.equals("FDSSDP")) {
            // We have found an unknown renderer
            LOGGER.info("Media renderer was not recognized. Possible identifying HTTP headers: User-Agent: " + userAgentString +
                ("".equals(unknownHeaders.toString()) ? "" : ", " + unknownHeaders.toString()));
            PMS.get().setRendererFound(request.getMediaRenderer());
          }
        } else {
          if (userAgentString != null) {
            LOGGER.debug("HTTP User-Agent: " + userAgentString);
          }
          LOGGER.trace("Recognized media renderer: " + request.getMediaRenderer().getRendererName());
        }
      }

      if (receivedContentLength > 0) {
        char buf[] = new char[receivedContentLength];
        br.read(buf);
        if (request != null) {
          request.setTextContent(new String(buf));
        }
      }

      if (request != null) {
        LOGGER.trace("HTTP: " + request.getArgument() + " / " + request.getLowRange() + "-" + request.getHighRange());
      }

      if (request != null) {
        request.answer(output, startStopListenerDelegate);
      }

      if (request != null && request.getInputStream() != null) {
        request.getInputStream().close();
      }
    } catch (IOException e) {
      LOGGER.trace("Unexpected IO error: " + e.getClass().getName() + ": " + e.getMessage());
      if (request != null && request.getInputStream() != null) {
        try {
          LOGGER.trace("Closing input stream: " + request.getInputStream());
          request.getInputStream().close();
        } catch (IOException e1) {
          LOGGER.error("Error closing input stream", e1);
        }
      }
    } finally {
      try {
        PMS.get().getRegistry().reenableGoToSleep();
        output.close();
        br.close();
        socket.close();
      } catch (IOException e) {
        LOGGER.error("Error closing connection: ", e);
      }

      startStopListenerDelegate.stop();
      LOGGER.trace("Close connection");
    }
  }
View Full Code Here

      } else {
        response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
      }
    }

    StartStopListenerDelegate startStopListenerDelegate = new StartStopListenerDelegate(ia.getHostAddress());

    try {
      request.answer(response, e, close, startStopListenerDelegate);
    } catch (IOException e1) {
      LOGGER.trace("HTTP request V2 IO error: " + e1.getMessage());
      // note: we don't call stop() here in a finally block as
      // answer() is non-blocking. we only (may) need to call it
      // here in the case of an exception. it's a no-op if it's
      // already been called
      startStopListenerDelegate.stop();
    }
  }
View Full Code Here

      } else {
        response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
      }
    }
   
    StartStopListenerDelegate startStopListenerDelegate = new StartStopListenerDelegate(ia.getHostAddress());

    try {
      request.answer(response, e, close, startStopListenerDelegate);
    } catch (IOException e1) {
      logger.trace("HTTP request V2 IO error: " + e1.getMessage());
      // note: we don't call stop() here in a finally block as
      // answer() is non-blocking. we only (may) need to call it
      // here in the case of an exception. it's a no-op if it's
      // already been called
      startStopListenerDelegate.stop();
    }
  }
View Full Code Here

  }

  @Override
  public void run() {
    Request request = null;
    StartStopListenerDelegate startStopListenerDelegate = new StartStopListenerDelegate(socket.getInetAddress().getHostAddress());

    try {
      int receivedContentLength = -1;
      String headerLine = br.readLine();
      String userAgentString = null;
      StringBuilder unknownHeaders = new StringBuilder();
      String separator = "";
      RendererConfiguration renderer = null;

      InetSocketAddress remoteAddress = (InetSocketAddress) socket.getRemoteSocketAddress();
      InetAddress ia = remoteAddress.getAddress();

      // Apply the IP filter
      if (filterIp(ia)) {
        throw new IOException("Access denied for address " + ia + " based on IP filter");
      }

      logger.trace("Opened request handler on socket " + socket);
      PMS.get().getRegistry().disableGoToSleep();

      while (headerLine != null && headerLine.length() > 0) {
        logger.trace("Received on socket: " + headerLine);

        // The request object is created inside the while loop.
        if (request != null && request.getMediaRenderer() == null) {
          // The handler makes a couple of attempts to recognize a renderer from its requests.
          // IP address matches from previous requests are preferred, when that fails request
          // header matches are attempted and if those fail as well we're stuck with the
          // default renderer.

          // Attempt 1: try to recognize the renderer by its socket address
          renderer = RendererConfiguration.getRendererConfigurationBySocketAddress(ia);

          if (renderer != null) {
            PMS.get().setRendererFound(renderer);
            request.setMediaRenderer(renderer);
            logger.trace("Matched media renderer \"" + renderer.getRendererName() + "\" based on address " + ia);
          }
        }

        if (renderer == null && headerLine != null
            && headerLine.toUpperCase().startsWith("USER-AGENT")
            && request != null) {
          userAgentString = headerLine.substring(headerLine.indexOf(":") + 1).trim();

          // Attempt 2: try to recognize the renderer by matching the "User-Agent" header
          renderer = RendererConfiguration.getRendererConfigurationByUA(userAgentString);

          if (renderer != null) {
            PMS.get().setRendererFound(renderer);
            request.setMediaRenderer(renderer);
            renderer.associateIP(ia)// Associate IP address for later requests
            logger.trace("Matched media renderer \"" + renderer.getRendererName() + "\" based on header \"" + headerLine + "\"");
          }
        }
        if (renderer == null && headerLine != null && request != null) {
          // Attempt 3: try to recognize the renderer by matching an additional header
          renderer = RendererConfiguration.getRendererConfigurationByUAAHH(headerLine);

          if (renderer != null) {
            PMS.get().setRendererFound(renderer);
            request.setMediaRenderer(renderer);
            renderer.associateIP(ia)// Associate IP address for later requests
            logger.trace("Matched media renderer \"" + renderer.getRendererName() + "\" based on header \"" + headerLine + "\"");
          }
        }
        try {
          StringTokenizer s = new StringTokenizer(headerLine);
          String temp = s.nextToken();
          if (temp.equals("SUBSCRIBE") || temp.equals("GET") || temp.equals("POST") || temp.equals("HEAD")) {
            request = new Request(temp, s.nextToken().substring(1));
            if (s.hasMoreTokens() && s.nextToken().equals("HTTP/1.0")) {
              request.setHttp10(true);
            }
          } else if (request != null && temp.toUpperCase().equals("CALLBACK:")) {
            request.setSoapaction(s.nextToken());
          } else if (request != null && temp.toUpperCase().equals("SOAPACTION:")) {
            request.setSoapaction(s.nextToken());
          } else if (headerLine.toUpperCase().contains("CONTENT-LENGTH:")) {
            receivedContentLength = Integer.parseInt(headerLine.substring(headerLine.toUpperCase().indexOf("CONTENT-LENGTH: ") + 16));
          } else if (headerLine.toUpperCase().indexOf("RANGE: BYTES=") > -1) {
            String nums = headerLine.substring(headerLine.toUpperCase().indexOf("RANGE: BYTES=") + 13).trim();
            StringTokenizer st = new StringTokenizer(nums, "-");
            if (!nums.startsWith("-")) {
              request.setLowRange(Long.parseLong(st.nextToken()));
            }
            if (!nums.startsWith("-") && !nums.endsWith("-")) {
              request.setHighRange(Long.parseLong(st.nextToken()));
            } else {
              request.setHighRange(-1);
            }
          } else if (headerLine.toLowerCase().indexOf("transfermode.dlna.org:") > -1) {
            request.setTransferMode(headerLine.substring(headerLine.toLowerCase().indexOf("transfermode.dlna.org:") + 22).trim());
          } else if (headerLine.toLowerCase().indexOf("getcontentfeatures.dlna.org:") > -1) {
            request.setContentFeatures(headerLine.substring(headerLine.toLowerCase().indexOf("getcontentfeatures.dlna.org:") + 28).trim());
          } else if (headerLine.toUpperCase().indexOf("TIMESEEKRANGE.DLNA.ORG: NPT=") > -1) { // firmware 2.50+
            String timeseek = headerLine.substring(headerLine.toUpperCase().indexOf("TIMESEEKRANGE.DLNA.ORG: NPT=") + 28);
            if (timeseek.endsWith("-")) {
              timeseek = timeseek.substring(0, timeseek.length() - 1);
            } else if (timeseek.indexOf("-") > -1) {
              timeseek = timeseek.substring(0, timeseek.indexOf("-"));
            }
            request.setTimeseek(Double.parseDouble(timeseek));
          } else if (headerLine.toUpperCase().indexOf("TIMESEEKRANGE.DLNA.ORG : NPT=") > -1) { // firmware 2.40
            String timeseek = headerLine.substring(headerLine.toUpperCase().indexOf("TIMESEEKRANGE.DLNA.ORG : NPT=") + 29);
            if (timeseek.endsWith("-")) {
              timeseek = timeseek.substring(0, timeseek.length() - 1);
            } else if (timeseek.indexOf("-") > -1) {
              timeseek = timeseek.substring(0, timeseek.indexOf("-"));
            }
            request.setTimeseek(Double.parseDouble(timeseek));
          } else {
            /*
             * If we made it to here, none of the previous header checks matched.
             * Unknown headers make interesting logging info when we cannot recognize
             * the media renderer, so keep track of the truly unknown ones.
             */
            boolean isKnown = false;

            // Try to match possible known headers.
            for (String knownHeaderString : KNOWN_HEADERS) {
              if (headerLine.toLowerCase().startsWith(knownHeaderString.toLowerCase())) {
                isKnown = true;
                break;
              }
            }

            if (!isKnown) {
              // Truly unknown header, therefore interesting. Save for later use.
              unknownHeaders.append(separator).append(headerLine);
              separator = ", ";
            }
          }
        } catch (Exception e) {
          logger.error("Error in parsing HTTP headers", e);
        }

        headerLine = br.readLine();
      }

      if (request != null) {
        // Still no media renderer recognized?
        if (request.getMediaRenderer() == null) {
          // Attempt 4: Not really an attempt; all other attempts to recognize
          // the renderer have failed. The only option left is to assume the
          // default renderer.
          request.setMediaRenderer(RendererConfiguration.getDefaultConf());
          logger.trace("Using default media renderer: " + request.getMediaRenderer().getRendererName());

          if (userAgentString != null && !userAgentString.equals("FDSSDP")) {
            // We have found an unknown renderer
            logger.info("Media renderer was not recognized. Possible identifying HTTP headers: User-Agent: "  + userAgentString
                + ("".equals(unknownHeaders.toString()) ? "" : ", " + unknownHeaders.toString()));
            PMS.get().setRendererFound(request.getMediaRenderer());
          }
        } else {
          if (userAgentString != null) {
            logger.debug("HTTP User-Agent: " + userAgentString);
          }
          logger.trace("Recognized media renderer: " + request.getMediaRenderer().getRendererName());
        }
      }

      if (receivedContentLength > 0) {
        char buf[] = new char[receivedContentLength];
        br.read(buf);
        if (request != null) {
          request.setTextContent(new String(buf));
        }
      }

      if (request != null) {
        logger.trace("HTTP: " + request.getArgument() + " / " + request.getLowRange() + "-" + request.getHighRange());
      }

      if (request != null) {
        request.answer(output, startStopListenerDelegate);
      }

      if (request != null && request.getInputStream() != null) {
        request.getInputStream().close();
      }
    } catch (IOException e) {
      logger.trace("Unexpected IO error: " + e.getClass().getName() + ": " + e.getMessage());
      if (request != null && request.getInputStream() != null) {
        try {
          logger.trace("Closing input stream: " + request.getInputStream());
          request.getInputStream().close();
        } catch (IOException e1) {
          logger.error("Error closing input stream", e1);
        }
      }
    } finally {
      try {
        PMS.get().getRegistry().reenableGoToSleep();
        output.close();
        br.close();
        socket.close();
      } catch (IOException e) {
        logger.error("Error closing connection: ", e);
      }

      startStopListenerDelegate.stop();
      logger.trace("Close connection");
    }
  }
View Full Code Here

TOP

Related Classes of net.pms.external.StartStopListenerDelegate

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.