void httpd_parse_useragent()

in AZ3166/src/cores/arduino/httpserver/http_parse.c [163:299]


void httpd_parse_useragent(char *hdrline, httpd_useragent_t * agent)
{
  char *token, *product, *p, *version, *v, *comment, *dummy;
  int len;
  
  /* Inpsect the first token. */
  hdrline = __httpd_parse_useragent(hdrline, &product,
                                    &version, &comment);
  if (!product)
    goto done;
  
  if (strcmp(product, "Mozilla") == 0) {
    if (comment && strncmp(comment, MOZ_COMPATIBLE, sizeof(MOZ_COMPATIBLE) - 1) == 0) {
      /* If this is a "mozilla compatible" browser, parse it
      * and be done. */
      token = strstr(comment, " ") + 1;
      token = __httpd_parse_useragent(token, &product,
                                      &version, &comment);
      /* Sometimes when the product and version are found
      * within a comment, the version is separated by a space
      * from the product, not the '/'.  This appears as the
      * next product to our token parser.  If it is numeric,
      * assume it's the version.
      */
      if (product && !version && token) {
        token = __httpd_parse_useragent(token, &version,
                                        &dummy,
                                        &comment);
        if (*version < '0' || *version > '9')
          version = 0;
      }
      
      /* Now, some browsers report Mozilla compatible MSIE,
      * but are actually something else!  Keep parsing these
      * ones.  Otherwise, we're done.
      */
      if (strcmp(product, "MSIE") != 0)
        goto done;
    }
    
    if (!hdrline)
      goto done;
    
    /* If this is not a "mozilla compatible" browser, step through
    * the rest of the product/version (comment) tokens and try to
    * figure out what it is.
    */
    while (1) {
      
      hdrline = __httpd_parse_useragent(hdrline, &p,
                                        &v, &comment);
      if (!p ||
          strcmp(p, "Galeon") == 0 ||
            strcmp(p, "safari") == 0 ||
              strcmp(p, "Safari") == 0 ||
                strcmp(p, "Shiira") == 0 ||
                  strcmp(p, "OmniWeb") == 0 ||
                    strcmp(p, "Firefox") == 0 ||
                      strcmp(p, "Camino") == 0 ||
                        strcmp(p, "Phoenix") == 0 ||
                          strcmp(p, "Netscape6") == 0 ||
			    strcmp(p, "Netscape") == 0 ||
                              strcmp(p, "NetFront") == 0 ||
                                strcmp(p, "WebTV") == 0) {
                                  product = p;
                                  version = v;
                                  goto done;
                                } else if (strcmp(p, "Opera") == 0) {
                                  /* Many Opera browsers say "Opera VER" instead
                                  * of Opera/VER */
                                  product = p;
                                  version = v;
                                  if (v == 0 && hdrline) {
                                    hdrline =
                                      __httpd_parse_useragent(hdrline,
                                                              &version,
                                                              &dummy,
                                                              &comment);
                                    if (*version < '0' || *version > '9')
                                      version = 0;
                                  }
                                  goto done;
                                }
      
      if (!hdrline)
        goto done;
    }
  } else if ((strcmp(product, "MSIE") == 0 ||
              strcmp(product, "Netscape")	== 0) &&
             version == 0 && hdrline) {
               /* Some MSIE and Netscape browsers report Mozilla compatbile.
               * Others say PROD/VER.  Others say PROD VER.
               */
               hdrline = __httpd_parse_useragent(hdrline, &version,
                                                 &dummy, &comment);
               if (*version < '0' || *version > '9')
                 version = 0;
             }
  
done:
  if (product) {
    len = strlen(product);
    if (product[len - 1] == ';')
      product[len - 1] = 0;
    strncpy(agent->product, product, HTTPD_MAX_VAL_LENGTH);
    
    /* Sometimes if there's a comment but no version, the first
    * token in the comment is the version.
    */
    if (comment && !version && *comment >= '0' && *comment <= '9') {
      version = comment;
      while (*comment != ' ' && *comment != 0)
        comment++;
      *comment = 0;
    }
  } else
    strncpy(agent->product, "unknown", HTTPD_MAX_VAL_LENGTH);
  
  agent->product[HTTPD_MAX_VAL_LENGTH] = 0;
  
  if (version) {
    len = strlen(version);
    if (version[len - 1] == ';')
      version[len - 1] = 0;
    /* Truncate version strings with unexpected chars */
    dummy = strstr(version, ",");
    if (dummy)
      *dummy = 0;
    dummy = strstr(version, "+");
    if (dummy)
      *dummy = 0;
    strncpy(agent->version, version, HTTPD_MAX_VAL_LENGTH);
  } else
    memset(agent->version, 0, HTTPD_MAX_VAL_LENGTH + 1);
  
  agent->version[HTTPD_MAX_VAL_LENGTH] = 0;
}