Back to index

avfs  1.0.1
Defines | Functions | Variables
uri.c File Reference
#include "config.h"
#include <ctype.h>
#include <stdio.h>
#include "http_utils.h"
#include "string_utils.h"
#include "uri.h"
#include "ne_alloc.h"

Go to the source code of this file.

Defines

#define SP   0 /* space = <US-ASCII coded character 20 hexadecimal> */
#define CO   0 /* control = <US-ASCII coded characters 00-1F and 7F hexadecimal> */
#define DE   0 /* delims = "<" | ">" | "#" | "%" | <"> */
#define UW   0 /* unwise = "{" | "}" | "|" | "\" | "^" | "[" | "]" | "`" */
#define MA   1 /* mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" */
#define AN   2 /* alphanum = alpha | digit */
#define RE   2 /* reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | "," */
#define ESCAPE(ch)

Functions

char * uri_parent (const char *uri)
int uri_has_trailing_slash (const char *uri)
const char * uri_abspath (const char *uri)
int uri_parse (const char *uri, struct uri *parsed, const struct uri *defaults)
void uri_free (struct uri *uri)
char * uri_absolute (const char *uri, const char *scheme, const char *hostport)
char * uri_unescape (const char *uri)
char * uri_abspath_escape (const char *abs_path)
int uri_compare (const char *a, const char *b)
int uri_childof (const char *parent, const char *child)

Variables

static const char uri_chars [128]

Define Documentation

#define AN   2 /* alphanum = alpha | digit */

Definition at line 195 of file uri.c.

#define CO   0 /* control = <US-ASCII coded characters 00-1F and 7F hexadecimal> */

Definition at line 191 of file uri.c.

#define DE   0 /* delims = "<" | ">" | "#" | "%" | <"> */

Definition at line 192 of file uri.c.

#define ESCAPE (   ch)
Value:
(((const signed char)(ch) < 0 || \
              uri_chars[(unsigned int)(ch)] == 0))

Definition at line 210 of file uri.c.

#define MA   1 /* mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" */

Definition at line 194 of file uri.c.

#define RE   2 /* reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | "," */

Definition at line 196 of file uri.c.

#define SP   0 /* space = <US-ASCII coded character 20 hexadecimal> */

Definition at line 190 of file uri.c.

#define UW   0 /* unwise = "{" | "}" | "|" | "\" | "^" | "[" | "]" | "`" */

Definition at line 193 of file uri.c.


Function Documentation

char* uri_absolute ( const char *  uri,
const char *  scheme,
const char *  hostport 
)

Definition at line 145 of file uri.c.

{
    char *ret;
    /* Is it absolute already? */
    if (strncmp(uri, scheme, strlen(scheme)) == 0)  {
       /* Yes it is */
       ret = ne_strdup(uri);
    } else {
       /* Oh no it isn't */
       CONCAT3(ret, scheme, hostport, uri);
    }
    return ret;
}
const char* uri_abspath ( const char *  uri)

Definition at line 69 of file uri.c.

{
    const char *ret;
    /* Look for the scheme: */
    ret = strstr(uri, "://");
    if (ret == NULL) {
       /* No scheme */
       ret = uri;
    } else {
       /* Look for the abs_path */
       ret = strchr(ret+3, '/');
       if (ret == NULL) {
           /* Uh-oh */
           ret = uri;
       }
    }
    return ret;
}
char* uri_abspath_escape ( const char *  abs_path)

Definition at line 224 of file uri.c.

{
    const char *pnt;
    char *ret, *retpos;
    int count = 0;
    for (pnt = abs_path; *pnt != '\0'; pnt++) {
       if (ESCAPE(*pnt)) {
           count++;
       }
    }
    if (count == 0) {
       return ne_strdup(abs_path);
    }
    /* An escaped character is "%xx", i.e., two MORE
     * characters than the original string */
    retpos = ret = ne_malloc(strlen(abs_path) + 2*count + 1);
    for (pnt = abs_path; *pnt != '\0'; pnt++) {
       if (ESCAPE(*pnt)) {
           /* Escape it - %<hex><hex> */
           sprintf(retpos, "%%%02x", (unsigned char) *pnt);
           retpos += 3;
       } else {
           /* It's cool */
           *retpos++ = *pnt;
       }
    }
    *retpos = '\0';
    return ret;
}
int uri_childof ( const char *  parent,
const char *  child 
)

Definition at line 280 of file uri.c.

{
    char *root = ne_strdup(child);
    int ret;
    if (strlen(parent) >= strlen(child)) {
       ret = 0;
    } else {
       /* root is the first of child, equal to length of parent */
       root[strlen(parent)] = '\0';
       ret = (uri_compare(parent, root) == 0);
    }
    free(root);
    return ret;
}
int uri_compare ( const char *  a,
const char *  b 
)

Definition at line 257 of file uri.c.

{
    int ret = strcasecmp(a, b);
    if (ret) {
       /* This logic says: "If the lengths of the two URIs differ by
        * exactly one, and the LONGER of the two URIs has a trailing
        * slash and the SHORTER one DOESN'T, then..." */
       int traila = uri_has_trailing_slash(a),
           trailb = uri_has_trailing_slash(b),
           lena = strlen(a), lenb = strlen(b);
       if (traila != trailb && abs(lena - lenb) == 1 &&
           ((traila && lena > lenb) || (trailb && lenb > lena))) {
           /* Compare them, ignoring the trailing slash on the longer
            * URI */
           if (strncasecmp(a, b, min(lena, lenb)) == 0)
              ret = 0;
       }
    }
    return ret;
}
void uri_free ( struct uri uri)

Definition at line 137 of file uri.c.

{
    HTTP_FREE(uri->host);
    HTTP_FREE(uri->path);
    HTTP_FREE(uri->scheme);
}
int uri_has_trailing_slash ( const char *  uri)

Definition at line 64 of file uri.c.

{
     return (uri[strlen(uri)-1] == '/');
}
char* uri_parent ( const char *  uri)

Definition at line 42 of file uri.c.

{
    const char *pnt;
    char *ret;
    pnt = uri+strlen(uri)-1;
    while (*(--pnt) != '/' && pnt >= uri) /* noop */;
    if (pnt < uri) {
       /* not a valid absPath */
       return NULL;
    }
    /*  uri    
     *   V
     *   |---|
     *   /foo/bar/
     */
    ret = ne_malloc((pnt - uri) + 2);
    memcpy(ret, uri, (pnt - uri) + 1);
    ret[1+(pnt-uri)] = '\0';
    pnt++;
    return ret;
}
int uri_parse ( const char *  uri,
struct uri parsed,
const struct uri defaults 
)

Definition at line 89 of file uri.c.

{
    const char *pnt, *slash, *colon;

    parsed->port = -1;
    parsed->host = NULL;
    parsed->path = NULL;
    parsed->scheme = NULL;

    pnt = strstr(uri, "://");
    if (pnt) {
       parsed->scheme = ne_strndup(uri, pnt - uri);
       pnt += 3; /* start of hostport segment */
    } else {
       pnt = uri;
       if (defaults && defaults->scheme != NULL) {
           parsed->scheme = ne_strdup(defaults->scheme);
       }
    }
    
    slash = strchr(pnt, '/');
    colon = strchr(pnt, ':');
    if (slash == NULL) {
       parsed->path = ne_strdup("/");
       if (colon == NULL) {
           if (defaults) parsed->port = defaults->port;
           parsed->host = ne_strdup(pnt);
       } else {
           parsed->port = atoi(colon+1);
           parsed->host = ne_strndup(pnt, colon - pnt);
       }
    } else {
       if (colon == NULL || colon > slash) {
           /* No port segment */
           if (defaults) parsed->port = defaults->port;
           parsed->host = ne_strndup(pnt, slash - pnt);
       } else {
           /* Port segment */
           parsed->port = atoi(colon + 1);
           parsed->host = ne_strndup(pnt, colon - pnt);
       }
       parsed->path = ne_strdup(slash);
    }

    return 0;
}
char* uri_unescape ( const char *  uri)

Definition at line 161 of file uri.c.

{
    const char *pnt;
    char *ret, *retpos, buf[5] = { "0x00\0" };
    retpos = ret = ne_malloc(strlen(uri) + 1);
    for (pnt = uri; *pnt != '\0'; pnt++) {
       if (*pnt == '%') {
           if (!isxdigit((unsigned char) pnt[1]) || 
              !isxdigit((unsigned char) pnt[2])) {
              /* Invalid URI */
              return NULL;
           }
           buf[2] = *++pnt; buf[3] = *++pnt; /* bit faster than memcpy */
           *retpos++ = (char)strtol(buf, NULL, 16);
       } else {
           *retpos++ = *pnt;
       }
    }
    *retpos = '\0';
    return ret;
}

Variable Documentation

const char uri_chars[128] [static]
Initial value:
 {

 CO, CO, CO, CO, CO, CO, CO, CO, CO, CO, CO, CO, CO, CO, CO, CO,
 CO, CO, CO, CO, CO, CO, CO, CO, CO, CO, CO, CO, CO, CO, CO, CO,
 SP, MA, DE, DE, RE, DE, RE, MA, MA, MA, MA, RE, RE, MA, MA, RE,
 AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, RE, RE, DE, RE, DE, RE,
 RE, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN,
 AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, UW, UW, UW, UW, MA,
 UW, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN,
 AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, UW, UW, UW, MA, CO 
}

Definition at line 198 of file uri.c.