Lots of changes, but notably:

* MiniDLNA can now pass the DLNA Conformance Test!
 * Dependence on libdlna has been removed, and the ffmpeg libs are used directly.
 * Lots of unused code has been cleaned up.
 * File transfers will now be forked off into a new process, so as not to tie up the server when sending data.
This commit is contained in:
Justin Maggard
2009-01-22 00:25:20 +00:00
parent 9867def383
commit 74d73037d0
25 changed files with 769 additions and 608 deletions

View File

@ -367,25 +367,6 @@ findendheaders(const char * s, int len)
return NULL;
}
#ifdef HAS_DUMMY_SERVICE
static void
sendDummyDesc(struct upnphttp * h)
{
static const char xml_desc[] = "<?xml version=\"1.0\"?>\r\n"
"<scpd xmlns=\"urn:schemas-upnp-org:service-1-0\">"
" <specVersion>"
" <major>1</major>"
" <minor>0</minor>"
" </specVersion>"
" <actionList />"
" <serviceStateTable />"
"</scpd>\r\n";
BuildResp_upnphttp(h, xml_desc, sizeof(xml_desc)-1);
SendResp_upnphttp(h);
CloseSocket_upnphttp(h);
}
#endif
/* Sends the description generated by the parameter */
static void
sendXMLdesc(struct upnphttp * h, char * (f)(int *))
@ -551,17 +532,31 @@ ProcessHttpQuery_upnphttp(struct upnphttp * h)
HttpVer[i] = '\0';
syslog(LOG_INFO, "HTTP REQUEST : %s %s (%s)",
HttpCommand, HttpUrl, HttpVer);
//DEBUG printf("HTTP REQUEST:\n%s\n", h->req_buf);
//DEBUG printf("HTTP REQUEST:\n%.*s\n", h->req_buflen, h->req_buf);
ParseHttpHeaders(h);
if( (h->reqflags & FLAG_CHUNKED) && (h->req_chunklen > (h->req_buflen - h->req_contentoff) || h->req_chunklen < 0) )
/* see if we need to wait for remaining data */
if( (h->reqflags & FLAG_CHUNKED) )
{
/* waiting for remaining data */
printf("*** %d < %d\n", (h->req_buflen - h->req_contentoff), h->req_contentlen);
printf("Chunked request [%ld]. Need more input.\n", h->req_chunklen);
char * chunkstart = h->req_buf+h->req_contentoff;
char * numstart;
h->state = 2;
while( h->req_chunklen )
{
if( chunkstart >= (h->req_buf+h->req_buflen) )
return;
numstart = chunkstart+h->req_chunklen+2;
h->req_chunklen = strtol(numstart, &chunkstart, 16);
if( !h->req_chunklen && (chunkstart == numstart) )
{
printf("Chunked request needs more input.\n");
return;
}
chunkstart = chunkstart+2;
}
h->state = 100;
}
else if(strcmp("POST", HttpCommand) == 0)
if(strcmp("POST", HttpCommand) == 0)
{
h->req_command = EPost;
ProcessHTTPPOST_upnphttp(h);
@ -602,12 +597,6 @@ ProcessHttpQuery_upnphttp(struct upnphttp * h)
{
sendXMLdesc(h, genX_MS_MediaReceiverRegistrar);
}
#ifdef HAS_DUMMY_SERVICE
else if(strcmp(DUMMY_PATH, HttpUrl) == 0)
{
sendDummyDesc(h);
}
#endif
else if(strncmp(HttpUrl, "/MediaItems/", 12) == 0)
{
SendResp_dlnafile(h, HttpUrl+12);
@ -864,6 +853,7 @@ SendResp_thumbnail(struct upnphttp * h, char * object)
char header[1500];
char sql_buf[256];
char **result;
int rows;
char date[30];
time_t curtime = time(NULL);
int n;
@ -879,8 +869,14 @@ SendResp_thumbnail(struct upnphttp * h, char * object)
return;
}
sprintf(sql_buf, "SELECT PATH from OBJECTS where OBJECT_ID = '%s'", object);
sqlite3_get_table(db, sql_buf, &result, 0, 0, 0);
sprintf(sql_buf, "SELECT d.PATH from OBJECTS o left join DETAILS d on (d.ID = o.DETAIL_ID) where OBJECT_ID = '%s'", object);
sqlite3_get_table(db, sql_buf, &result, &rows, 0, 0);
if( !rows )
{
syslog(LOG_NOTICE, "%s not found, responding ERROR 404", object);
Send404(h);
goto error;
}
printf("Serving up thumbnail for ObjectId: %s [%s]\n", object, result[1]);
if( access(result[1], F_OK) == 0 )
@ -976,7 +972,7 @@ SendResp_resizedimg(struct upnphttp * h, char * object)
return;
}
sprintf(sql_buf, "SELECT o.PATH, d.WIDTH, d.HEIGHT from OBJECTS o left join DETAILS d on (d.ID = o.DETAIL_ID) where OBJECT_ID = '%s'", object);
sprintf(sql_buf, "SELECT d.PATH, d.WIDTH, d.HEIGHT from OBJECTS o left join DETAILS d on (d.ID = o.DETAIL_ID) where OBJECT_ID = '%s'", object);
sqlite3_get_table(db, sql_buf, &result, 0, 0, 0);
printf("Serving up resized image for ObjectId: %s [%s]\n", object, result[1]);
@ -1073,17 +1069,26 @@ SendResp_dlnafile(struct upnphttp * h, char * object)
time_t curtime = time(NULL);
off_t total, send_size;
char *path, *mime, *dlna;
#if USE_FORK
pid_t newpid = 0;
#endif
memset(header, 0, 1500);
sprintf(sql_buf, "SELECT o.PATH, d.MIME, d.DLNA_PN from OBJECTS o left join DETAILS d on (d.ID = o.DETAIL_ID) where OBJECT_ID = '%s'", object);
sprintf(sql_buf, "SELECT d.PATH, d.MIME, d.DLNA_PN from OBJECTS o left join DETAILS d on (d.ID = o.DETAIL_ID) where OBJECT_ID = '%s'", object);
sqlite3_get_table(db, sql_buf, &result, &rows, 0, 0);
if( !rows )
{
syslog(LOG_NOTICE, "%s not found, responding ERROR 404", object);
Send404(h);
goto error;
sqlite3_free_table(result);
return;
}
#if USE_FORK
newpid = fork();
if( newpid )
return;
#endif
path = result[3];
mime = result[4];
@ -1186,8 +1191,8 @@ SendResp_dlnafile(struct upnphttp * h, char * object)
}
else //if( h->reqflags & FLAG_XFERINTERACTIVE )
{
if( (strncmp(mime, "vide", 4) == 0) ||
(strncmp(mime, "audi", 4) == 0) )
if( (strncmp(mime, "video", 5) == 0) ||
(strncmp(mime, "audio", 5) == 0) )
strcat(header, "transferMode.dlna.org: Streaming\r\n");
else
strcat(header, "transferMode.dlna.org: Interactive\r\n");
@ -1240,4 +1245,7 @@ SendResp_dlnafile(struct upnphttp * h, char * object)
}
error:
sqlite3_free_table(result);
#if USE_FORK
_exit(0);
#endif
}