Menu

Error in .SSDP.getLeaseTime(String)

2005-07-22
2013-05-02
  • Stefano Lenzi

    Stefano Lenzi - 2005-07-22

    The method org.cybergarage.upnp.ssdp.SSDP.getLeaseTime(String cacheCont)
    fail to return the right value if the cacheCont contain whitespace after the equal charcter.

    The fixed method is:
    int equIdx = cacheCont.indexOf('=');
    int mx = 0;
    try {
       String mxStr = new String(cacheCont.getBytes(), equIdx+1, cacheCont.length() - (equIdx+1)).trim();
       mx = Integer.parseInt(mxStr);
    }
    catch (Exception e) {}
    return mx;

    I found the error using our OSGi Base Driver with the Philips Media Manager

     
    • Mikael

      Mikael - 2005-07-22

      Not only that. According to HTTP spec cache control header may contain other properties beside the max-age property (which is the lease time in this context). These properties (keyword/value pairs) may come in any order and are separated by a comma from each other. Therefore my version of SSDP.getLeaseTime() which I have sent to Satoshi is:

          public final static int getLeaseTime(String cacheCont)
          {
      /*
      *         Search for max-age keyword instead of equals sign
      *         Found value of max-age ends at next comma or end of string
      */
              int mx = 0;
              int maxAgeIdx = cacheCont.indexOf("max-age");
              if (maxAgeIdx >= 0) {
                  int begIdx = maxAgeIdx + 8;
                  int endIdx = cacheCont.indexOf(',',begIdx);
                  if (endIdx < 0) endIdx = cacheCont.length();
                  try {
                      String mxStr = cacheCont.substring (begIdx,endIdx);
                      mx = Integer.parseInt(mxStr);
                  } catch (Exception e) {
                      Debug.warning (e);
                  }
              }
              return mx;
          }

      Zyxel Zywall IGD requires this.

       
    • Stefano Lenzi

      Stefano Lenzi - 2005-07-22

      You are right, but even your solution have the same trouble with whitespace. I think that the final solution may be:

      public final static int getLeaseTime(String cacheCont){
          int mx = 0;
          int maxAgeIdx = cacheCont.indexOf("=");
          if (maxAgeIdx >= 0) {
              int endIdx = cacheCont.indexOf(',',maxAgeIdx);
              if (endIdx < 0)
                  endIdx = cacheCont.length();
              try {
                  String mxStr = cacheCont.substring (maxAgeIdx+1,endIdx).trim();
                  mx = Integer.parseInt(mxStr);
              } catch (Exception e) {
                  Debug.warning (e);
              }
          }       
          return mx;
      }

       
      • Mikael

        Mikael - 2005-07-22

        You are right concerning white space. I wasnt aware that Integer.parseInt() cannot handle leading (and trailing) white spaces. However in your code you are still looking for equal sign. There is no guarantee that the first equal sign found belongs to max-age property. It could be some other property encoded before max-age within cache control header. If you search for max-age string and then jump one character forward (equal sign) and then trim and parse following string up to comma or end then it will be much more robust. In my code replace statement:

        mx = Integer.parseInt(mxStr);

        with

        mx = Integer.parseInt(mxStr.trim());

        Robust programming is a way to deal with this imperfect real world we are all living in.

         
    • Stefano Lenzi

      Stefano Lenzi - 2005-07-22

      I understood that other directive may follow max-age separated by comma, but now reading even the RFC I have understood what you mean.
      Anyway the problem with your approch is that the Whitespace may occur between "max-age" and "=" and "number"
      so I think that we have to do use a metho like this:
      public final static int getLeaseTime(String cacheCont){
          /*
           * Search for max-age keyword instead of equals sign Found value of
           * max-age ends at next comma or end of string
           */
          int mx = 0;
          int maxAgeIdx = cacheCont.indexOf("max-age"); 
          if (maxAgeIdx >= 0) {
              int endIdx = cacheCont.indexOf(',',maxAgeIdx);
              if (endIdx < 0)
                  endIdx = cacheCont.length();
              try {
                  maxAgeIdx = cacheCont.indexOf("=",maxAgeIdx);
                  String mxStr = cacheCont.substring(maxAgeIdx+1,endIdx).trim();
                  mx = Integer.parseInt(mxStr);
              } catch (Exception e) {
                  Debug.warning (e);
              }
          }       
          return mx;
      }

       
    • Satoshi Konno

      Satoshi Konno - 2005-08-03

      Hi Stefano and Mikael,

      I understood your suggestions to read HTTP specification.

      I added the changes to my latest package, and
      it will be release with the next package.

      I am sorry to late. Thanks for your suggestions :-)

       

Log in to post a comment.

MongoDB Logo MongoDB