mirror of
https://github.com/owntone/owntone-server.git
synced 2025-02-04 10:26:02 -05:00
rollback r884 and r885, the json mess. Probably cleaner to make an xml-building api that more cleanly maps to json
This commit is contained in:
parent
a2528eba8c
commit
b1ed033d9e
187
src/xml-rpc.c
187
src/xml-rpc.c
@ -21,7 +21,6 @@
|
|||||||
#include "mp3-scanner.h"
|
#include "mp3-scanner.h"
|
||||||
#include "rend.h"
|
#include "rend.h"
|
||||||
#include "webserver.h"
|
#include "webserver.h"
|
||||||
#include "xml-rpc.h"
|
|
||||||
|
|
||||||
/* typedefs */
|
/* typedefs */
|
||||||
typedef struct tag_xmlstack {
|
typedef struct tag_xmlstack {
|
||||||
@ -32,8 +31,6 @@ typedef struct tag_xmlstack {
|
|||||||
typedef struct tag_xmlstruct {
|
typedef struct tag_xmlstruct {
|
||||||
WS_CONNINFO *pwsc;
|
WS_CONNINFO *pwsc;
|
||||||
int stack_level;
|
int stack_level;
|
||||||
int suppress_lead;
|
|
||||||
int flags;
|
|
||||||
XMLSTACK stack;
|
XMLSTACK stack;
|
||||||
} XMLSTRUCT;
|
} XMLSTRUCT;
|
||||||
|
|
||||||
@ -41,6 +38,12 @@ typedef struct tag_xmlstruct {
|
|||||||
void xml_get_stats(WS_CONNINFO *pwsc);
|
void xml_get_stats(WS_CONNINFO *pwsc);
|
||||||
char *xml_entity_encode(char *original);
|
char *xml_entity_encode(char *original);
|
||||||
|
|
||||||
|
XMLSTRUCT *xml_init(WS_CONNINFO *pwsc, int emit_header);
|
||||||
|
void xml_push(XMLSTRUCT *pxml, char *term);
|
||||||
|
void xml_pop(XMLSTRUCT *pxml);
|
||||||
|
void xml_output(XMLSTRUCT *pxml, char *section, char *fmt, ...);
|
||||||
|
void xml_deinit(XMLSTRUCT *pxml);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* create an xml response structure, a helper struct for
|
* create an xml response structure, a helper struct for
|
||||||
* building xml responses.
|
* building xml responses.
|
||||||
@ -49,7 +52,7 @@ char *xml_entity_encode(char *original);
|
|||||||
* @param emit_header whether or not to throw out html headers and xml header
|
* @param emit_header whether or not to throw out html headers and xml header
|
||||||
* @returns XMLSTRUCT on success, or NULL if failure
|
* @returns XMLSTRUCT on success, or NULL if failure
|
||||||
*/
|
*/
|
||||||
XMLSTRUCT *xml_init(WS_CONNINFO *pwsc, int emit_header, int flags) {
|
XMLSTRUCT *xml_init(WS_CONNINFO *pwsc, int emit_header) {
|
||||||
XMLSTRUCT *pxml;
|
XMLSTRUCT *pxml;
|
||||||
|
|
||||||
pxml=(XMLSTRUCT*)malloc(sizeof(XMLSTRUCT));
|
pxml=(XMLSTRUCT*)malloc(sizeof(XMLSTRUCT));
|
||||||
@ -60,20 +63,13 @@ XMLSTRUCT *xml_init(WS_CONNINFO *pwsc, int emit_header, int flags) {
|
|||||||
memset(pxml,0,sizeof(XMLSTRUCT));
|
memset(pxml,0,sizeof(XMLSTRUCT));
|
||||||
|
|
||||||
pxml->pwsc = pwsc;
|
pxml->pwsc = pwsc;
|
||||||
pxml->flags = flags;
|
|
||||||
|
|
||||||
if(emit_header) {
|
if(emit_header) {
|
||||||
if(flags & XML_FLAG_JSON) {
|
ws_addresponseheader(pwsc,"Content-Type","text/xml; charset=utf-8");
|
||||||
ws_addresponseheader(pwsc,"Content-Type","text/json");
|
|
||||||
} else {
|
|
||||||
ws_addresponseheader(pwsc,"Content-Type","text/xml; charset=utf-8");
|
|
||||||
}
|
|
||||||
ws_writefd(pwsc,"HTTP/1.0 200 OK\r\n");
|
ws_writefd(pwsc,"HTTP/1.0 200 OK\r\n");
|
||||||
ws_emitheaders(pwsc);
|
ws_emitheaders(pwsc);
|
||||||
|
|
||||||
if(!(flags & XML_FLAG_JSON)) {
|
ws_writefd(pwsc,"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
|
||||||
ws_writefd(pwsc,"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return pxml;
|
return pxml;
|
||||||
@ -85,55 +81,17 @@ XMLSTRUCT *xml_init(WS_CONNINFO *pwsc, int emit_header, int flags) {
|
|||||||
* @param pxml xml struct obtained from xml_init
|
* @param pxml xml struct obtained from xml_init
|
||||||
* @param term next xlm section to start
|
* @param term next xlm section to start
|
||||||
*/
|
*/
|
||||||
void xml_push(XMLSTRUCT *pxml, char *term, int container) {
|
void xml_push(XMLSTRUCT *pxml, char *term) {
|
||||||
XMLSTACK *pstack;
|
XMLSTACK *pstack;
|
||||||
int is_array=0;
|
|
||||||
int parent_is_array=0;
|
|
||||||
int suppress_nl=0;
|
|
||||||
char *parent_term;
|
|
||||||
|
|
||||||
pstack = (XMLSTACK *)malloc(sizeof(XMLSTACK));
|
pstack = (XMLSTACK *)malloc(sizeof(XMLSTACK));
|
||||||
pstack->next=pxml->stack.next;
|
pstack->next=pxml->stack.next;
|
||||||
pstack->tag=strdup(term);
|
pstack->tag=strdup(term);
|
||||||
pxml->stack.next=pstack;
|
pxml->stack.next=pstack;
|
||||||
|
|
||||||
if((strlen(term) > 5)&&(strcasecmp(&term[strlen(term)-5],"array") == 0)) {
|
|
||||||
is_array=1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pstack->next) {
|
|
||||||
parent_term = pstack->next->tag;
|
|
||||||
if((strlen(parent_term) > 5) &&
|
|
||||||
(strcasecmp(&parent_term[strlen(parent_term)-5],"array") == 0)) {
|
|
||||||
parent_is_array=1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if((pxml->flags & XML_FLAG_READABLE) && (!pxml->suppress_lead))
|
|
||||||
ws_writefd(pxml->pwsc,"%*s",pxml->stack_level,"");
|
|
||||||
|
|
||||||
if(pxml->flags & XML_FLAG_JSON) {
|
|
||||||
if(pxml->suppress_lead) {
|
|
||||||
ws_writefd(pxml->pwsc,", ");
|
|
||||||
}
|
|
||||||
if(!parent_is_array) {
|
|
||||||
ws_writefd(pxml->pwsc,"\"%s\": ",term);
|
|
||||||
} else {
|
|
||||||
suppress_nl=1;
|
|
||||||
}
|
|
||||||
if(is_array) {
|
|
||||||
ws_writefd(pxml->pwsc,"[");
|
|
||||||
} else if(container) {
|
|
||||||
ws_writefd(pxml->pwsc,"{");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ws_writefd(pxml->pwsc,"<%s>",term);
|
|
||||||
}
|
|
||||||
|
|
||||||
if((container) && (pxml->flags & XML_FLAG_READABLE)&&(!suppress_nl))
|
|
||||||
ws_writefd(pxml->pwsc,"\n");
|
|
||||||
|
|
||||||
pxml->stack_level++;
|
pxml->stack_level++;
|
||||||
|
|
||||||
|
ws_writefd(pxml->pwsc,"<%s>",term);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -141,14 +99,9 @@ void xml_push(XMLSTRUCT *pxml, char *term, int container) {
|
|||||||
*
|
*
|
||||||
* @param pxml xml struct we are working with
|
* @param pxml xml struct we are working with
|
||||||
*/
|
*/
|
||||||
void xml_pop(XMLSTRUCT *pxml, int container) {
|
void xml_pop(XMLSTRUCT *pxml) {
|
||||||
XMLSTACK *pstack;
|
XMLSTACK *pstack;
|
||||||
int is_array=0;
|
|
||||||
int parent_is_array=0;
|
|
||||||
char *term;
|
|
||||||
char *parent_term;
|
|
||||||
|
|
||||||
int suppress_nl = 0;
|
|
||||||
pstack=pxml->stack.next;
|
pstack=pxml->stack.next;
|
||||||
if(!pstack) {
|
if(!pstack) {
|
||||||
DPRINTF(E_LOG,L_XML,"xml_pop: tried to pop an empty stack\n");
|
DPRINTF(E_LOG,L_XML,"xml_pop: tried to pop an empty stack\n");
|
||||||
@ -157,43 +110,11 @@ void xml_pop(XMLSTRUCT *pxml, int container) {
|
|||||||
|
|
||||||
pxml->stack.next = pstack->next;
|
pxml->stack.next = pstack->next;
|
||||||
|
|
||||||
pxml->stack_level--;
|
ws_writefd(pxml->pwsc,"</%s>",pstack->tag);
|
||||||
|
|
||||||
term = pstack->tag;
|
|
||||||
if((strlen(term) > 5)&&(strcasecmp(&term[strlen(term)-5],"array") == 0)) {
|
|
||||||
is_array=1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pxml->stack.next) {
|
|
||||||
parent_term = pxml->stack.next->tag;
|
|
||||||
if((strlen(parent_term) > 5) &&
|
|
||||||
(strcasecmp(&parent_term[strlen(parent_term)-5],"array") == 0)) {
|
|
||||||
parent_is_array=1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if((container) && (pxml->flags & XML_FLAG_READABLE))
|
|
||||||
ws_writefd(pxml->pwsc,"%*s",pxml->stack_level,"");
|
|
||||||
|
|
||||||
if(pxml->flags & XML_FLAG_JSON) {
|
|
||||||
pxml->suppress_lead=0;
|
|
||||||
if(is_array) {
|
|
||||||
ws_writefd(pxml->pwsc,"]");
|
|
||||||
} else if(container) {
|
|
||||||
ws_writefd(pxml->pwsc,"}");
|
|
||||||
} else {
|
|
||||||
suppress_nl = 1;
|
|
||||||
pxml->suppress_lead=1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ws_writefd(pxml->pwsc,"</%s>",pstack->tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
if((pxml->flags & XML_FLAG_READABLE)&&(!suppress_nl))
|
|
||||||
ws_writefd(pxml->pwsc,"\n");
|
|
||||||
|
|
||||||
free(pstack->tag);
|
free(pstack->tag);
|
||||||
free(pstack);
|
free(pstack);
|
||||||
|
|
||||||
|
pxml->stack_level--;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -208,22 +129,14 @@ void xml_output(XMLSTRUCT *pxml, char *section, char *fmt, ...) {
|
|||||||
vsnprintf(buf, sizeof(buf), fmt, ap);
|
vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
if(section) {
|
|
||||||
xml_push(pxml,section,FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
output = xml_entity_encode(buf);
|
output = xml_entity_encode(buf);
|
||||||
if(pxml->flags & XML_FLAG_JSON) {
|
|
||||||
ws_writefd(pxml->pwsc,"\"%s\"",output);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
ws_writefd(pxml->pwsc,"%s",output);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(output);
|
|
||||||
|
|
||||||
if(section) {
|
if(section) {
|
||||||
xml_pop(pxml,FALSE);
|
xml_push(pxml,section);
|
||||||
|
}
|
||||||
|
ws_writefd(pxml->pwsc,"%s",output);
|
||||||
|
free(output);
|
||||||
|
if(section) {
|
||||||
|
xml_pop(pxml);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,7 +187,6 @@ void xml_handle(WS_CONNINFO *pwsc) {
|
|||||||
*/
|
*/
|
||||||
void xml_get_stats(WS_CONNINFO *pwsc) {
|
void xml_get_stats(WS_CONNINFO *pwsc) {
|
||||||
int r_secs, r_days, r_hours, r_mins;
|
int r_secs, r_days, r_hours, r_mins;
|
||||||
int flag=0;
|
|
||||||
char buf[80];
|
char buf[80];
|
||||||
WS_CONNINFO *pci;
|
WS_CONNINFO *pci;
|
||||||
SCAN_STATUS *pss;
|
SCAN_STATUS *pss;
|
||||||
@ -282,20 +194,13 @@ void xml_get_stats(WS_CONNINFO *pwsc) {
|
|||||||
int count;
|
int count;
|
||||||
XMLSTRUCT *pxml;
|
XMLSTRUCT *pxml;
|
||||||
|
|
||||||
/* check output... */
|
pxml=xml_init(pwsc,1);
|
||||||
if(ws_getvar(pwsc,"output") == NULL) {
|
xml_push(pxml,"status");
|
||||||
flag = XML_FLAG_NONE;
|
|
||||||
} else if(strcasecmp(ws_getvar(pwsc,"output"),"json") == 0) {
|
|
||||||
flag = XML_FLAG_JSON | XML_FLAG_READABLE;
|
|
||||||
} else if(strcasecmp(ws_getvar(pwsc,"output"),"readable") == 0) {
|
|
||||||
flag = XML_FLAG_READABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
pxml=xml_init(pwsc,1,flag);
|
xml_push(pxml,"service_status");
|
||||||
|
|
||||||
|
xml_push(pxml,"service");
|
||||||
|
|
||||||
xml_push(pxml,"status",TRUE);
|
|
||||||
xml_push(pxml,"service_array",TRUE);
|
|
||||||
xml_push(pxml,"service",TRUE);
|
|
||||||
xml_output(pxml,"name","Rendezvous");
|
xml_output(pxml,"name","Rendezvous");
|
||||||
|
|
||||||
#ifndef WITHOUT_MDNS
|
#ifndef WITHOUT_MDNS
|
||||||
@ -308,38 +213,38 @@ void xml_get_stats(WS_CONNINFO *pwsc) {
|
|||||||
|
|
||||||
ws_writefd(pwsc,"<td>No Support</td><td> </td></tr>\n");
|
ws_writefd(pwsc,"<td>No Support</td><td> </td></tr>\n");
|
||||||
#endif
|
#endif
|
||||||
xml_pop(pxml,TRUE); /* service */
|
xml_pop(pxml); /* service */
|
||||||
|
|
||||||
xml_push(pxml,"service",TRUE);
|
xml_push(pxml,"service");
|
||||||
xml_output(pxml,"name","DAAP Server");
|
xml_output(pxml,"name","DAAP Server");
|
||||||
xml_output(pxml,"status",config.stop ? "Stopping" : "Running");
|
xml_output(pxml,"status",config.stop ? "Stopping" : "Running");
|
||||||
xml_pop(pxml,TRUE); /* service */
|
xml_pop(pxml); /* service */
|
||||||
|
|
||||||
xml_push(pxml,"service",TRUE);
|
xml_push(pxml,"service");
|
||||||
xml_output(pxml,"name","File Scanner");
|
xml_output(pxml,"name","File Scanner");
|
||||||
xml_output(pxml,"status",config.reload ? "Running" : "Idle");
|
xml_output(pxml,"status",config.reload ? "Running" : "Idle");
|
||||||
xml_pop(pxml,TRUE); /* service */
|
xml_pop(pxml); /* service */
|
||||||
|
|
||||||
xml_pop(pxml,TRUE); /* service_status */
|
xml_pop(pxml); /* service_status */
|
||||||
|
|
||||||
xml_push(pxml,"thread_array",TRUE);
|
xml_push(pxml,"thread_status");
|
||||||
|
|
||||||
pci = ws_thread_enum_first(config.server,&wste);
|
pci = ws_thread_enum_first(config.server,&wste);
|
||||||
while(pci) {
|
while(pci) {
|
||||||
pss = ws_get_local_storage(pci);
|
pss = ws_get_local_storage(pci);
|
||||||
if(pss) {
|
if(pss) {
|
||||||
xml_push(pxml,"thread",TRUE);
|
xml_push(pxml,"thread");
|
||||||
xml_output(pxml,"id","%d",pss->thread);
|
xml_output(pxml,"id","%d",pss->thread);
|
||||||
xml_output(pxml,"sourceip","%s",pss->host);
|
xml_output(pxml,"sourceip","%s",pss->host);
|
||||||
xml_output(pxml,"action","%s",pss->what);
|
xml_output(pxml,"action","%s",pss->what);
|
||||||
xml_pop(pxml,TRUE); /* thread */
|
xml_pop(pxml); /* thread */
|
||||||
}
|
}
|
||||||
pci=ws_thread_enum_next(config.server,&wste);
|
pci=ws_thread_enum_next(config.server,&wste);
|
||||||
}
|
}
|
||||||
|
|
||||||
xml_pop(pxml,TRUE); /* thread_status */
|
xml_pop(pxml); /* thread_status */
|
||||||
|
|
||||||
xml_push(pxml,"stat_array",TRUE);
|
xml_push(pxml,"statistics");
|
||||||
|
|
||||||
r_secs=(int)(time(NULL)-config.stats.start_time);
|
r_secs=(int)(time(NULL)-config.stats.start_time);
|
||||||
|
|
||||||
@ -368,24 +273,24 @@ void xml_get_stats(WS_CONNINFO *pwsc) {
|
|||||||
sprintf((char*)&buf[strlen(buf)],"%d second%s ", r_secs,
|
sprintf((char*)&buf[strlen(buf)],"%d second%s ", r_secs,
|
||||||
r_secs == 1 ? "" : "s");
|
r_secs == 1 ? "" : "s");
|
||||||
|
|
||||||
xml_push(pxml,"stat",TRUE);
|
xml_push(pxml,"stat");
|
||||||
xml_output(pxml,"name","Uptime");
|
xml_output(pxml,"name","Uptime");
|
||||||
xml_output(pxml,"value","%s",buf);
|
xml_output(pxml,"value","%s",buf);
|
||||||
xml_pop(pxml,TRUE); /* stat */
|
xml_pop(pxml); /* stat */
|
||||||
|
|
||||||
xml_push(pxml,"stat",TRUE);
|
xml_push(pxml,"stat");
|
||||||
xml_output(pxml,"name","Songs");
|
xml_output(pxml,"name","Songs");
|
||||||
db_get_song_count(NULL,&count);
|
db_get_song_count(NULL,&count);
|
||||||
xml_output(pxml,"value","%d",count);
|
xml_output(pxml,"value","%d",count);
|
||||||
xml_pop(pxml,TRUE); /* stat */
|
xml_pop(pxml); /* stat */
|
||||||
|
|
||||||
xml_push(pxml,"stat",TRUE);
|
xml_push(pxml,"stat");
|
||||||
xml_output(pxml,"name","Songs Served");
|
xml_output(pxml,"name","Songs Served");
|
||||||
xml_output(pxml,"value","%d",config.stats.songs_served);
|
xml_output(pxml,"value","%d",config.stats.songs_served);
|
||||||
xml_pop(pxml,TRUE); /* stat */
|
xml_pop(pxml); /* stat */
|
||||||
|
|
||||||
xml_pop(pxml,TRUE); /* statistics */
|
xml_pop(pxml); /* statistics */
|
||||||
xml_pop(pxml,TRUE); /* status */
|
xml_pop(pxml); /* status */
|
||||||
|
|
||||||
xml_deinit(pxml);
|
xml_deinit(pxml);
|
||||||
return;
|
return;
|
||||||
|
@ -7,19 +7,6 @@
|
|||||||
|
|
||||||
#include "webserver.h"
|
#include "webserver.h"
|
||||||
|
|
||||||
#define XML_FLAG_NONE 0
|
|
||||||
#define XML_FLAG_JSON 1
|
|
||||||
#define XML_FLAG_READABLE 2
|
|
||||||
|
|
||||||
|
|
||||||
struct tag_xmlstruct;
|
|
||||||
|
|
||||||
extern void xml_handle(WS_CONNINFO *pwsc);
|
extern void xml_handle(WS_CONNINFO *pwsc);
|
||||||
extern struct tag_xmlstruct *xml_init(WS_CONNINFO *pwsc, int emit_header,
|
|
||||||
int flags);
|
|
||||||
extern void xml_push(struct tag_xmlstruct *pxml, char *term, int container);
|
|
||||||
extern void xml_pop(struct tag_xmlstruct *pxml, int container);
|
|
||||||
extern void xml_output(struct tag_xmlstruct *pxml, char *section, char *fmt, ...);
|
|
||||||
extern void xml_deinit(struct tag_xmlstruct *pxml);
|
|
||||||
|
|
||||||
#endif /* _XMLRPC_H_ */
|
#endif /* _XMLRPC_H_ */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user