Annotation of libaitwww/src/url.c, revision 1.3.4.1
1.2 misho 1: /*************************************************************************
2: * (C) 2010 AITNET ltd - Sofia/Bulgaria - <misho@aitnet.org>
3: * by Michael Pounov <misho@elwix.org>
4: *
5: * $Author: misho $
1.3.4.1 ! misho 6: * $Id: url.c,v 1.3 2012/09/20 14:19:45 misho Exp $
1.2 misho 7: *
8: **************************************************************************
9: The ELWIX and AITNET software is distributed under the following
10: terms:
11:
12: All of the documentation and software included in the ELWIX and AITNET
13: Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
14:
1.3.4.1 ! misho 15: Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
1.2 misho 16: by Michael Pounov <misho@elwix.org>. All rights reserved.
17:
18: Redistribution and use in source and binary forms, with or without
19: modification, are permitted provided that the following conditions
20: are met:
21: 1. Redistributions of source code must retain the above copyright
22: notice, this list of conditions and the following disclaimer.
23: 2. Redistributions in binary form must reproduce the above copyright
24: notice, this list of conditions and the following disclaimer in the
25: documentation and/or other materials provided with the distribution.
26: 3. All advertising materials mentioning features or use of this software
27: must display the following acknowledgement:
28: This product includes software developed by Michael Pounov <misho@elwix.org>
29: ELWIX - Embedded LightWeight unIX and its contributors.
30: 4. Neither the name of AITNET nor the names of its contributors
31: may be used to endorse or promote products derived from this software
32: without specific prior written permission.
33:
34: THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
35: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37: ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
38: FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39: DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40: OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43: OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44: SUCH DAMAGE.
45: */
46: #include "global.h"
47:
48:
49: /*
1.3 misho 50: * www_URLInit() - Init URL structure and free old one
51: *
52: * @url = Input URL
53: * return: -1 error or 0 ok
54: */
55: inline int
56: www_URLInit(struct tagIOURL * __restrict url)
57: {
58: if (!url)
59: return -1;
60: else
61: memset(url, 0, sizeof(struct tagIOURL));
62:
63: AIT_INIT_VAL2(&url->url_tech, string);
64: AIT_INIT_VAL2(&url->url_user, string);
65: AIT_INIT_VAL2(&url->url_pass, string);
66: AIT_INIT_VAL2(&url->url_host, string);
67: AIT_INIT_VAL2(&url->url_port, string);
68: AIT_INIT_VAL2(&url->url_path, string);
69: AIT_INIT_VAL2(&url->url_args, string);
70: return 0;
71: }
72:
73: /*
1.2 misho 74: * www_URLGet() - Parse and get data from input URL
75: *
76: * @csURL = Input URL line
77: * @url = Output parsed URL
78: * return: 0 error format not find tech:// and return URL like path;
79: * -1 error:: can`t read; >0 ok, up bits for known elements
80: */
81: int
1.3 misho 82: www_URLGet(const char *csURL, struct tagIOURL * __restrict url)
1.2 misho 83: {
84: char *pos, *at, *cl, *sl;
85: int ret = 0;
86:
87: if (!url)
88: return -1;
89: else
1.3 misho 90: www_URLInit(url);
1.2 misho 91:
1.3 misho 92: AIT_SET_STR(&url->url_line, csURL);
93: /* unescape URL */
94: www_unescape(AIT_GET_STR(&url->url_line));
1.2 misho 95: /* Tech */
1.3 misho 96: if (!(pos = strstr(AIT_GET_STR(&url->url_line), "://"))) {
97: AIT_SET_LIKE(&url->url_path, string,
98: AIT_LEN(&url->url_line), AIT_ADDR(&url->url_line));
1.2 misho 99: return ret;
100: } else {
1.3 misho 101: AIT_SET_LIKE(&url->url_tech, string,
102: pos - AIT_GET_STR(&url->url_line), AIT_ADDR(&url->url_line));
103: if (AIT_LEN(&url->url_tech))
1.2 misho 104: ret |= 1;
105:
106: *pos = 0;
1.3 misho 107: pos += 3; /* :// */
1.2 misho 108: }
109:
110: /* User */
111: if ((at = strchr(pos, '@'))) {
112: *at++ = 0;
113: /* Pass */
114: if ((cl = strchr(pos, ':'))) {
115: *cl++ = 0;
116:
1.3 misho 117: AIT_SET_LIKE(&url->url_pass, string, at - cl - 1, cl);
118: if (AIT_LEN(&url->url_pass))
1.2 misho 119: ret |= 4;
120: } else
121: cl = at;
122:
1.3 misho 123: AIT_SET_LIKE(&url->url_user, string, cl - pos - 1, pos);
124: if (AIT_LEN(&url->url_user))
1.2 misho 125: ret |= 2;
126:
127: pos = at;
128: }
129:
130: /* Host */
131: if ((sl = strchr(pos, '/')))
132: *sl++ = 0;
133: else
134: sl = pos + strlen(pos) + 1;
135: /* Port */
136: if ((cl = strchr(pos, ':'))) {
137: *cl++ = 0;
138:
1.3 misho 139: AIT_SET_LIKE(&url->url_port, string, sl - cl - 1, cl);
140: if (AIT_LEN(&url->url_port))
1.2 misho 141: ret |= 16;
142: } else
143: cl = sl;
144:
1.3 misho 145: AIT_SET_LIKE(&url->url_host, string, cl - pos - 1, pos);
146: if (AIT_LEN(&url->url_host))
1.2 misho 147: ret |= 8;
148:
149: pos = sl;
150:
151: /* Args */
152: if ((at = strchr(pos, '?'))) {
153: *at++ = 0;
154:
1.3 misho 155: AIT_SET_LIKE(&url->url_args, string, strlen(at), at);
156: if (AIT_LEN(&url->url_args))
1.2 misho 157: ret |= 64;
158: } else
159: at = pos + strlen(pos) + 1;
160:
161: /* Path */
1.3 misho 162: AIT_SET_LIKE(&url->url_path, string, at - pos - 1, pos);
163: if (AIT_LEN(&url->url_path))
1.2 misho 164: ret |= 32;
165:
166: pos = at + strlen(at);
167:
168: /* Reserved */
1.3 misho 169: url->url_reserved = (u_char*) pos;
1.2 misho 170: if (*pos)
171: ret |= 128;
172:
173: return ret;
174: }
175:
176: /*
177: * www_URLGetFile() - Get file from parsed URL
178: *
179: * @url = Input parsed URL
1.3 misho 180: * @value = Return filename, if not specified file in url path, replace with /
181: * return: -1 error, 0 filename from path, 1 filename or 2 not specified filename
1.2 misho 182: */
183: int
1.3 misho 184: www_URLGetFile(struct tagIOURL * __restrict url, ait_val_t * __restrict value)
1.2 misho 185: {
186: char *pos, *psBuf;
1.3 misho 187: int ret = 0;
1.2 misho 188:
1.3 misho 189: if (!url || !value)
1.2 misho 190: return -1;
191:
1.3.4.1 ! misho 192: psBuf = e_strdup(AIT_GET_STR(&url->url_path));
1.2 misho 193: if (!psBuf) {
1.3.4.1 ! misho 194: www_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
1.2 misho 195: return -1;
1.3 misho 196: } else
197: AIT_FREE_VAL(value);
1.2 misho 198:
199: pos = strrchr(psBuf, '/');
200: if (!pos) {
201: /* whole string is filename */
1.3 misho 202: pos = psBuf;
203: ret = 1;
204: } else
205: *pos++ = 0;
206: /* If not specified file in path, default replace to / */
207: if (!*pos) {
208: pos = "/";
209: ret = 2;
210: }
1.2 misho 211:
1.3 misho 212: AIT_SET_STR(value, pos);
1.3.4.1 ! misho 213: e_free(psBuf);
1.3 misho 214: return ret;
215: }
1.2 misho 216:
1.3 misho 217: /*
218: * www_URLFree() - URL free structure
219: *
220: * @url = Input parsed URL
221: * return: none
222: */
223: inline void
224: www_URLFree(struct tagIOURL * __restrict url)
225: {
226: AIT_FREE_VAL(&url->url_tech);
227: AIT_FREE_VAL(&url->url_user);
228: AIT_FREE_VAL(&url->url_pass);
229: AIT_FREE_VAL(&url->url_host);
230: AIT_FREE_VAL(&url->url_port);
231: AIT_FREE_VAL(&url->url_path);
232: AIT_FREE_VAL(&url->url_args);
233: url->url_reserved = NULL;
1.2 misho 234:
1.3 misho 235: AIT_FREE_VAL(&url->url_line);
1.2 misho 236: }
237:
238: /*
239: * www_XMLGet() - Parse and get data from input XML request string
240: * [ns:]container[|attribute[=value]][?data]
241: *
242: * @csXML = Input XML request line
243: * @xml = Output parsed XML request
244: * return: 0 error format incorrect, -1 error:: can`t read; >0 ok readed elements bits
245: */
246: int
247: www_XMLGet(const char *csXML, struct tagReqXML *xml)
248: {
249: char *pos, *p, *end;
250: int ret = 0;
251:
252: if (!csXML || !xml)
253: return -1;
254: else
255: memset(xml, 0, sizeof *xml);
256:
257: strlcpy((char*) xml->xml_line, csXML, BUFSIZ);
258: /* if namespace present */
259: if ((pos = strchr((char*) xml->xml_line, ':'))) {
260: xml->xml_namespace.value = (char*) xml->xml_line;
261: xml->xml_namespace.vallen = pos - (char*) xml->xml_line;
262: if (xml->xml_namespace.vallen)
263: ret |= 1;
264: *pos++ = 0;
265: } else
266: pos = (char*) xml->xml_line;
267: /* if container is path */
268: if (*pos == '/') {
269: xml->xml_node.path.value = pos;
270: xml->xml_node.path.vallen = strlen(pos);
271: if (!xml->xml_node.path.vallen)
272: ret = 0;
273: else
274: ret |= 32;
275: return ret;
276: } else {
277: /* container */
278: xml->xml_node.container.value = pos;
279: xml->xml_node.container.vallen = strlen(pos);
280: if (!xml->xml_node.container.vallen)
281: return 0;
282: else
283: ret |= 2;
284: }
285: end = strchr(pos, '?');
286: /* if attribute present */
287: if (pos && (p = strchr(pos, '|')) && (!end || end > p)) {
288: pos = p;
289: *pos++ = 0;
290: xml->xml_node.container.vallen = strlen(xml->xml_node.container.value);
291: if (!xml->xml_node.container.vallen)
292: return 0;
293:
294: xml->xml_attribute.value = pos;
295: xml->xml_attribute.vallen = strlen(pos);
296: if (xml->xml_attribute.vallen)
297: ret |= 4;
298: }
299: /* if value present */
300: if (pos && (p = strchr(pos, '=')) && (!end || end > p)) {
301: if (!(ret & 4))
302: return 0;
303: else
304: pos = p;
305: *pos++ = 0;
306: xml->xml_attribute.vallen = strlen(xml->xml_attribute.value);
307: if (!xml->xml_attribute.vallen)
308: return 0;
309:
310: xml->xml_value.value = pos;
311: xml->xml_value.vallen = strlen(pos);
312: if (xml->xml_value.vallen)
313: ret |= 8;
314: }
315: /* if data present */
316: if (pos && end) {
317: if (ret < 2)
318: return 0;
319: else
320: pos = end;
321: *pos++ = 0;
322: if (ret & 8) {
323: xml->xml_value.vallen = strlen(xml->xml_value.value);
324: if (!xml->xml_value.vallen)
325: return 0;
326: } else if (ret & 4) {
327: xml->xml_attribute.vallen = strlen(xml->xml_attribute.value);
328: if (!xml->xml_attribute.vallen)
329: return 0;
330: } else if (ret & 2) {
331: xml->xml_node.container.vallen = strlen(xml->xml_node.container.value);
332: if (!xml->xml_node.container.vallen)
333: return 0;
334: } else
335: return 0;
336:
337: xml->xml_data.value = pos;
338: xml->xml_data.vallen = strlen(pos);
339: if (xml->xml_data.vallen)
340: ret |= 16;
341: }
342:
343: return ret;
344: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>