upnpttp: factor out basic header generation
This commit is contained in:
parent
04c8730dae
commit
75a697a671
185
upnphttp.c
185
upnphttp.c
@ -80,12 +80,13 @@
|
||||
#include "tivo_commands.h"
|
||||
#include "clients.h"
|
||||
#include "process.h"
|
||||
|
||||
#include "sendfile.h"
|
||||
|
||||
#define MAX_BUFFER_SIZE 2147483647
|
||||
#define MIN_BUFFER_SIZE 65536
|
||||
|
||||
#define INIT_STR(s, d) { s.data = d; s.size = sizeof(d); s.off = 0; }
|
||||
|
||||
#include "icons.c"
|
||||
|
||||
enum event_type {
|
||||
@ -592,9 +593,7 @@ SendResp_presentation(struct upnphttp * h)
|
||||
char body[4096];
|
||||
int a, v, p, i;
|
||||
|
||||
str.data = body;
|
||||
str.size = sizeof(body);
|
||||
str.off = 0;
|
||||
INIT_STR(str, body);
|
||||
|
||||
h->respflags = FLAG_HTML;
|
||||
|
||||
@ -1181,9 +1180,6 @@ BuildHeader_upnphttp(struct upnphttp * h, int respcode,
|
||||
strftime(date, 30,"%a, %d %b %Y %H:%M:%S GMT" , gmtime(&curtime));
|
||||
strcatf(&res, "Date: %s\r\n", date);
|
||||
strcatf(&res, "EXT:\r\n");
|
||||
#if 0 // DLNA
|
||||
strcatf(&res, "contentFeatures.dlna.org: \r\n");
|
||||
#endif
|
||||
strcatf(&res, "\r\n");
|
||||
h->res_buflen = res.off;
|
||||
if(h->res_buf_alloclen < (h->res_buflen + bodylen))
|
||||
@ -1313,15 +1309,33 @@ send_file(struct upnphttp * h, int sendfd, off_t offset, off_t end_offset)
|
||||
free(buf);
|
||||
}
|
||||
|
||||
static void
|
||||
start_dlna_header(struct string_s *str, int respcode, const char *tmode, const char *mime)
|
||||
{
|
||||
char date[30];
|
||||
time_t now;
|
||||
|
||||
now = time(NULL);
|
||||
strftime(date, sizeof(date),"%a, %d %b %Y %H:%M:%S GMT" , gmtime(&now));
|
||||
strcatf(str, "HTTP/1.1 %d OK\r\n"
|
||||
"Connection: close\r\n"
|
||||
"Date: %s\r\n"
|
||||
"Server: " MINIDLNA_SERVER_STRING "\r\n"
|
||||
"EXT:\r\n"
|
||||
"realTimeInfo.dlna.org: DLNA.ORG_TLAG=*\r\n"
|
||||
"transferMode.dlna.org: %s\r\n"
|
||||
"Content-Type: %s\r\n",
|
||||
respcode, date, tmode, mime);
|
||||
}
|
||||
|
||||
static void
|
||||
SendResp_icon(struct upnphttp * h, char * icon)
|
||||
{
|
||||
char header[512];
|
||||
char mime[12] = "image/";
|
||||
char date[30];
|
||||
char *data;
|
||||
int size, ret;
|
||||
time_t curtime = time(NULL);
|
||||
int size;
|
||||
struct string_s str;
|
||||
|
||||
if( strcmp(icon, "sm.png") == 0 )
|
||||
{
|
||||
@ -1358,16 +1372,12 @@ SendResp_icon(struct upnphttp * h, char * icon)
|
||||
return;
|
||||
}
|
||||
|
||||
strftime(date, 30,"%a, %d %b %Y %H:%M:%S GMT" , gmtime(&curtime));
|
||||
ret = snprintf(header, sizeof(header), "HTTP/1.1 200 OK\r\n"
|
||||
"Content-Type: %s\r\n"
|
||||
"Content-Length: %d\r\n"
|
||||
"Connection: close\r\n"
|
||||
"Date: %s\r\n"
|
||||
"Server: " MINIDLNA_SERVER_STRING "\r\n\r\n",
|
||||
mime, size, date);
|
||||
INIT_STR(str, header);
|
||||
|
||||
if( send_data(h, header, ret, MSG_MORE) == 0 )
|
||||
start_dlna_header(&str, 200, "Interactive", mime);
|
||||
strcatf(&str, "Content-Length: %d\r\n\r\n", size);
|
||||
|
||||
if( send_data(h, str.data, str.off, MSG_MORE) == 0 )
|
||||
{
|
||||
if( h->req_command != EHead )
|
||||
send_data(h, data, size, 0);
|
||||
@ -1380,11 +1390,10 @@ SendResp_albumArt(struct upnphttp * h, char * object)
|
||||
{
|
||||
char header[512];
|
||||
char *path;
|
||||
char date[30];
|
||||
time_t curtime = time(NULL);
|
||||
off_t size;
|
||||
long long id;
|
||||
int fd, ret;
|
||||
int fd;
|
||||
struct string_s str;
|
||||
|
||||
if( h->reqflags & (FLAG_XFERSTREAMING|FLAG_RANGE) )
|
||||
{
|
||||
@ -1415,20 +1424,14 @@ SendResp_albumArt(struct upnphttp * h, char * object)
|
||||
size = lseek(fd, 0, SEEK_END);
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
|
||||
strftime(date, 30,"%a, %d %b %Y %H:%M:%S GMT" , gmtime(&curtime));
|
||||
ret = snprintf(header, sizeof(header), "HTTP/1.1 200 OK\r\n"
|
||||
"Content-Type: image/jpeg\r\n"
|
||||
"Content-Length: %jd\r\n"
|
||||
"Connection: close\r\n"
|
||||
"Date: %s\r\n"
|
||||
"EXT:\r\n"
|
||||
"realTimeInfo.dlna.org: DLNA.ORG_TLAG=*\r\n"
|
||||
"contentFeatures.dlna.org: DLNA.ORG_PN=JPEG_TN\r\n"
|
||||
"Server: " MINIDLNA_SERVER_STRING "\r\n"
|
||||
"transferMode.dlna.org: Interactive\r\n\r\n",
|
||||
(intmax_t)size, date);
|
||||
INIT_STR(str, header);
|
||||
|
||||
if( send_data(h, header, ret, MSG_MORE) == 0 )
|
||||
start_dlna_header(&str, 200, "Interactive", "image/jpeg");
|
||||
strcatf(&str, "Content-Length: %jd\r\n"
|
||||
"contentFeatures.dlna.org: DLNA.ORG_PN=JPEG_TN\r\n\r\n",
|
||||
(intmax_t)size);
|
||||
|
||||
if( send_data(h, str.data, str.off, MSG_MORE) == 0 )
|
||||
{
|
||||
if( h->req_command != EHead )
|
||||
send_file(h, fd, 0, size-1);
|
||||
@ -1442,11 +1445,10 @@ SendResp_caption(struct upnphttp * h, char * object)
|
||||
{
|
||||
char header[512];
|
||||
char *path;
|
||||
char date[30];
|
||||
time_t curtime = time(NULL);
|
||||
off_t size;
|
||||
long long id;
|
||||
int fd, ret;
|
||||
int fd;
|
||||
struct string_s str;
|
||||
|
||||
id = strtoll(object, NULL, 10);
|
||||
|
||||
@ -1470,17 +1472,12 @@ SendResp_caption(struct upnphttp * h, char * object)
|
||||
size = lseek(fd, 0, SEEK_END);
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
|
||||
strftime(date, 30,"%a, %d %b %Y %H:%M:%S GMT" , gmtime(&curtime));
|
||||
ret = snprintf(header, sizeof(header), "HTTP/1.1 200 OK\r\n"
|
||||
"Content-Type: smi/caption\r\n"
|
||||
"Content-Length: %jd\r\n"
|
||||
"Connection: close\r\n"
|
||||
"Date: %s\r\n"
|
||||
"EXT:\r\n"
|
||||
"Server: " MINIDLNA_SERVER_STRING "\r\n\r\n",
|
||||
(intmax_t)size, date);
|
||||
INIT_STR(str, header);
|
||||
|
||||
if( send_data(h, header, ret, MSG_MORE) == 0 )
|
||||
start_dlna_header(&str, 200, "Interactive", "smi/caption");
|
||||
strcatf(&str, "Content-Length: %jd\r\n\r\n", (intmax_t)size);
|
||||
|
||||
if( send_data(h, str.data, str.off, MSG_MORE) == 0 )
|
||||
{
|
||||
if( h->req_command != EHead )
|
||||
send_file(h, fd, 0, size-1);
|
||||
@ -1494,12 +1491,10 @@ SendResp_thumbnail(struct upnphttp * h, char * object)
|
||||
{
|
||||
char header[512];
|
||||
char *path;
|
||||
char date[30];
|
||||
time_t curtime = time(NULL);
|
||||
long long id;
|
||||
int ret;
|
||||
ExifData *ed;
|
||||
ExifLoader *l;
|
||||
struct string_s str;
|
||||
|
||||
if( h->reqflags & (FLAG_XFERSTREAMING|FLAG_RANGE) )
|
||||
{
|
||||
@ -1539,20 +1534,15 @@ SendResp_thumbnail(struct upnphttp * h, char * object)
|
||||
exif_data_unref(ed);
|
||||
return;
|
||||
}
|
||||
strftime(date, 30,"%a, %d %b %Y %H:%M:%S GMT" , gmtime(&curtime));
|
||||
ret = snprintf(header, sizeof(header), "HTTP/1.1 200 OK\r\n"
|
||||
"Content-Type: image/jpeg\r\n"
|
||||
"Content-Length: %jd\r\n"
|
||||
"Connection: close\r\n"
|
||||
"Date: %s\r\n"
|
||||
"EXT:\r\n"
|
||||
"realTimeInfo.dlna.org: DLNA.ORG_TLAG=*\r\n"
|
||||
"contentFeatures.dlna.org: DLNA.ORG_PN=JPEG_TN;DLNA.ORG_CI=1\r\n"
|
||||
"Server: " MINIDLNA_SERVER_STRING "\r\n"
|
||||
"transferMode.dlna.org: Interactive\r\n\r\n",
|
||||
(intmax_t)ed->size, date);
|
||||
|
||||
if( send_data(h, header, ret, MSG_MORE) == 0 )
|
||||
INIT_STR(str, header);
|
||||
|
||||
start_dlna_header(&str, 200, "Interactive", "image/jpeg");
|
||||
strcatf(&str, "Content-Length: %jd\r\n"
|
||||
"contentFeatures.dlna.org: DLNA.ORG_PN=JPEG_TN;DLNA.ORG_CI=1\r\n\r\n",
|
||||
(intmax_t)ed->size);
|
||||
|
||||
if( send_data(h, str.data, str.off, MSG_MORE) == 0 )
|
||||
{
|
||||
if( h->req_command != EHead )
|
||||
send_data(h, (char *)ed->data, ed->size, 0);
|
||||
@ -1568,10 +1558,8 @@ SendResp_resizedimg(struct upnphttp * h, char * object)
|
||||
char buf[128];
|
||||
struct string_s str;
|
||||
char **result;
|
||||
char date[30];
|
||||
char dlna_pn[22];
|
||||
uint32_t dlna_flags = DLNA_FLAG_DLNA_V1_5|DLNA_FLAG_HTTP_STALLING|DLNA_FLAG_TM_B|DLNA_FLAG_TM_I;
|
||||
time_t curtime = time(NULL);
|
||||
int width=640, height=480, dstw, dsth, size;
|
||||
int srcw, srch;
|
||||
unsigned char * data = NULL;
|
||||
@ -1586,6 +1574,7 @@ SendResp_resizedimg(struct upnphttp * h, char * object)
|
||||
int rows=0, chunked, ret;
|
||||
image_s *imsrc = NULL, *imdst = NULL;
|
||||
int scale = 1;
|
||||
const char *tmode;
|
||||
|
||||
id = strtoll(object, &saveptr, 10);
|
||||
snprintf(buf, sizeof(buf), "SELECT PATH, RESOLUTION, ROTATION from DETAILS where ID = '%lld'", (long long)id);
|
||||
@ -1706,26 +1695,17 @@ SendResp_resizedimg(struct upnphttp * h, char * object)
|
||||
else if( srcw>>2 >= dstw && srch>>2 >= dsth )
|
||||
scale = 2;
|
||||
|
||||
str.data = header;
|
||||
str.size = sizeof(header);
|
||||
str.off = 0;
|
||||
INIT_STR(str, header);
|
||||
|
||||
strftime(date, 30,"%a, %d %b %Y %H:%M:%S GMT" , gmtime(&curtime));
|
||||
strcatf(&str, "HTTP/1.1 200 OK\r\n"
|
||||
"Content-Type: image/jpeg\r\n"
|
||||
"Connection: close\r\n"
|
||||
"Date: %s\r\n"
|
||||
"EXT:\r\n"
|
||||
"realTimeInfo.dlna.org: DLNA.ORG_TLAG=*\r\n"
|
||||
"contentFeatures.dlna.org: %sDLNA.ORG_CI=%X;DLNA.ORG_FLAGS=%08X%024X\r\n"
|
||||
"Server: " MINIDLNA_SERVER_STRING "\r\n",
|
||||
date, dlna_pn, 1, dlna_flags, 0);
|
||||
#if USE_FORK
|
||||
if( (h->reqflags & FLAG_XFERBACKGROUND) && (setpriority(PRIO_PROCESS, 0, 19) == 0) )
|
||||
strcatf(&str, "transferMode.dlna.org: Background\r\n");
|
||||
tmode = "Background";
|
||||
else
|
||||
#endif
|
||||
strcatf(&str, "transferMode.dlna.org: Interactive\r\n");
|
||||
tmode = "Interactive";
|
||||
start_dlna_header(&str, 200, tmode, "image/jpeg");
|
||||
strcatf(&str, "contentFeatures.dlna.org: %sDLNA.ORG_CI=1;DLNA.ORG_FLAGS=%08X%024X\r\n",
|
||||
dlna_pn, dlna_flags, 0);
|
||||
|
||||
if( strcmp(h->HttpVer, "HTTP/1.0") == 0 )
|
||||
{
|
||||
@ -1799,13 +1779,12 @@ SendResp_dlnafile(struct upnphttp *h, char *object)
|
||||
char buf[128];
|
||||
char **result;
|
||||
int rows, ret;
|
||||
char date[30];
|
||||
time_t curtime = time(NULL);
|
||||
off_t total, offset, size;
|
||||
int64_t id;
|
||||
int sendfh;
|
||||
uint32_t dlna_flags = DLNA_FLAG_DLNA_V1_5|DLNA_FLAG_HTTP_STALLING|DLNA_FLAG_TM_B;
|
||||
uint32_t cflags = h->req_client ? h->req_client->type->flags : 0;
|
||||
const char *tmode;
|
||||
enum client_types ctype = h->req_client ? h->req_client->type->type : 0;
|
||||
static struct { int64_t id;
|
||||
enum client_types client;
|
||||
@ -1934,14 +1913,20 @@ SendResp_dlnafile(struct upnphttp *h, char *object)
|
||||
size = lseek(sendfh, 0, SEEK_END);
|
||||
lseek(sendfh, 0, SEEK_SET);
|
||||
|
||||
str.data = header;
|
||||
str.size = sizeof(header);
|
||||
str.off = 0;
|
||||
INIT_STR(str, header);
|
||||
|
||||
#if USE_FORK
|
||||
if( (h->reqflags & FLAG_XFERBACKGROUND) && (setpriority(PRIO_PROCESS, 0, 19) == 0) )
|
||||
tmode = "Background";
|
||||
else
|
||||
#endif
|
||||
if( strncmp(last_file.mime, "image", 5) == 0 )
|
||||
tmode = "Interactive";
|
||||
else
|
||||
tmode = "Streaming";
|
||||
|
||||
start_dlna_header(&str, (h->reqflags & FLAG_RANGE ? 206 : 200), tmode, last_file.mime);
|
||||
|
||||
strcatf(&str, "HTTP/1.1 20%c OK\r\n"
|
||||
"Content-Type: %s\r\n",
|
||||
(h->reqflags & FLAG_RANGE ? '6' : '0'),
|
||||
last_file.mime);
|
||||
if( h->reqflags & FLAG_RANGE )
|
||||
{
|
||||
if( !h->req_RangeEnd || h->req_RangeEnd == size )
|
||||
@ -1976,16 +1961,6 @@ SendResp_dlnafile(struct upnphttp *h, char *object)
|
||||
strcatf(&str, "Content-Length: %jd\r\n", (intmax_t)total);
|
||||
}
|
||||
|
||||
#if USE_FORK
|
||||
if( (h->reqflags & FLAG_XFERBACKGROUND) && (setpriority(PRIO_PROCESS, 0, 19) == 0) )
|
||||
strcatf(&str, "transferMode.dlna.org: Background\r\n");
|
||||
else
|
||||
#endif
|
||||
if( strncmp(last_file.mime, "image", 5) == 0 )
|
||||
strcatf(&str, "transferMode.dlna.org: Interactive\r\n");
|
||||
else
|
||||
strcatf(&str, "transferMode.dlna.org: Streaming\r\n");
|
||||
|
||||
switch( *last_file.mime )
|
||||
{
|
||||
case 'i':
|
||||
@ -2005,15 +1980,9 @@ SendResp_dlnafile(struct upnphttp *h, char *object)
|
||||
lan_addr[h->iface].str, runtime_vars.port, (long long)id);
|
||||
}
|
||||
|
||||
strftime(date, 30,"%a, %d %b %Y %H:%M:%S GMT" , gmtime(&curtime));
|
||||
strcatf(&str, "Accept-Ranges: bytes\r\n"
|
||||
"Connection: close\r\n"
|
||||
"Date: %s\r\n"
|
||||
"EXT:\r\n"
|
||||
"realTimeInfo.dlna.org: DLNA.ORG_TLAG=*\r\n"
|
||||
"contentFeatures.dlna.org: %sDLNA.ORG_OP=%02X;DLNA.ORG_CI=%X;DLNA.ORG_FLAGS=%08X%024X\r\n"
|
||||
"Server: " MINIDLNA_SERVER_STRING "\r\n\r\n",
|
||||
date, last_file.dlna, 1, 0, dlna_flags, 0);
|
||||
"contentFeatures.dlna.org: %sDLNA.ORG_OP=%02X;DLNA.ORG_CI=%X;DLNA.ORG_FLAGS=%08X%024X\r\n\r\n",
|
||||
last_file.dlna, 1, 0, dlna_flags, 0);
|
||||
|
||||
//DEBUG DPRINTF(E_DEBUG, L_HTTP, "RESPONSE: %s\n", str.data);
|
||||
if( send_data(h, str.data, str.off, MSG_MORE) == 0 )
|
||||
|
Loading…
x
Reference in New Issue
Block a user