Fix up a few conformance issues with latest testing tools.
This commit is contained in:
parent
8d6ce5e8b5
commit
0700cf9774
@ -388,6 +388,11 @@ ParseHttpHeaders(struct upnphttp * h)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(strncasecmp(line, "uctt.upnp.org:", 14)==0)
|
||||
{
|
||||
/* Conformance testing */
|
||||
SETFLAG(DLNA_STRICT_MASK);
|
||||
}
|
||||
}
|
||||
next_header:
|
||||
while(!(line[0] == '\r' && line[1] == '\n'))
|
||||
@ -1622,7 +1627,9 @@ SendResp_resizedimg(struct upnphttp * h, char * object)
|
||||
dstw = (((height<<10)/srch) * srcw>>10);
|
||||
}
|
||||
|
||||
if( dstw <= 640 && dsth <= 480 )
|
||||
if( dstw <= 160 && dsth <= 160 )
|
||||
strcpy(dlna_pn, "DLNA.ORG_PN=JPEG_TN;");
|
||||
else if( dstw <= 640 && dsth <= 480 )
|
||||
strcpy(dlna_pn, "DLNA.ORG_PN=JPEG_SM;");
|
||||
else if( dstw <= 1024 && dsth <= 768 )
|
||||
strcpy(dlna_pn, "DLNA.ORG_PN=JPEG_MED;");
|
||||
|
79
upnpsoap.c
79
upnpsoap.c
@ -306,15 +306,16 @@ GetCurrentConnectionInfo(struct upnphttp * h, const char * action)
|
||||
#define FILTER_RES_RESOLUTION 0x00000400
|
||||
#define FILTER_RES_SAMPLEFREQUENCY 0x00000800
|
||||
#define FILTER_RES_SIZE 0x00001000
|
||||
#define FILTER_UPNP_ACTOR 0x00002000
|
||||
#define FILTER_UPNP_ALBUM 0x00004000
|
||||
#define FILTER_UPNP_ALBUMARTURI 0x00008000
|
||||
#define FILTER_UPNP_ALBUMARTURI_DLNA_PROFILEID 0x00010000
|
||||
#define FILTER_UPNP_ARTIST 0x00020000
|
||||
#define FILTER_UPNP_GENRE 0x00040000
|
||||
#define FILTER_UPNP_ORIGINALTRACKNUMBER 0x00080000
|
||||
#define FILTER_UPNP_SEARCHCLASS 0x00100000
|
||||
#define FILTER_UPNP_STORAGEUSED 0x00200000
|
||||
#define FILTER_SEARCHABLE 0x00002000
|
||||
#define FILTER_UPNP_ACTOR 0x00004000
|
||||
#define FILTER_UPNP_ALBUM 0x00008000
|
||||
#define FILTER_UPNP_ALBUMARTURI 0x00010000
|
||||
#define FILTER_UPNP_ALBUMARTURI_DLNA_PROFILEID 0x00020000
|
||||
#define FILTER_UPNP_ARTIST 0x00040000
|
||||
#define FILTER_UPNP_GENRE 0x00080000
|
||||
#define FILTER_UPNP_ORIGINALTRACKNUMBER 0x00100000
|
||||
#define FILTER_UPNP_SEARCHCLASS 0x00200000
|
||||
#define FILTER_UPNP_STORAGEUSED 0x00400000
|
||||
/* Vendor-specific filter flags */
|
||||
#define FILTER_SEC_CAPTION_INFO_EX 0x01000000
|
||||
#define FILTER_SEC_DCM_INFO 0x02000000
|
||||
@ -345,6 +346,10 @@ set_filter_flags(char *filter, struct upnphttp *h)
|
||||
{
|
||||
flags |= FILTER_CHILDCOUNT;
|
||||
}
|
||||
else if( strcmp(item, "@searchable") == 0 )
|
||||
{
|
||||
flags |= FILTER_SEARCHABLE;
|
||||
}
|
||||
else if( strcmp(item, "dc:creator") == 0 )
|
||||
{
|
||||
flags |= FILTER_DC_CREATOR;
|
||||
@ -989,30 +994,27 @@ callback(void *args, int argc, char **argv, char **azColName)
|
||||
else if( strncmp(class, "container", 9) == 0 )
|
||||
{
|
||||
ret = strcatf(str, "<container id=\"%s\" parentID=\"%s\" restricted=\"1\" ", id, parent);
|
||||
if( passed_args->filter & FILTER_CHILDCOUNT )
|
||||
{
|
||||
if( passed_args->filter & FILTER_SEARCHABLE ) {
|
||||
ret = strcatf(str, "searchable=\"1\" ");
|
||||
}
|
||||
if( passed_args->filter & FILTER_CHILDCOUNT ) {
|
||||
int children;
|
||||
ret = sql_get_int_field(db, "SELECT count(*) from OBJECTS where PARENT_ID = '%s';", id);
|
||||
children = (ret > 0) ? ret : 0;
|
||||
ret = strcatf(str, "childCount=\"%d\"", children);
|
||||
}
|
||||
/* If the client calls for BrowseMetadata on root, we have to include our "upnp:searchClass"'s, unless they're filtered out */
|
||||
if( (passed_args->requested == 1) && (strcmp(id, "0") == 0) )
|
||||
{
|
||||
ret = strcatf(str, " searchable=\"1\"");
|
||||
if( passed_args->filter & FILTER_UPNP_SEARCHCLASS )
|
||||
{
|
||||
ret = strcatf(str, ">"
|
||||
"<upnp:searchClass includeDerived=\"1\">object.item.audioItem</upnp:searchClass>"
|
||||
"<upnp:searchClass includeDerived=\"1\">object.item.imageItem</upnp:searchClass>"
|
||||
"<upnp:searchClass includeDerived=\"1\">object.item.videoItem</upnp:searchClass");
|
||||
}
|
||||
if( passed_args->requested == 1 && strcmp(id, "0") == 0 && (passed_args->filter & FILTER_UPNP_SEARCHCLASS) ) {
|
||||
ret = strcatf(str, ">"
|
||||
"<upnp:searchClass includeDerived=\"1\">object.item.audioItem</upnp:searchClass>"
|
||||
"<upnp:searchClass includeDerived=\"1\">object.item.imageItem</upnp:searchClass>"
|
||||
"<upnp:searchClass includeDerived=\"1\">object.item.videoItem</upnp:searchClass");
|
||||
}
|
||||
ret = strcatf(str, ">"
|
||||
"<dc:title>%s</dc:title>"
|
||||
"<upnp:class>object.%s</upnp:class>",
|
||||
title, class);
|
||||
if( (passed_args->filter & FILTER_UPNP_STORAGEUSED) && strcmp(class+10, "storageFolder") == 0 ) {
|
||||
if( (passed_args->filter & FILTER_UPNP_STORAGEUSED) || strcmp(class+10, "storageFolder") == 0 ) {
|
||||
/* TODO: Implement real folder size tracking */
|
||||
ret = strcatf(str, "<upnp:storageUsed>%s</upnp:storageUsed>", (size ? size : "-1"));
|
||||
}
|
||||
@ -1331,6 +1333,12 @@ parse_search_criteria(const char *str)
|
||||
case 'o':
|
||||
if (strncmp(s, "object.", 7) == 0)
|
||||
s += 7;
|
||||
else if (strncmp(s, "object\"", 7) == 0 ||
|
||||
strncmp(s, "object"", 12) == 0)
|
||||
{
|
||||
s += 6;
|
||||
continue;
|
||||
}
|
||||
default:
|
||||
charcat(&criteria, *s);
|
||||
break;
|
||||
@ -1498,6 +1506,16 @@ parse_search_criteria(const char *str)
|
||||
else
|
||||
charcat(&criteria, *s);
|
||||
break;
|
||||
case '(':
|
||||
if (s > str && !isspace(s[-1]))
|
||||
charcat(&criteria, ' ');
|
||||
charcat(&criteria, *s);
|
||||
break;
|
||||
case ')':
|
||||
charcat(&criteria, *s);
|
||||
if (!isspace(s[1]))
|
||||
charcat(&criteria, ' ');
|
||||
break;
|
||||
default:
|
||||
charcat(&criteria, *s);
|
||||
break;
|
||||
@ -1526,7 +1544,7 @@ SearchContentDirectory(struct upnphttp * h, const char * action)
|
||||
int totalMatches;
|
||||
int ret;
|
||||
char *ContainerID, *Filter, *SearchCriteria, *SortCriteria;
|
||||
char *orderBy = NULL;
|
||||
char *orderBy = NULL, *where = NULL;
|
||||
char groupBy[] = "group by DETAIL_ID";
|
||||
struct NameValueParserData data;
|
||||
int RequestedCount = 0;
|
||||
@ -1604,8 +1622,11 @@ SearchContentDirectory(struct upnphttp * h, const char * action)
|
||||
else if( strcmp(ContainerID, MUSIC_ALL_ID) == 0 )
|
||||
groupBy[0] = '\0';
|
||||
|
||||
SearchCriteria = parse_search_criteria(SearchCriteria);
|
||||
DPRINTF(E_DEBUG, L_HTTP, "Translated SearchCriteria: %s\n", SearchCriteria);
|
||||
if( GETFLAG(DLNA_STRICT_MASK) )
|
||||
groupBy[0] = '\0';
|
||||
|
||||
where = parse_search_criteria(SearchCriteria);
|
||||
DPRINTF(E_DEBUG, L_HTTP, "Translated SearchCriteria: %s\n", where);
|
||||
|
||||
totalMatches = sql_get_int_field(db, "SELECT (select count(distinct DETAIL_ID)"
|
||||
" from OBJECTS o left join DETAILS d on (o.DETAIL_ID = d.ID)"
|
||||
@ -1613,7 +1634,7 @@ SearchContentDirectory(struct upnphttp * h, const char * action)
|
||||
" + "
|
||||
"(select count(*) from OBJECTS o left join DETAILS d on (o.DETAIL_ID = d.ID)"
|
||||
" where (OBJECT_ID = '%q') and (%s))",
|
||||
ContainerID, SearchCriteria, ContainerID, SearchCriteria);
|
||||
ContainerID, where, ContainerID, where);
|
||||
if( totalMatches < 0 )
|
||||
{
|
||||
/* Must be invalid SQL, so most likely bad or unhandled search criteria. */
|
||||
@ -1648,11 +1669,11 @@ SearchContentDirectory(struct upnphttp * h, const char * action)
|
||||
" where OBJECT_ID glob '%q$*' and (%s) %s "
|
||||
"%z %s"
|
||||
" limit %d, %d",
|
||||
ContainerID, SearchCriteria, groupBy,
|
||||
ContainerID, where, groupBy,
|
||||
(*ContainerID == '*') ? NULL :
|
||||
sqlite3_mprintf("UNION ALL " SELECT_COLUMNS
|
||||
"from OBJECTS o left join DETAILS d on (d.ID = o.DETAIL_ID)"
|
||||
" where OBJECT_ID = '%q' and (%s) ", ContainerID, SearchCriteria),
|
||||
" where OBJECT_ID = '%q' and (%s) ", ContainerID, where),
|
||||
orderBy, StartingIndex, RequestedCount);
|
||||
DPRINTF(E_DEBUG, L_HTTP, "Search SQL: %s\n", sql);
|
||||
ret = sqlite3_exec(db, sql, callback, (void *) &args, &zErrMsg);
|
||||
@ -1674,7 +1695,7 @@ search_error:
|
||||
if( args.flags & FLAG_FREE_OBJECT_ID )
|
||||
sqlite3_free(ContainerID);
|
||||
free(orderBy);
|
||||
free(SearchCriteria);
|
||||
free(where);
|
||||
free(str.data);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user