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:
86
upnphttp.c
86
upnphttp.c
@ -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
|
||||
}
|
||||
|
Reference in New Issue
Block a user