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>