char * Ns_ConfigGetPath(char *server, char *module, ...) { va_list ap; char *s; Ns_DString ds; Ns_Set *set; Ns_DStringInit(&ds); Ns_DStringAppend(&ds, "ns"); if (server != NULL) { Ns_DStringVarAppend(&ds, "/server/", server, NULL); } if (module != NULL) { Ns_DStringVarAppend(&ds, "/module/", module, NULL); } va_start(ap, module); while ((s = va_arg(ap, char *)) != NULL) { Ns_DStringAppend(&ds, "/"); while (*s != '\0' && ISSLASH(*s)) { ++s; } Ns_DStringAppend(&ds, s); while (ISSLASH(ds.string[ds.length - 1])) { ds.string[--ds.length] = '\0'; } } va_end(ap); set = Ns_ConfigGetSection(ds.string); Ns_DStringFree(&ds); return (set ? Ns_SetName(set) : NULL); }
char * Ns_HttpTime(Ns_DString *pds, time_t *when) { time_t now; char buf[40]; struct tm *tmPtr; if (when == NULL) { now = time(0); when = &now; } tmPtr = ns_gmtime(when); if (tmPtr == NULL) { return NULL; } /* * Provide always english names independent of locale setting. * The format is RFC 1123: "Sun, 06 Nov 1997 09:12:45 GMT" */ snprintf(buf, 40, "%s, %02d %s %04d %02d:%02d:%02d GMT", weekdays_names[tmPtr->tm_wday], tmPtr->tm_mday, month_names[tmPtr->tm_mon], tmPtr->tm_year + 1900, tmPtr->tm_hour, tmPtr->tm_min, tmPtr->tm_sec); Ns_DStringAppend(pds, buf); return pds->string; }
void Ns_SetRequestUrl(Ns_Request * request, char *url) { Ns_DString ds; Ns_MutexLock(&reqlock); FreeUrl(request); Ns_DStringInit(&ds); Ns_DStringAppend(&ds, url); SetUrl(request, ds.string, NULL); Ns_MutexUnlock(&reqlock); Ns_DStringFree(&ds); }
void Ns_QuoteHtml(Ns_DString *pds, char *string) { char *end, *next; end = string + strlen(string); do { next = Tcl_UtfNext(string); switch (*string) { case '<': Ns_DStringAppend(pds, "<"); break; case '>': Ns_DStringAppend(pds, ">"); break; case '&': Ns_DStringAppend(pds, "&"); break; case '\'': Ns_DStringAppend(pds, "'"); break; case '"': Ns_DStringAppend(pds, """); break; default: Ns_DStringNAppend(pds, string, next - string); break; } string = next; } while (string < end); }
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_DecodeUrlWithEncoding(Ns_DString *dsPtr, char *string, Tcl_Encoding encoding) { register int i, j, n; register char *p, *q; char c; Ns_DString *outPtr, out; Tcl_DString ds; /* * If using an encoding, copy output to a scratch buffer instead * of directly to given dstring. */ if (encoding == NULL) { outPtr = dsPtr; } else { Ns_DStringInit(&out); outPtr = &out; } /* * Expand the output to the length of the input * string which will be the largest size required. */ n = strlen(string); i = dsPtr->length; Ns_DStringSetLength(outPtr, i + n); q = outPtr->string + i; p = string; while ((c = UCHAR(*p)) != '\0') { if (c == '%' && n > 2 && (i = enc[UCHAR(p[1])].hex) >= 0 && (j = enc[UCHAR(p[2])].hex) >= 0) { *q = (unsigned char) ((i << 4) + j); n -= 2; p += 2; } else if (c == '+') { *q = ' '; } else { *q = c; } --n, ++q, ++p; } /* * Terminate the dstring, decoding to utf8 if necessary. */ n = q - outPtr->string; if (outPtr == dsPtr) { Ns_DStringSetLength(dsPtr, n); } else { Tcl_ExternalToUtfDString(encoding, outPtr->string, n, &ds); Ns_DStringAppend(dsPtr, ds.string); Tcl_DStringFree(&ds); Ns_DStringFree(outPtr); } return dsPtr->string; }