Annotation of libaitio/src/url.c, revision 1.5.4.1

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: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>