Annotation of libaitio/src/url.c, revision 1.5.4.3
1.2 misho 1: /*************************************************************************
1.5.4.2 misho 2: * (C) 2010 AITNET ltd - Sofia/Bulgaria - <misho@aitnet.org>
3: * by Michael Pounov <misho@elwix.org>
1.2 misho 4: *
5: * $Author: misho $
1.5.4.3 ! misho 6: * $Id: url.c,v 1.5.4.2 2011/04/19 22:32:16 misho Exp $
1.2 misho 7: *
1.5.4.2 misho 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:
15: Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
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.
1.5.4.3 ! misho 30: 4. Neither the name of AITNET nor the names of its contributors
1.5.4.2 misho 31: may be used to endorse or promote products derived from this software
32: without specific prior written permission.
33:
1.5.4.3 ! misho 34: THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
1.5.4.2 misho 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: */
1.2 misho 46: #include "global.h"
47:
48:
49: /*
50: * ioURLGet() Parse and get data from input URL
51: * @csURL = Input URL line
52: * @url = Output parsed URL
53: * return: 0 error format not find tech:// and return URL like path;
54: -1 error:: can`t read; >0 ok, up bits for known elements
55: */
1.4 misho 56: int
57: ioURLGet(const char *csURL, struct tagIOURL *url)
1.2 misho 58: {
59: char *pos, *at, *cl, *sl;
60: int ret = 0;
61:
62: if (!url)
63: return -1;
64: else
65: memset(url, 0, sizeof(*url));
66:
67: strlcpy((char*) url->url_line, csURL, BUFSIZ);
68: // Tech
69: if (!(pos = strstr((char*) url->url_line, "://"))) {
70: url->url_path.vallen = strlen((char*) url->url_line);
71: url->url_path.value = (char*) url->url_line;
72: return ret;
73: } else {
74: url->url_tech.value = (char*) url->url_line;
75: url->url_tech.vallen = pos - (char*) url->url_line;
76: if (url->url_tech.vallen)
77: ret |= 1;
78:
79: *pos = 0;
80: pos += 3;
81: }
82:
83: // User
84: if ((at = strchr(pos, '@'))) {
85: *at++ = 0;
86: // Pass
87: if ((cl = strchr(pos, ':'))) {
88: *cl++ = 0;
89:
90: url->url_pass.value = cl;
91: url->url_pass.vallen = at - cl - 1;
92: if (url->url_pass.vallen)
93: ret |= 4;
94: } else
95: cl = at;
96:
97: url->url_user.value = pos;
98: url->url_user.vallen = cl - pos - 1;
99: if (url->url_user.vallen)
100: ret |= 2;
101:
102: pos = at;
103: }
104:
105: // Host
106: if ((sl = strchr(pos, '/')))
107: *sl++ = 0;
108: else
109: sl = pos + strlen(pos) + 1;
110: // Port
111: if ((cl = strchr(pos, ':'))) {
112: *cl++ = 0;
113:
114: url->url_port.value = cl;
115: url->url_port.vallen = sl - cl - 1;
116: if (url->url_port.vallen)
117: ret |= 16;
118: } else
119: cl = sl;
120:
121: url->url_host.value = pos;
122: url->url_host.vallen = cl - pos - 1;
123: if (url->url_host.vallen)
124: ret |= 8;
125:
126: pos = sl;
127:
128: // Args
129: if ((at = strchr(pos, '?'))) {
130: *at++ = 0;
131:
132: url->url_args.value = at;
133: url->url_args.vallen = strlen(at);
134: if (url->url_args.vallen)
135: ret |= 64;
136: } else
137: at = pos + strlen(pos) + 1;
138:
139: // Path
140: url->url_path.value = pos;
141: url->url_path.vallen = at - pos - 1;
142: if (url->url_path.vallen)
143: ret |= 32;
144:
145: pos = at + strlen(at);
146:
147: // Reserved
148: url->url_reserved = pos;
149: if (*pos)
150: ret |= 128;
151:
152: return ret;
153: }
154:
155: /*
156: * io_Path2File() Parse and make path/filename pair
157: * @csArgs = Input argument line
158: * @psPath = Output Path, if ==NULL path not returned
159: * @pathLen = Size of path array
160: * @psFile = Output File
161: * @fileLen = Size of file array
162: * return: 0 error format; -1 error:: can`t read; >0 ok, number of readed items
163: */
1.4 misho 164: inline int
165: io_Path2File(const char * __restrict csArgs, char * __restrict psPath, int pathLen,
1.2 misho 166: char * __restrict psFile, int fileLen)
167: {
168: char *pos, *psBuf;
169:
170: if (!csArgs || !psFile || !fileLen)
171: return -1;
172: if (psPath && !pathLen)
173: return -1;
174: else
175: memset(psPath, 0, pathLen);
176: psBuf = strdup(csArgs);
177: if (!psBuf) {
178: LOGERR;
179: return -1;
180: }
181:
182: pos = strrchr(psBuf, '/');
183: if (!pos) {
184: strlcpy(psFile, psBuf, fileLen);
185:
186: free(psBuf);
187: return 1;
188: } else
189: *pos++ = 0;
190:
191: strlcpy(psFile, pos, fileLen);
192: if (psPath)
193: strlcpy(psPath, psBuf, pathLen);
194:
195: free(psBuf);
196: return 2;
197: }
198:
199: /*
200: * ioURLGetValue() Get value from parsed URL
201: * @url = Input parsed URL
202: * @csAttr = Attribute for search
203: * @psValue = Return value of attribute, if ==NULL only check for existence of attribute
204: * @valLen = Size of psValue array
205: * return: 0 error attribute not find; -1 error:: can`t read; >0 ok, find at position
206: */
1.4 misho 207: int
208: ioURLGetValue(struct tagIOURL *url, const char *csAttr, char * __restrict psValue, int valLen)
1.2 misho 209: {
210: register int i, ret = 0;
1.5.4.1 misho 211: char szBuf[BUFSIZ], szElem[2][BUFSIZ];
1.2 misho 212: int len;
1.5.4.1 misho 213: array_t *items;
1.2 misho 214:
215: if (!url || !csAttr)
216: return -1;
217:
218: strlcpy(szBuf, url->url_args.value, BUFSIZ);
1.5.4.1 misho 219: if ((len = io_arrayMake(szBuf, 0, "&", &items)) < 1)
1.2 misho 220: return ret;
221:
1.5.4.1 misho 222: for (i = 0; i < len && items->arr_data[i]; i++) {
223: if (io_MakeAV(items->arr_data[i], "=", szElem[0], BUFSIZ, szElem[1], BUFSIZ) < 1)
1.2 misho 224: continue;
225:
226: if (!strcmp(szElem[0], csAttr)) {
227: ret = i + 1;
228: if (psValue && valLen)
229: strlcpy(psValue, szElem[1], valLen);
230: break;
231: }
232: }
233:
1.5.4.1 misho 234: io_arrayDestroy(&items);
1.2 misho 235: return ret;
236: }
237:
238: /*
239: * ioURLGetFile() Get file from parsed URL
240: * @url = Input parsed URL
241: * @psValue = Return filename, if not specified file in url path, replace with /
242: * @valLen = Size of psValue array
243: * return: -1 error:: can`t read; 0 ok
244: */
1.4 misho 245: int
246: ioURLGetFile(struct tagIOURL *url, char * __restrict psValue, int valLen)
1.2 misho 247: {
248: if (!url || !psValue || !valLen)
249: return -1;
250:
251: if (io_Path2File(url->url_path.value, NULL, 0, psValue, valLen) < 1)
252: return -1;
253:
254: // If not specified file in path, default replace to /
255: if (!*psValue)
256: strlcpy(psValue, "/", valLen);
257: return 0;
258: }
1.4 misho 259:
260: // ------------------------------------------
261:
262: /*
263: * ioXMLGet() Parse and get data from input XML request string [ns:]container[|attribute[=value]][?data]
264: * @csXML = Input XML request line
265: * @xml = Output parsed XML request
266: * return: 0 error format incorrect, -1 error:: can`t read; >0 ok readed elements bits
267: */
268: int
269: ioXMLGet(const char *csXML, struct tagReqXML *xml)
270: {
271: char *pos, *p, *end;
272: int ret = 0;
273:
274: if (!csXML || !xml)
275: return -1;
276: else
277: memset(xml, 0, sizeof *xml);
278:
279: strlcpy((char*) xml->xml_line, csXML, BUFSIZ);
280: // if namespace present
281: if ((pos = strchr((char*) xml->xml_line, ':'))) {
282: xml->xml_namespace.value = (char*) xml->xml_line;
283: xml->xml_namespace.vallen = pos - (char*) xml->xml_line;
284: if (xml->xml_namespace.vallen)
285: ret |= 1;
286: *pos++ = 0;
287: } else
288: pos = (char*) xml->xml_line;
289: // if container is path
290: if (*pos == '/') {
291: xml->xml_node.path.value = pos;
292: xml->xml_node.path.vallen = strlen(pos);
293: if (!xml->xml_node.path.vallen)
294: ret = 0;
295: else
296: ret |= 32;
297: return ret;
298: } else {
299: // container
300: xml->xml_node.container.value = pos;
301: xml->xml_node.container.vallen = strlen(pos);
302: if (!xml->xml_node.container.vallen)
303: return 0;
304: else
305: ret |= 2;
306: }
307: end = strchr(pos, '?');
308: // if attribute present
309: if (pos && (p = strchr(pos, '|')) && (!end || end > p)) {
310: pos = p;
311: *pos++ = 0;
312: xml->xml_node.container.vallen = strlen(xml->xml_node.container.value);
313: if (!xml->xml_node.container.vallen)
314: return 0;
315:
316: xml->xml_attribute.value = pos;
317: xml->xml_attribute.vallen = strlen(pos);
318: if (xml->xml_attribute.vallen)
319: ret |= 4;
320: }
321: // if value present
322: if (pos && (p = strchr(pos, '=')) && (!end || end > p)) {
323: if (!(ret & 4))
324: return 0;
325: else
326: pos = p;
327: *pos++ = 0;
328: xml->xml_attribute.vallen = strlen(xml->xml_attribute.value);
329: if (!xml->xml_attribute.vallen)
330: return 0;
331:
332: xml->xml_value.value = pos;
333: xml->xml_value.vallen = strlen(pos);
334: if (xml->xml_value.vallen)
335: ret |= 8;
336: }
337: // if data present
338: if (pos && end) {
339: if (ret < 2)
340: return 0;
341: else
342: pos = end;
343: *pos++ = 0;
344: if (ret & 8) {
345: xml->xml_value.vallen = strlen(xml->xml_value.value);
346: if (!xml->xml_value.vallen)
347: return 0;
348: } else if (ret & 4) {
349: xml->xml_attribute.vallen = strlen(xml->xml_attribute.value);
350: if (!xml->xml_attribute.vallen)
351: return 0;
352: } else if (ret & 2) {
353: xml->xml_node.container.vallen = strlen(xml->xml_node.container.value);
354: if (!xml->xml_node.container.vallen)
355: return 0;
356: } else
357: return 0;
358:
359: xml->xml_data.value = pos;
360: xml->xml_data.vallen = strlen(pos);
361: if (xml->xml_data.vallen)
362: ret |= 16;
363: }
364:
365: return ret;
366: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>