Annotation of embedaddon/libpdel/http/servlet/http_servlet_xml.c, revision 1.1
1.1 ! misho 1:
! 2: /*
! 3: * Copyright (c) 2001-2002 Packet Design, LLC.
! 4: * All rights reserved.
! 5: *
! 6: * Subject to the following obligations and disclaimer of warranty,
! 7: * use and redistribution of this software, in source or object code
! 8: * forms, with or without modifications are expressly permitted by
! 9: * Packet Design; provided, however, that:
! 10: *
! 11: * (i) Any and all reproductions of the source or object code
! 12: * must include the copyright notice above and the following
! 13: * disclaimer of warranties; and
! 14: * (ii) No rights are granted, in any manner or form, to use
! 15: * Packet Design trademarks, including the mark "PACKET DESIGN"
! 16: * on advertising, endorsements, or otherwise except as such
! 17: * appears in the above copyright notice or in the software.
! 18: *
! 19: * THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND
! 20: * TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO
! 21: * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING
! 22: * THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED
! 23: * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
! 24: * OR NON-INFRINGEMENT. PACKET DESIGN DOES NOT WARRANT, GUARANTEE,
! 25: * OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS
! 26: * OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY,
! 27: * RELIABILITY OR OTHERWISE. IN NO EVENT SHALL PACKET DESIGN BE
! 28: * LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE
! 29: * OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT,
! 30: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL
! 31: * DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF
! 32: * USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY THEORY OF
! 33: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
! 34: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
! 35: * THE USE OF THIS SOFTWARE, EVEN IF PACKET DESIGN IS ADVISED OF
! 36: * THE POSSIBILITY OF SUCH DAMAGE.
! 37: *
! 38: * Author: Archie Cobbs <archie@freebsd.org>
! 39: */
! 40:
! 41: #include <sys/types.h>
! 42: #include <sys/param.h>
! 43: #include <sys/stat.h>
! 44:
! 45: #include <netinet/in_systm.h>
! 46: #include <netinet/in.h>
! 47:
! 48: #include <stdlib.h>
! 49: #include <stdio.h>
! 50: #include <string.h>
! 51: #include <stdarg.h>
! 52: #include <syslog.h>
! 53: #include <errno.h>
! 54: #include <assert.h>
! 55:
! 56: #include <openssl/ssl.h>
! 57:
! 58: #include "structs/structs.h"
! 59: #include "structs/type/array.h"
! 60: #include "structs/xml.h"
! 61:
! 62: #include "http/http_defs.h"
! 63: #include "http/http_server.h"
! 64: #include "http/http_servlet.h"
! 65: #include "http/servlet/xml.h"
! 66: #include "util/typed_mem.h"
! 67:
! 68: #define MEM_TYPE "http_servlet_xml"
! 69:
! 70: struct http_servlet_xml_private {
! 71: struct http_servlet_xml_info info; /* copy of 'info' struct */
! 72: void *arg; /* handler arg */
! 73: void (*destroy)(void *); /* arg d'tor */
! 74: };
! 75:
! 76: /* Internal functions */
! 77: static http_servlet_run_t http_servlet_xml_run;
! 78: static http_servlet_destroy_t http_servlet_xml_destroy;
! 79:
! 80: /*
! 81: * Create a new http_servlet_xml servlet.
! 82: */
! 83: struct http_servlet *
! 84: http_servlet_xml_create(const struct http_servlet_xml_info *info,
! 85: void *arg, void (*destroy)(void *))
! 86: {
! 87: struct http_servlet_xml_private *priv;
! 88: struct http_servlet *servlet;
! 89:
! 90: /* Create servlet */
! 91: if ((servlet = MALLOC(MEM_TYPE, sizeof(*servlet))) == NULL)
! 92: return (NULL);
! 93: memset(servlet, 0, sizeof(*servlet));
! 94: servlet->run = http_servlet_xml_run;
! 95: servlet->destroy = http_servlet_xml_destroy;
! 96:
! 97: /* Create private info */
! 98: if ((priv = MALLOC(MEM_TYPE, sizeof(*priv))) == NULL)
! 99: goto fail;
! 100: memset(priv, 0, sizeof(*priv));
! 101: priv->arg = arg;
! 102: priv->destroy = destroy;
! 103: priv->info = *info;
! 104: priv->info.ptag = NULL;
! 105: priv->info.rtag = NULL;
! 106:
! 107: /* Copy info structure strings */
! 108: if ((priv->info.ptag = STRDUP(MEM_TYPE, info->ptag)) == NULL)
! 109: goto fail;
! 110: if ((priv->info.rtag = STRDUP(MEM_TYPE, info->rtag)) == NULL)
! 111: goto fail;
! 112:
! 113: /* Done */
! 114: servlet->arg = priv;
! 115: return (servlet);
! 116:
! 117: fail:
! 118: /* Clean up after failure */
! 119: if (priv != NULL) {
! 120: FREE(MEM_TYPE, (char *)priv->info.ptag);
! 121: FREE(MEM_TYPE, (char *)priv->info.rtag);
! 122: FREE(MEM_TYPE, priv);
! 123: }
! 124: FREE(MEM_TYPE, servlet);
! 125: return (NULL);
! 126: }
! 127:
! 128: /*
! 129: * XML message processing servlet.
! 130: */
! 131: static int
! 132: http_servlet_xml_run(struct http_servlet *servlet,
! 133: struct http_request *req, struct http_response *resp)
! 134: {
! 135: struct http_servlet_xml_private *const priv = servlet->arg;
! 136: struct http_servlet_xml_info *const info = &priv->info;
! 137: const char *method = http_request_get_method(req);
! 138: FILE *const input = http_request_get_input(req);
! 139: FILE *const output = http_response_get_output(resp, 1);
! 140: void *payload = NULL;
! 141: void *reply = NULL;
! 142: char *attrs = NULL;
! 143: char *rattrs = NULL;
! 144:
! 145: /* Check method */
! 146: if (!((info->allow_post && strcmp(method, HTTP_METHOD_POST) == 0)
! 147: || (info->allow_get && strcmp(method, HTTP_METHOD_GET) == 0))) {
! 148: http_response_send_error(resp,
! 149: HTTP_STATUS_METHOD_NOT_ALLOWED, NULL);
! 150: return (1);
! 151: }
! 152:
! 153: /* Get request structure (POST only) */
! 154: if (strcmp(method, HTTP_METHOD_POST) == 0) {
! 155: if ((payload = MALLOC(TYPED_MEM_TEMP,
! 156: info->ptype->size)) == NULL) {
! 157: (*info->logger)(LOG_ERR, "%s: %s",
! 158: "malloc", strerror(errno));
! 159: goto server_error;
! 160: }
! 161: if (structs_xml_input(info->ptype, info->ptag, &attrs,
! 162: TYPED_MEM_TEMP, input, payload, STRUCTS_XML_UNINIT,
! 163: info->logger) == -1) {
! 164: (*info->logger)(LOG_ERR, "%s: %s",
! 165: "structs_xml_input", strerror(errno));
! 166: FREE(TYPED_MEM_TEMP, payload);
! 167: payload = NULL;
! 168: goto server_error;
! 169: }
! 170: #ifdef XML_RPC_DEBUG
! 171: printf("%s: read this XML input from http_request %p:\n",
! 172: __FUNCTION__, req);
! 173: (void)structs_xml_output(info->ptype, info->ptag,
! 174: attrs, payload, stdout, NULL, 0);
! 175: #endif
! 176: }
! 177:
! 178: /* Invoke handler */
! 179: if ((reply = (*info->handler)(priv->arg, req,
! 180: payload, attrs, &rattrs, TYPED_MEM_TEMP)) == NULL) {
! 181: (*info->logger)(LOG_ERR, "%s: %s",
! 182: "error from handler", strerror(errno));
! 183: goto server_error;
! 184: }
! 185:
! 186: /* Set MIME type */
! 187: http_response_set_header(resp, 0, HTTP_HEADER_CONTENT_TYPE, "text/xml");
! 188:
! 189: #ifdef XML_RPC_DEBUG
! 190: printf("%s: writing this XML output back to http_response %p:\n",
! 191: __FUNCTION__, resp);
! 192: (void)structs_xml_output(info->rtype,
! 193: info->rtag, rattrs, reply, stdout, NULL, info->flags);
! 194: #endif
! 195:
! 196: /* Write back response */
! 197: if (structs_xml_output(info->rtype, info->rtag,
! 198: rattrs, reply, output, NULL, info->flags) == -1) {
! 199: (*info->logger)(LOG_ERR, "%s: %s",
! 200: "error writing output", strerror(errno));
! 201: }
! 202: goto done;
! 203:
! 204: server_error:
! 205: http_response_send_errno_error(resp);
! 206:
! 207: done:
! 208: /* Clean up */
! 209: if (payload != NULL) {
! 210: structs_free(info->ptype, NULL, payload);
! 211: FREE(TYPED_MEM_TEMP, payload);
! 212: }
! 213: if (reply != NULL) {
! 214: structs_free(info->rtype, NULL, reply);
! 215: FREE(TYPED_MEM_TEMP, reply);
! 216: }
! 217: FREE(TYPED_MEM_TEMP, attrs);
! 218: FREE(TYPED_MEM_TEMP, rattrs);
! 219: return (1);
! 220: }
! 221:
! 222: static void
! 223: http_servlet_xml_destroy(struct http_servlet *servlet)
! 224: {
! 225: struct http_servlet_xml_private *const priv = servlet->arg;
! 226:
! 227: if (priv->destroy != NULL)
! 228: (*priv->destroy)(priv->arg);
! 229: FREE(MEM_TYPE, (char *)priv->info.ptag);
! 230: FREE(MEM_TYPE, (char *)priv->info.rtag);
! 231: FREE(MEM_TYPE, priv);
! 232: FREE(MEM_TYPE, servlet);
! 233: }
! 234:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>