Annotation of libaitwww/src/url.c, revision 1.4

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.4     ! misho       6: * $Id: url.c,v 1.3.4.2 2013/05/26 20:30:43 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.4     ! 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:  */
1.4     ! misho      55: int
1.3       misho      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.4     ! misho     192:        psBuf = e_strdup(AIT_GET_STR(&url->url_path));
1.2       misho     193:        if (!psBuf) {
1.4     ! 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.4     ! 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:  */
1.4     ! misho     223: void
1.3       misho     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>