File:  [ELWIX - Embedded LightWeight unIX -] / libaitwww / src / url.c
Revision 1.4: download - view: text, annotated - select for diffs - revision graph
Thu May 30 09:25:35 2013 UTC (11 years ago) by misho
Branches: MAIN
CVS tags: www3_4, www3_3, www3_2, www3_1, WWW3_3, WWW3_2, WWW3_1, WWW3_0, HEAD
version 3.0

    1: /*************************************************************************
    2: * (C) 2010 AITNET ltd - Sofia/Bulgaria - <misho@aitnet.org>
    3: *  by Michael Pounov <misho@elwix.org>
    4: *
    5: * $Author: misho $
    6: * $Id: url.c,v 1.4 2013/05/30 09:25:35 misho Exp $
    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: 
   15: Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
   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: /*
   50:  * www_URLInit() - Init URL structure and free old one
   51:  *
   52:  * @url = Input URL
   53:  * return: -1 error or 0 ok
   54:  */
   55: 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: /*
   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
   82: www_URLGet(const char *csURL, struct tagIOURL * __restrict url)
   83: {
   84: 	char *pos, *at, *cl, *sl;
   85: 	int ret = 0;
   86: 
   87: 	if (!url)
   88: 		return -1;
   89: 	else
   90: 		www_URLInit(url);
   91: 
   92: 	AIT_SET_STR(&url->url_line, csURL);
   93: 	/* unescape URL */
   94: 	www_unescape(AIT_GET_STR(&url->url_line));
   95: 	/* Tech */
   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));
   99: 		return ret;
  100: 	} else {
  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))
  104: 			ret |= 1;
  105: 
  106: 		*pos = 0;
  107: 		pos += 3;	/* :// */
  108: 	}
  109: 
  110: 	/* User */
  111: 	if ((at = strchr(pos, '@'))) {
  112: 		*at++ = 0;
  113: 		/* Pass */
  114: 		if ((cl = strchr(pos, ':'))) {
  115: 			*cl++ = 0;
  116: 
  117: 			AIT_SET_LIKE(&url->url_pass, string, at - cl - 1, cl);
  118: 			if (AIT_LEN(&url->url_pass))
  119: 				ret |= 4;
  120: 		} else
  121: 			cl = at;
  122: 
  123: 		AIT_SET_LIKE(&url->url_user, string, cl - pos - 1, pos);
  124: 		if (AIT_LEN(&url->url_user))
  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: 
  139: 		AIT_SET_LIKE(&url->url_port, string, sl - cl - 1, cl);
  140: 		if (AIT_LEN(&url->url_port))
  141: 			ret |= 16;
  142: 	} else
  143: 		cl = sl;
  144: 
  145: 	AIT_SET_LIKE(&url->url_host, string, cl - pos - 1, pos);
  146: 	if (AIT_LEN(&url->url_host))
  147: 		ret |= 8;
  148: 
  149: 	pos = sl;
  150: 
  151: 	/* Args */
  152: 	if ((at = strchr(pos, '?'))) {
  153: 		*at++ = 0;
  154: 
  155: 		AIT_SET_LIKE(&url->url_args, string, strlen(at), at);
  156: 		if (AIT_LEN(&url->url_args))
  157: 			ret |= 64;
  158: 	} else
  159: 		at = pos + strlen(pos) + 1;
  160: 
  161: 	/* Path */
  162: 	AIT_SET_LIKE(&url->url_path, string, at - pos - 1, pos);
  163: 	if (AIT_LEN(&url->url_path))
  164: 		ret |= 32;
  165: 
  166: 	pos = at + strlen(at);
  167: 
  168: 	/* Reserved */
  169: 	url->url_reserved = (u_char*) pos;
  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
  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
  182:  */
  183: int
  184: www_URLGetFile(struct tagIOURL * __restrict url, ait_val_t * __restrict value)
  185: {
  186: 	char *pos, *psBuf;
  187: 	int ret = 0;
  188: 
  189: 	if (!url || !value)
  190: 		return -1;
  191: 
  192: 	psBuf = e_strdup(AIT_GET_STR(&url->url_path));
  193: 	if (!psBuf) {
  194: 		www_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
  195: 		return -1;
  196: 	} else
  197: 		AIT_FREE_VAL(value);
  198: 
  199: 	pos = strrchr(psBuf, '/');
  200: 	if (!pos) {
  201: 		/* whole string is filename */
  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: 	}
  211: 
  212: 	AIT_SET_STR(value, pos);
  213: 	e_free(psBuf);
  214: 	return ret;
  215: }
  216: 
  217: /*
  218:  * www_URLFree() - URL free structure
  219:  *
  220:  * @url = Input parsed URL
  221:  * return: none
  222:  */
  223: 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;
  234: 
  235: 	AIT_FREE_VAL(&url->url_line);
  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>