Annotation of embedaddon/libpdel/http/servlet/http_servlet_xml.c, revision 1.1.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>