int Ns_AbsoluteUrl(Ns_DString *dsPtr, char *url, char *base) { char *protocol, *host, *port, *path, *tail, *baseprotocol, *basehost, *baseport, *basepath, *basetail; int status = NS_OK; /* * Copy the URL's to allow Ns_ParseUrl to destory them. */ url = ns_strdup(url); base = ns_strdup(base); Ns_ParseUrl(url, &protocol, &host, &port, &path, &tail); Ns_ParseUrl(base, &baseprotocol, &basehost, &baseport, &basepath, &basetail); if (baseprotocol == NULL || basehost == NULL || basepath == NULL) { status = NS_ERROR; goto done; } if (protocol == NULL) { protocol = baseprotocol; } if (host == NULL) { host = basehost; port = baseport; } if (path == NULL) { path = basepath; } Ns_DStringVarAppend(dsPtr, protocol, "://", host, NULL); if (port != NULL) { Ns_DStringVarAppend(dsPtr, ":", port, NULL); } if (*path == '\0') { Ns_DStringVarAppend(dsPtr, "/", tail, NULL); } else { Ns_DStringVarAppend(dsPtr, "/", path, "/", tail, NULL); } done: ns_free(url); ns_free(base); return status; }
static void SetUrl(Ns_Request *request, char *url, Tcl_Encoding encoding) { Ns_Conn *conn; Ns_DString ds1, ds2; char *p; Ns_DStringInit(&ds1); Ns_DStringInit(&ds2); /* * Look for a query string at the end of the URL. */ p = strchr(url, '?'); if (p != NULL) { *p++ = '\0'; if (request->query != NULL) { ns_free(request->query); } request->query = ns_strdup(p); } /* * Decode and normalize the URL. If the encoding isn't specified, * use the encoding of the current connection, if any. */ if (encoding == NULL && (conn = Ns_GetConn()) != NULL) { encoding = Ns_ConnGetUrlEncoding(conn); } p = Ns_DecodeUrlWithEncoding(&ds1, url, encoding); if (p == NULL) { p = url; } Ns_NormalizePath(&ds2, p); Ns_DStringTrunc(&ds1, 0); /* * Append a trailing slash to the normalized URL if the original URL * ended in slash that wasn't also the leading slash. */ while (*url == '/') { ++url; } if (*url != '\0' && url[strlen(url) - 1] == '/') { Ns_DStringAppend(&ds2, "/"); } request->url = ns_strdup(ds2.string); Ns_DStringFree(&ds2); /* * Build the urlv and set urlc. */ p = ns_strdup(request->url + 1); Ns_DStringNAppend(&ds1, (char *) &p, sizeof(char *)); while (*p != '\0') { if (*p == '/') { *p++ = '\0'; if (*p == '\0') { /* * Stop on a trailing slash. */ break; } Ns_DStringNAppend(&ds1, (char *) &p, sizeof(char *)); } ++p; } request->urlc = ds1.length / (sizeof(char *)); p = NULL; Ns_DStringNAppend(&ds1, (char *) &p, sizeof(char *)); request->urlv = (char **) ns_malloc((size_t)ds1.length); memcpy(request->urlv, ds1.string, (size_t)ds1.length); Ns_DStringFree(&ds1); }
Ns_Request * Ns_ParseRequestEx(char *line, Tcl_Encoding encoding) { char *url; char *p; Ns_DString ds; Ns_Request *request; unsigned int major, minor; int i; request = ns_calloc(1, sizeof(Ns_Request)); Ns_DStringInit(&ds); /* * Make a copy of the line to chop up. Make sure it isn't blank. */ if (line == NULL) { goto done; } Ns_DStringAppend(&ds, line); line = Ns_StrTrim(ds.string); if (*line == '\0') { goto done; } /* * Save the trimmed line for logging purposes. */ request->line = ns_strdup(line); /* * Look for the minimum of method and url. */ url = line; while (*url != '\0' && !isspace(UCHAR(*url))) { ++url; } if (*url == '\0') { goto done; } *url++ = '\0'; while (*url != '\0' && isspace(UCHAR(*url))) { ++url; } if (*url == '\0') { goto done; } request->method = ns_strdup(line); /* * Look for a valid version. */ request->version = 0.0; p = NsFindVersion(url, &major, &minor); if (p != NULL) { *p = '\0'; i = 10; while ((minor / i) > 0) { i *= 10; } request->version = major + (double) minor / i; } url = Ns_StrTrim(url); if (*url == '\0') { goto done; } /* * Look for a protocol in the URL. */ request->protocol = NULL; request->host = NULL; request->port = 0; if (*url != '/') { p = url; while (*p != '\0' && *p != '/' && *p != ':') { ++p; } if (*p == ':') { /* * Found a protocol - copy it and search for host:port. */ *p++ = '\0'; request->protocol = ns_strdup(url); url = p; if ((strlen(url) > 3) && (*p++ == '/') && (*p++ == '/') && (*p != '\0') && (*p != '/')) { char *h; h = p; while (*p != '\0' && *p != '/') { ++p; } if (*p == '/') { *p++ = '\0'; } url = p; p = strchr(h, ':'); if (p != NULL) { *p++ = '\0'; if (Tcl_GetInt(NULL, p, &i) != TCL_OK) { goto done; } request->port = (unsigned short) i; } request->host = ns_strdup(h); } } } SetUrl(request, url, encoding); done: if (request->url == NULL) { Ns_FreeRequest(request); request = NULL; } Ns_DStringFree(&ds); return request; }
char * Ns_StrDup(char *str) { return ns_strdup(str); }
char * Ns_PoolStrDup(Ns_Pool *pool, char *old) { return ns_strdup(old); }
char * Ns_ThreadStrDup(char *old) { return ns_strdup(old); }