Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Xiph.Org
Icecast-Server
Commits
7fadb6ce
Commit
7fadb6ce
authored
Jun 27, 2018
by
Philipp Schafft
🦁
Browse files
Feature: Added function to send XML Report to client
parent
8ea908e3
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/client.c
View file @
7fadb6ce
...
...
@@ -38,6 +38,9 @@
#include "stats.h"
#include "fserve.h"
#include "errors.h"
#include "reportxml.h"
#include "refobject.h"
#include "xslt.h"
#include "client.h"
#include "auth.h"
...
...
@@ -409,6 +412,151 @@ static inline void client_send_500(client_t *client, const char *message)
client_destroy
(
client
);
}
/* this function sends a reportxml file to the client in the prefered format. */
void
client_send_reportxml
(
client_t
*
client
,
reportxml_t
*
report
,
document_domain_t
domain
,
const
char
*
xsl
,
admin_format_t
admin_format_hint
,
int
status
)
{
admin_format_t
admin_format
;
xmlDocPtr
doc
;
if
(
!
client
)
return
;
if
(
!
report
)
{
ICECAST_LOG_ERROR
(
"No report xml given. Sending 500 to client %p"
,
client
);
client_send_500
(
client
,
"No report."
);
return
;
}
if
(
!
status
)
status
=
200
;
if
(
admin_format_hint
==
ADMIN_FORMAT_AUTO
)
{
admin_format
=
client_get_admin_format_by_content_negotiation
(
client
);
}
else
{
admin_format
=
admin_format_hint
;
}
if
(
!
xsl
)
{
switch
(
admin_format
)
{
case
ADMIN_FORMAT_RAW
:
/* noop, we don't need to set xsl */
break
;
case
ADMIN_FORMAT_TRANSFORMED
:
xsl
=
CLIENT_DEFAULT_REPORT_XSL_TRANSFORMED
;
break
;
case
ADMIN_FORMAT_PLAINTEXT
:
xsl
=
CLIENT_DEFAULT_REPORT_XSL_PLAINTEXT
;
break
;
default:
ICECAST_LOG_ERROR
(
"Unsupported admin format and no XSLT file given. Sending 500 to client %p"
,
client
);
client_send_500
(
client
,
"Unsupported admin format."
);
return
;
break
;
}
}
else
if
(
admin_format_hint
==
ADMIN_FORMAT_AUTO
)
{
ICECAST_LOG_ERROR
(
"No explicit admin format but XSLT file given. BUG. Sending 500 to client %p"
,
client
);
client_send_500
(
client
,
"Admin type AUTO but XSLT."
);
return
;
}
doc
=
reportxml_render_xmldoc
(
report
);
if
(
!
doc
)
{
ICECAST_LOG_ERROR
(
"Can not render XML Document from report. Sending 500 to client %p"
,
client
);
client_send_500
(
client
,
"Can not render XML Document from report."
);
return
;
}
if
(
admin_format
==
ADMIN_FORMAT_RAW
)
{
xmlChar
*
buff
=
NULL
;
int
len
=
0
;
size_t
buf_len
;
ssize_t
ret
;
xmlDocDumpMemory
(
doc
,
&
buff
,
&
len
);
buf_len
=
len
+
1024
;
if
(
buf_len
<
4096
)
buf_len
=
4096
;
client_set_queue
(
client
,
NULL
);
client
->
refbuf
=
refbuf_new
(
buf_len
);
ret
=
util_http_build_header
(
client
->
refbuf
->
data
,
buf_len
,
0
,
0
,
status
,
NULL
,
"text/xml"
,
"utf-8"
,
NULL
,
NULL
,
client
);
if
(
ret
<
0
)
{
ICECAST_LOG_ERROR
(
"Dropping client as we can not build response headers."
);
client_send_error_by_id
(
client
,
ICECAST_ERROR_GEN_HEADER_GEN_FAILED
);
xmlFree
(
buff
);
return
;
}
else
if
(
buf_len
<
(
size_t
)(
len
+
ret
+
64
))
{
void
*
new_data
;
buf_len
=
ret
+
len
+
64
;
new_data
=
realloc
(
client
->
refbuf
->
data
,
buf_len
);
if
(
new_data
)
{
ICECAST_LOG_DEBUG
(
"Client buffer reallocation succeeded."
);
client
->
refbuf
->
data
=
new_data
;
client
->
refbuf
->
len
=
buf_len
;
ret
=
util_http_build_header
(
client
->
refbuf
->
data
,
buf_len
,
0
,
0
,
status
,
NULL
,
"text/xml"
,
"utf-8"
,
NULL
,
NULL
,
client
);
if
(
ret
==
-
1
)
{
ICECAST_LOG_ERROR
(
"Dropping client as we can not build response headers."
);
client_send_error_by_id
(
client
,
ICECAST_ERROR_GEN_HEADER_GEN_FAILED
);
xmlFree
(
buff
);
return
;
}
}
else
{
ICECAST_LOG_ERROR
(
"Client buffer reallocation failed. Dropping client."
);
client_send_error_by_id
(
client
,
ICECAST_ERROR_GEN_BUFFER_REALLOC
);
xmlFree
(
buff
);
return
;
}
}
/* FIXME: in this section we hope no function will ever return -1 */
ret
+=
snprintf
(
client
->
refbuf
->
data
+
ret
,
buf_len
-
ret
,
"Content-Length: %d
\r\n\r\n
%s"
,
xmlStrlen
(
buff
),
buff
);
client
->
refbuf
->
len
=
ret
;
xmlFree
(
buff
);
client
->
respcode
=
status
;
fserve_add_client
(
client
,
NULL
);
}
else
{
char
*
fullpath_xslt_template
;
const
char
*
document_domain_path
;
ssize_t
fullpath_xslt_template_len
;
ice_config_t
*
config
;
config
=
config_get_config
();
switch
(
domain
)
{
case
DOCUMENT_DOMAIN_WEB
:
document_domain_path
=
config
->
webroot_dir
;
break
;
case
DOCUMENT_DOMAIN_ADMIN
:
document_domain_path
=
config
->
adminroot_dir
;
break
;
default:
config_release_config
();
ICECAST_LOG_ERROR
(
"Invalid document domain. Sending 500 to client %p"
,
client
);
client_send_500
(
client
,
"Invalid document domain."
);
return
;
break
;
}
fullpath_xslt_template_len
=
strlen
(
document_domain_path
)
+
strlen
(
xsl
)
+
strlen
(
PATH_SEPARATOR
)
+
1
;
fullpath_xslt_template
=
malloc
(
fullpath_xslt_template_len
);
snprintf
(
fullpath_xslt_template
,
fullpath_xslt_template_len
,
"%s%s%s"
,
document_domain_path
,
PATH_SEPARATOR
,
xsl
);
config_release_config
();
ICECAST_LOG_DEBUG
(
"Sending XSLT (%s)"
,
fullpath_xslt_template
);
xslt_transform
(
doc
,
fullpath_xslt_template
,
client
,
status
);
free
(
fullpath_xslt_template
);
}
xmlFreeDoc
(
doc
);
}
admin_format_t
client_get_admin_format_by_content_negotiation
(
client_t
*
client
)
{
const
char
*
pref
;
...
...
src/client.h
View file @
7fadb6ce
...
...
@@ -27,8 +27,15 @@
#include "refbuf.h"
#include "module.h"
#define CLIENT_DEFAULT_REPORT_XSL_TRANSFORMED "report-html.xsl"
#define CLIENT_DEFAULT_REPORT_XSL_PLAINTEXT "report-plaintext.xsl"
#define CLIENT_DEFAULT_ADMIN_FORMAT ADMIN_FORMAT_TRANSFORMED
typedef
enum
_document_domain_tag
{
DOCUMENT_DOMAIN_WEB
,
DOCUMENT_DOMAIN_ADMIN
}
document_domain_t
;
typedef
enum
_protocol_tag
{
ICECAST_PROTOCOL_HTTP
=
0
,
ICECAST_PROTOCOL_SHOUTCAST
...
...
@@ -133,6 +140,7 @@ void client_send_error_by_id(client_t *client, icecast_error_id_t id);
void
client_send_101
(
client_t
*
client
,
reuse_t
reuse
);
void
client_send_204
(
client_t
*
client
);
void
client_send_426
(
client_t
*
client
,
reuse_t
reuse
);
void
client_send_reportxml
(
client_t
*
client
,
reportxml_t
*
report
,
document_domain_t
domain
,
const
char
*
xsl
,
admin_format_t
admin_format_hint
,
int
status
);
admin_format_t
client_get_admin_format_by_content_negotiation
(
client_t
*
client
);
int
client_send_bytes
(
client_t
*
client
,
const
void
*
buf
,
unsigned
len
);
int
client_read_bytes
(
client_t
*
client
,
void
*
buf
,
unsigned
len
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment