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;
}