Implement xml output
This commit is contained in:
parent
8e6c0d2c6d
commit
cb5f0283d6
|
@ -103,6 +103,7 @@ typedef struct tag_dbqueryinfo {
|
|||
int uri_count;
|
||||
char *uri_sections[10];
|
||||
char *whereclause;
|
||||
void *output_info;
|
||||
} DBQUERYINFO;
|
||||
|
||||
typedef struct {
|
||||
|
|
488
src/dispatch.c
488
src/dispatch.c
|
@ -55,8 +55,31 @@ static void dispatch_playlists(WS_CONNINFO *pqsc, DBQUERYINFO *pqi);
|
|||
static void dispatch_items(WS_CONNINFO *pwsc, DBQUERYINFO *pqi);
|
||||
static void dispatch_logout(WS_CONNINFO *pwsc, DBQUERYINFO *pqi);
|
||||
|
||||
static int dispatch_output_start(WS_CONNINFO *pwsc, DBQUERYINFO *pqi, int content_length);
|
||||
static int dispatch_output_write(WS_CONNINFO *pwsc, DBQUERYINFO *pqi, char *block, int len);
|
||||
static int dispatch_output_end(WS_CONNINFO *pwsc, DBQUERYINFO *pqi);
|
||||
|
||||
static DAAP_ITEMS *dispatch_xml_lookup_tag(char *tag);
|
||||
static char *dispatch_xml_encode(char *original, int len);
|
||||
static int dispatch_output_xml_write(WS_CONNINFO *pwsc, DBQUERYINFO *pqi, char *block, int len);
|
||||
|
||||
|
||||
/**
|
||||
* Hold the inf for the output serializer
|
||||
*/
|
||||
typedef struct tag_xml_stack {
|
||||
char tag[5];
|
||||
int bytes_left;
|
||||
} XML_STACK;
|
||||
|
||||
typedef struct tag_output_info {
|
||||
int xml_output;
|
||||
int readable;
|
||||
int browse_response;
|
||||
int dmap_response_length;
|
||||
int stack_height;
|
||||
XML_STACK stack[10];
|
||||
} OUTPUT_INFO;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -85,6 +108,11 @@ int daap_auth(char *username, char *password) {
|
|||
return !strcasecmp(password,config.readpassword);
|
||||
}
|
||||
|
||||
/**
|
||||
* decodes the request and hands it off to the appropriate dispatcher
|
||||
*
|
||||
* \param pwsc the current web connection info
|
||||
*/
|
||||
void daap_handler(WS_CONNINFO *pwsc) {
|
||||
DBQUERYINFO *pqi;
|
||||
char *token, *string, *save;
|
||||
|
@ -185,6 +213,352 @@ void daap_handler(WS_CONNINFO *pwsc) {
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* set up whatever necessary to begin streaming the output
|
||||
* to the client.
|
||||
*
|
||||
* \param pwsc pointer to the current conninfo struct
|
||||
* \param pqi pointer to the current dbquery struct
|
||||
* \param content_length content_length (assuming dmap) of the output
|
||||
*/
|
||||
int dispatch_output_start(WS_CONNINFO *pwsc, DBQUERYINFO *pqi, int content_length) {
|
||||
OUTPUT_INFO *poi;
|
||||
|
||||
poi=(OUTPUT_INFO*)calloc(1,sizeof(OUTPUT_INFO));
|
||||
if(!poi) {
|
||||
DPRINTF(E_LOG,L_DAAP,"Malloc error in dispatch_ouput_start\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pqi->output_info = (void*) poi;
|
||||
poi->dmap_response_length = content_length;
|
||||
|
||||
if(ws_getvar(pwsc,"output")) {
|
||||
if(strcasecmp(ws_getvar(pwsc,"output"),"readable") == 0)
|
||||
poi->readable=1;
|
||||
|
||||
poi->xml_output=1;
|
||||
ws_addresponseheader(pwsc,"Content-Type","text/xml");
|
||||
ws_addresponseheader(pwsc,"Connection","Close");
|
||||
pwsc->close=1;
|
||||
ws_writefd(pwsc,"HTTP/1.1 200 OK\r\n");
|
||||
ws_emitheaders(pwsc);
|
||||
ws_writefd(pwsc,"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
|
||||
if(poi->readable)
|
||||
ws_writefd(pwsc,"\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ws_addresponseheader(pwsc,"Content-Length","%d",poi->dmap_response_length);
|
||||
ws_writefd(pwsc,"HTTP/1.1 200 OK\r\n");
|
||||
ws_emitheaders(pwsc);
|
||||
|
||||
/* I guess now we would start writing the output */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* write the output to wherever it goes. This expects to be fed
|
||||
* full dmap blocks. In the simplest case, it just streams those
|
||||
* dmap blocks out to the client. In more complex cases, it convert
|
||||
* them to xml, or compresses them.
|
||||
*
|
||||
* \param pqi pointer to the current dbquery info struct
|
||||
* \param pwsc pointer to the current conninfo struct
|
||||
* \param pblock block of data to write
|
||||
* \param len length of block to write
|
||||
*/
|
||||
int dispatch_output_write(WS_CONNINFO *pwsc, DBQUERYINFO *pqi, char *block, int len) {
|
||||
OUTPUT_INFO *poi=(pqi->output_info);
|
||||
int result;
|
||||
|
||||
if(poi->xml_output)
|
||||
return dispatch_output_xml_write(pwsc, pqi, block, len);
|
||||
|
||||
result=r_write(pwsc->fd,block,len);
|
||||
|
||||
if(result != len)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* this is the serializer for xml. This assumes that (with the exception of
|
||||
* containers) blocks are complete dmap blocks
|
||||
*
|
||||
* \param pqi pointer to the current dbquery info struct
|
||||
* \param pwsc pointer to the current conninfo struct
|
||||
* \param pblock block of data to write
|
||||
* \param len length of block to write
|
||||
*/
|
||||
int dispatch_output_xml_write(WS_CONNINFO *pwsc, DBQUERYINFO *pqi, char *block, int len) {
|
||||
OUTPUT_INFO *poi = pqi->output_info;
|
||||
char *current=block;
|
||||
char block_tag[5];
|
||||
int block_len;
|
||||
int len_left;
|
||||
DAAP_ITEMS *pitem;
|
||||
unsigned char *data;
|
||||
int ivalue;
|
||||
long long lvalue;
|
||||
int block_done=1;
|
||||
int stack_ptr;
|
||||
char *encoded_string;
|
||||
|
||||
while(current < (block + len)) {
|
||||
block_done=1;
|
||||
len_left=(block+len) - current;
|
||||
if(len_left < 8) {
|
||||
DPRINTF(E_FATAL,L_DAAP,"Badly formatted dmap block - frag size: %d",len_left);
|
||||
}
|
||||
|
||||
/* set up block */
|
||||
memcpy(block_tag,current,4);
|
||||
block_tag[4] = '\0';
|
||||
block_len = ntohl(*((int*)¤t[4]));
|
||||
data = ¤t[8];
|
||||
|
||||
if(strncmp(block_tag,"abro",4) ==0 ) {
|
||||
/* browse queries treat mlit as a string, not container */
|
||||
poi->browse_response=1;
|
||||
}
|
||||
|
||||
/* lookup and serialize */
|
||||
pitem=dispatch_xml_lookup_tag(block_tag);
|
||||
if(poi->readable)
|
||||
r_fdprintf(pwsc->fd,"%*s",poi->stack_height,"");
|
||||
r_fdprintf(pwsc->fd,"<%s>",pitem->description);
|
||||
switch(pitem->type) {
|
||||
case 0x01: /* byte */
|
||||
if(block_len != 1) {
|
||||
DPRINTF(E_FATAL,L_DAAP,"tag %s, size %d, wanted 1\n",block_tag, block_len);
|
||||
}
|
||||
r_fdprintf(pwsc->fd,"%d",*((char *)data));
|
||||
break;
|
||||
|
||||
case 0x02: /* unsigned byte */
|
||||
if(block_len != 1) {
|
||||
DPRINTF(E_FATAL,L_DAAP,"tag %s, size %d, wanted 1\n",block_tag, block_len);
|
||||
}
|
||||
r_fdprintf(pwsc->fd,"%ud",*((char *)data));
|
||||
break;
|
||||
|
||||
case 0x03: /* short */
|
||||
if(block_len != 2) {
|
||||
DPRINTF(E_FATAL,L_DAAP,"tag %s, size %d, wanted 2\n",block_tag, block_len);
|
||||
}
|
||||
|
||||
ivalue = data[0] << 8 | data[1];
|
||||
r_fdprintf(pwsc->fd,"%d",ivalue);
|
||||
break;
|
||||
|
||||
case 0x05: /* int */
|
||||
case 0x0A: /* epoch */
|
||||
if(block_len != 4) {
|
||||
DPRINTF(E_FATAL,L_DAAP,"tag %s, size %d, wanted 4\n",block_tag, block_len);
|
||||
}
|
||||
ivalue = data[0] << 24 |
|
||||
data[1] << 16 |
|
||||
data[2] << 8 |
|
||||
data[3];
|
||||
r_fdprintf(pwsc->fd,"%d",ivalue);
|
||||
break;
|
||||
case 0x07: /* long long */
|
||||
if(block_len != 8) {
|
||||
DPRINTF(E_FATAL,L_DAAP,"tag %s, size %d, wanted 8\n",block_tag, block_len);
|
||||
}
|
||||
|
||||
ivalue = data[0] << 24 |
|
||||
data[1] << 16 |
|
||||
data[2] << 8 |
|
||||
data[3];
|
||||
lvalue=ivalue;
|
||||
ivalue = data[4] << 24 |
|
||||
data[5] << 16 |
|
||||
data[6] << 8 |
|
||||
data[7];
|
||||
lvalue = (lvalue << 32) | ivalue;
|
||||
r_fdprintf(pwsc->fd,"%ll",ivalue);
|
||||
break;
|
||||
case 0x09: /* string */
|
||||
encoded_string=dispatch_xml_encode(data,block_len);
|
||||
r_fdprintf(pwsc->fd,"%s",encoded_string);
|
||||
free(encoded_string);
|
||||
break;
|
||||
case 0x0B: /* version? */
|
||||
if(block_len != 4) {
|
||||
DPRINTF(E_FATAL,L_DAAP,"tag %s, size %d, wanted 4\n",block_tag, block_len);
|
||||
}
|
||||
|
||||
ivalue=data[0] << 8 | data[1];
|
||||
r_fdprintf(pwsc->fd,"%d.%d.%d",ivalue,data[2],data[3]);
|
||||
break;
|
||||
|
||||
case 0x0C:
|
||||
if((poi->browse_response)&&(strcmp(block_tag,"mlit") ==0)) {
|
||||
encoded_string=dispatch_xml_encode(data,block_len);
|
||||
r_fdprintf(pwsc->fd,"%s",encoded_string);
|
||||
free(encoded_string);
|
||||
} else {
|
||||
/* we'll need to stack this up and try and remember where we
|
||||
* came from. Make it an extra 8 so that it gets fixed to
|
||||
* the *right* amount when the stacks are juggled below
|
||||
*/
|
||||
|
||||
poi->stack[poi->stack_height].bytes_left=block_len + 8;
|
||||
memcpy(poi->stack[poi->stack_height].tag,block_tag,5);
|
||||
poi->stack_height++;
|
||||
if(poi->stack_height == 10) {
|
||||
DPRINTF(E_FATAL,L_DAAP,"Stack overflow\n");
|
||||
}
|
||||
block_done=0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
DPRINTF(E_FATAL,L_DAAP,"Bad dmap type: %d, %s\n",
|
||||
pitem->type, pitem->description);
|
||||
break;
|
||||
}
|
||||
|
||||
if(block_done) {
|
||||
r_fdprintf(pwsc->fd,"</%s>",pitem->description);
|
||||
if(poi->readable)
|
||||
r_fdprintf(pwsc->fd,"\n");
|
||||
|
||||
block_len += 8;
|
||||
} else {
|
||||
/* must be a container */
|
||||
block_len = 8;
|
||||
if(poi->readable)
|
||||
r_fdprintf(pwsc->fd,"\n");
|
||||
}
|
||||
|
||||
current += block_len;
|
||||
|
||||
if(poi->stack_height) {
|
||||
stack_ptr=poi->stack_height;
|
||||
while(stack_ptr--) {
|
||||
poi->stack[stack_ptr].bytes_left -= block_len;
|
||||
if(poi->stack[stack_ptr].bytes_left < 0) {
|
||||
DPRINTF(E_FATAL,L_DAAP,"negative container\n");
|
||||
}
|
||||
|
||||
if(!poi->stack[stack_ptr].bytes_left) {
|
||||
poi->stack_height--;
|
||||
pitem=dispatch_xml_lookup_tag(poi->stack[stack_ptr].tag);
|
||||
if(poi->readable)
|
||||
r_fdprintf(pwsc->fd,"%*s",poi->stack_height,"");
|
||||
r_fdprintf(pwsc->fd,"</%s>",pitem->description);
|
||||
if(poi->readable)
|
||||
r_fdprintf(pwsc->fd,"\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* finish streaming output to the client, freeing any allocated
|
||||
* memory, and cleaning up
|
||||
*
|
||||
* \param pwsc current conninfo struct
|
||||
* \param pqi current dbquery struct
|
||||
*/
|
||||
int dispatch_output_end(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) {
|
||||
OUTPUT_INFO *poi = pqi->output_info;
|
||||
|
||||
if((poi) && (poi->xml_output) && (poi->stack_height)) {
|
||||
DPRINTF(E_LOG,L_DAAP,"Badly formed xml -- still stack\n");
|
||||
}
|
||||
|
||||
config_set_status(pwsc,pqi->session_id,NULL);
|
||||
free(poi);
|
||||
free(pqi);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
DAAP_ITEMS *dispatch_xml_lookup_tag(char *tag) {
|
||||
DAAP_ITEMS *pitem;
|
||||
|
||||
pitem=taglist;
|
||||
while((pitem->tag) && (strncmp(tag,pitem->tag,4))) {
|
||||
pitem++;
|
||||
}
|
||||
|
||||
if(!pitem->tag)
|
||||
DPRINTF(E_FATAL,L_DAAP,"Unknown daap tag: %c%c%c%c\n",tag[0],tag[1],tag[2],tag[3]);
|
||||
|
||||
return pitem;
|
||||
}
|
||||
|
||||
/**
|
||||
* xml entity encoding, stupid style
|
||||
*/
|
||||
char *dispatch_xml_encode(char *original, int len) {
|
||||
char *new;
|
||||
char *s, *d;
|
||||
int destsize;
|
||||
int truelen;
|
||||
|
||||
/* this is about stupid */
|
||||
if(len) {
|
||||
truelen=len;
|
||||
} else {
|
||||
truelen=strlen(original);
|
||||
}
|
||||
|
||||
destsize = 6*truelen+1;
|
||||
new=(char *)malloc(destsize);
|
||||
if(!new) return NULL;
|
||||
|
||||
memset(new,0x00,destsize);
|
||||
|
||||
s=original;
|
||||
d=new;
|
||||
|
||||
while(s < (original+truelen)) {
|
||||
switch(*s) {
|
||||
case '>':
|
||||
strcat(d,">");
|
||||
d += 4;
|
||||
s++;
|
||||
break;
|
||||
case '<':
|
||||
strcat(d,"<");
|
||||
d += 4;
|
||||
s++;
|
||||
break;
|
||||
case '"':
|
||||
strcat(d,""");
|
||||
d += 6;
|
||||
s++;
|
||||
break;
|
||||
case '\'':
|
||||
strcat(d,"'");
|
||||
d += 6;
|
||||
s++;
|
||||
break;
|
||||
case '&':
|
||||
strcat(d,"&");
|
||||
d += 5;
|
||||
s++;
|
||||
break;
|
||||
default:
|
||||
*d++ = *s++;
|
||||
}
|
||||
}
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
void dispatch_stream(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) {
|
||||
MP3FILE *pmp3;
|
||||
FILE *file_ptr;
|
||||
|
@ -422,15 +796,12 @@ void dispatch_playlistitems(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) {
|
|||
current += db_dmap_add_int(current,"mrco",song_count); /* 12 */
|
||||
current += db_dmap_add_container(current,"mlcl",list_length);
|
||||
|
||||
ws_addresponseheader(pwsc,"Content-Length","%d",61+list_length);
|
||||
ws_writefd(pwsc,"HTTP/1.1 200 OK\r\n");
|
||||
ws_emitheaders(pwsc);
|
||||
|
||||
r_write(pwsc->fd,items_response,61);
|
||||
dispatch_output_start(pwsc,pqi,61+list_length);
|
||||
dispatch_output_write(pwsc,pqi,items_response,61);
|
||||
|
||||
while((list_length=db_enum_fetch(pqi,&block)) > 0) {
|
||||
DPRINTF(E_DBG,L_DAAP,"Got block of size %d\n",list_length);
|
||||
r_write(pwsc->fd,block,list_length);
|
||||
DPRINTF(E_SPAM,L_DAAP,"Got block of size %d\n",list_length);
|
||||
dispatch_output_write(pwsc,pqi,block,list_length);
|
||||
free(block);
|
||||
}
|
||||
|
||||
|
@ -438,8 +809,7 @@ void dispatch_playlistitems(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) {
|
|||
|
||||
db_enum_end();
|
||||
|
||||
config_set_status(pwsc,pqi->session_id,NULL);
|
||||
free(pqi);
|
||||
dispatch_output_end(pwsc,pqi);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -492,15 +862,12 @@ void dispatch_browse(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) {
|
|||
current += db_dmap_add_int(current,"mrco",item_count); /* 12 */
|
||||
current += db_dmap_add_container(current,response_type,list_length); /* 8 + length */
|
||||
|
||||
ws_addresponseheader(pwsc,"Content-Length","%d",52+list_length);
|
||||
ws_writefd(pwsc,"HTTP/1.1 200 OK\r\n");
|
||||
ws_emitheaders(pwsc);
|
||||
|
||||
r_write(pwsc->fd,browse_response,52);
|
||||
dispatch_output_start(pwsc,pqi,52+list_length);
|
||||
dispatch_output_write(pwsc,pqi,browse_response,52);
|
||||
|
||||
while((list_length=db_enum_fetch(pqi,&block)) > 0) {
|
||||
DPRINTF(E_DBG,L_DAAP|L_BROW,"Got block of size %d\n",list_length);
|
||||
r_write(pwsc->fd,block,list_length);
|
||||
DPRINTF(E_SPAM,L_DAAP|L_BROW,"Got block of size %d\n",list_length);
|
||||
dispatch_output_write(pwsc,pqi,block,list_length);
|
||||
free(block);
|
||||
}
|
||||
|
||||
|
@ -508,8 +875,7 @@ void dispatch_browse(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) {
|
|||
|
||||
db_enum_end();
|
||||
|
||||
config_set_status(pwsc,pqi->session_id,NULL);
|
||||
free(pqi);
|
||||
dispatch_output_end(pwsc,pqi);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -547,15 +913,12 @@ void dispatch_playlists(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) {
|
|||
current += db_dmap_add_int(current,"mrco",pl_count); /* 12 */
|
||||
current += db_dmap_add_container(current,"mlcl",list_length);
|
||||
|
||||
ws_addresponseheader(pwsc,"Content-Length","%d",61+list_length);
|
||||
ws_writefd(pwsc,"HTTP/1.1 200 OK\r\n");
|
||||
ws_emitheaders(pwsc);
|
||||
|
||||
r_write(pwsc->fd,playlist_response,61);
|
||||
dispatch_output_start(pwsc,pqi,61+list_length);
|
||||
dispatch_output_write(pwsc,pqi,playlist_response,61);
|
||||
|
||||
while((list_length=db_enum_fetch(pqi,&block)) > 0) {
|
||||
DPRINTF(E_DBG,L_DAAP,"Got block of size %d\n",list_length);
|
||||
r_write(pwsc->fd,block,list_length);
|
||||
DPRINTF(E_SPAM,L_DAAP,"Got block of size %d\n",list_length);
|
||||
dispatch_output_write(pwsc,pqi,block,list_length);
|
||||
free(block);
|
||||
}
|
||||
|
||||
|
@ -563,8 +926,7 @@ void dispatch_playlists(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) {
|
|||
|
||||
db_enum_end();
|
||||
|
||||
config_set_status(pwsc,pqi->session_id,NULL);
|
||||
free(pqi);
|
||||
dispatch_output_end(pwsc,pqi);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -600,15 +962,12 @@ void dispatch_items(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) {
|
|||
current += db_dmap_add_int(current,"mrco",song_count); /* 12 */
|
||||
current += db_dmap_add_container(current,"mlcl",list_length);
|
||||
|
||||
ws_addresponseheader(pwsc,"Content-Length","%d",61+list_length);
|
||||
ws_writefd(pwsc,"HTTP/1.1 200 OK\r\n");
|
||||
ws_emitheaders(pwsc);
|
||||
|
||||
r_write(pwsc->fd,items_response,61);
|
||||
dispatch_output_start(pwsc,pqi,61+list_length);
|
||||
dispatch_output_write(pwsc,pqi,items_response,61);
|
||||
|
||||
while((list_length=db_enum_fetch(pqi,&block)) > 0) {
|
||||
DPRINTF(E_DBG,L_DAAP,"Got block of size %d\n",list_length);
|
||||
r_write(pwsc->fd,block,list_length);
|
||||
DPRINTF(E_SPAM,L_DAAP,"Got block of size %d\n",list_length);
|
||||
dispatch_output_write(pwsc,pqi,block,list_length);
|
||||
free(block);
|
||||
}
|
||||
|
||||
|
@ -616,8 +975,7 @@ void dispatch_items(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) {
|
|||
|
||||
db_enum_end();
|
||||
|
||||
config_set_status(pwsc,pqi->session_id,NULL);
|
||||
free(pqi);
|
||||
dispatch_output_end(pwsc,pqi);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -656,14 +1014,11 @@ void dispatch_update(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) {
|
|||
current += db_dmap_add_int(current,"mstt",200); /* 12 */
|
||||
current += db_dmap_add_int(current,"musr",db_revision()); /* 12 */
|
||||
|
||||
ws_addresponseheader(pwsc,"Content-Length","32");
|
||||
ws_writefd(pwsc,"HTTP/1.1 200 OK\r\n");
|
||||
ws_emitheaders(pwsc);
|
||||
dispatch_output_start(pwsc,pqi,32);
|
||||
dispatch_output_write(pwsc,pqi,update_response,32);
|
||||
dispatch_output_end(pwsc,pqi);
|
||||
|
||||
r_write(pwsc->fd,update_response,32);
|
||||
|
||||
config_set_status(pwsc,pqi->session_id,NULL);
|
||||
free(pqi);
|
||||
return;
|
||||
}
|
||||
|
||||
void dispatch_dbinfo(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) {
|
||||
|
@ -685,13 +1040,10 @@ void dispatch_dbinfo(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) {
|
|||
current += db_dmap_add_int(current,"mimc",db_get_song_count()); /* 12 */
|
||||
current += db_dmap_add_int(current,"mctc",db_get_playlist_count()); /* 12 */
|
||||
|
||||
ws_addresponseheader(pwsc,"Content-Length","%d",113 + namelen);
|
||||
ws_writefd(pwsc,"HTTP/1.1 200 OK\r\n");
|
||||
ws_emitheaders(pwsc);
|
||||
dispatch_output_start(pwsc,pqi,113+namelen);
|
||||
dispatch_output_write(pwsc,pqi,dbinfo_response,113+namelen);
|
||||
dispatch_output_end(pwsc,pqi);
|
||||
|
||||
r_write(pwsc->fd,dbinfo_response,113 + namelen);
|
||||
config_set_status(pwsc,pqi->session_id,NULL);
|
||||
free(pqi);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -713,13 +1065,9 @@ void dispatch_login(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) {
|
|||
current += db_dmap_add_int(current,"mstt",200); /* 12 */
|
||||
current += db_dmap_add_int(current,"mlid",session); /* 12 */
|
||||
|
||||
ws_addresponseheader(pwsc,"Content-Length","32");
|
||||
ws_writefd(pwsc,"HTTP/1.1 200 OK\r\n");
|
||||
ws_emitheaders(pwsc);
|
||||
|
||||
r_write(pwsc->fd,login_response,32);
|
||||
config_set_status(pwsc,pqi->session_id,NULL);
|
||||
free(pqi);
|
||||
dispatch_output_start(pwsc,pqi,32);
|
||||
dispatch_output_write(pwsc,pqi,login_response,32);
|
||||
dispatch_output_end(pwsc,pqi);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -741,12 +1089,9 @@ void dispatch_content_codes(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) {
|
|||
current += db_dmap_add_container(current,"mccr",len + 12);
|
||||
current += db_dmap_add_int(current,"mstt",200);
|
||||
|
||||
|
||||
ws_addresponseheader(pwsc,"Content-Length","%d",len+20);
|
||||
ws_writefd(pwsc,"HTTP/1.1 200 OK\r\n");
|
||||
ws_emitheaders(pwsc);
|
||||
r_write(pwsc->fd,content_codes,20);
|
||||
|
||||
dispatch_output_start(pwsc,pqi,len+20);
|
||||
dispatch_output_write(pwsc,pqi,content_codes,20);
|
||||
|
||||
dicurrent=taglist;
|
||||
while(dicurrent->type) {
|
||||
current=mdcl;
|
||||
|
@ -755,12 +1100,12 @@ void dispatch_content_codes(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) {
|
|||
current += db_dmap_add_string(current,"mcnm",dicurrent->tag); /* 12 */
|
||||
current += db_dmap_add_string(current,"mcna",dicurrent->description); /* 8 + descr */
|
||||
current += db_dmap_add_short(current,"mcty",dicurrent->type); /* 10 */
|
||||
r_write(pwsc->fd,mdcl,len+8);
|
||||
dispatch_output_write(pwsc,pqi,mdcl,len+8);
|
||||
dicurrent++;
|
||||
}
|
||||
|
||||
config_set_status(pwsc,pqi->session_id,NULL);
|
||||
free(pqi);
|
||||
|
||||
dispatch_output_end(pwsc,pqi);
|
||||
return;
|
||||
}
|
||||
|
||||
void dispatch_server_info(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) {
|
||||
|
@ -805,13 +1150,10 @@ void dispatch_server_info(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) {
|
|||
current += db_dmap_add_char(current,"msup",0); /* 9 */
|
||||
current += db_dmap_add_int(current,"msdc",1); /* 12 */
|
||||
|
||||
ws_addresponseheader(pwsc,"Content-Length","%d",actual_length);
|
||||
dispatch_output_start(pwsc,pqi,actual_length);
|
||||
dispatch_output_write(pwsc,pqi,server_info,actual_length);
|
||||
dispatch_output_end(pwsc,pqi);
|
||||
|
||||
ws_writefd(pwsc,"HTTP/1.1 200 OK\r\n");
|
||||
ws_emitheaders(pwsc);
|
||||
|
||||
r_write(pwsc->fd,server_info,actual_length);
|
||||
config_set_status(pwsc,pqi->session_id,NULL);
|
||||
free(pqi);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue