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>