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