/** * Defines functions for reading and writing XML content while handling HTTP * requests, using the dxml library: https://code.dlang.org/packages/dxml */ module handy_http_data.xml; import handy_http_primitives.request; import handy_http_primitives.response; import dxml.dom; import dxml.writer; import std.array : appender, Appender; import streams; /** * Reads an XML request body. * Params: * request = The request to read from. * Returns: The DOMEntity representing the XML payload. */ DOMEntity!string readXMLBody(ref ServerHttpRequest request) { string contentType = request.getHeaderAs!string("Content-Type"); if (!(contentType == "application/xml" || contentType == "text/xml")) { throw new HttpStatusException(HttpStatus.UNSUPPORTED_MEDIA_TYPE, "Non-XML Content-Type header."); } string bodyContent = request.readBodyAsString(false); return parseDOM(bodyContent); } /** * Writes an XML response body, by using the provided delegate function to * compose the XML tag tree using a provided XMLWriter. * * See https://jmdavisprog.com/docs/dxml/0.4.4/dxml_writer.html#.xmlWriter * Params: * response = The HTTP response to write to. * dg = The delegate function that will be called to generate the XML. */ void writeXMLBody(ref ServerHttpResponse response, void delegate(ref XMLWriter!(Appender!string)) dg) { import std.conv : to; auto writer = xmlWriter(appender!string()); dg(writer); string xmlContent = writer.output[]; response.headers.remove("Content-Type"); response.headers.add("Content-Type", "application/xml"); response.headers.add("Content-Length", to!string(xmlContent.length)); StreamResult result = response.outputStream.writeToStream(cast(ubyte[]) xmlContent); if (result.hasError) { StreamError err = result.error; throw new HttpStatusException(HttpStatus.INTERNAL_SERVER_ERROR, cast(string) err.message); } }