Пример #1
0
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);
}
Пример #2
0
void
NsConfUpdate(void)
{
    int stacksize;
    Ns_DString ds;
    
    Ns_DStringInit(&ds);
    Ns_HomePath(&ds, "modules", "tcl", NULL);
    nsconf.tcl.sharedlibrary = Ns_DStringExport(&ds);

    nsconf.shutdowntimeout = NsParamInt("shutdowntimeout", SHUTDOWNTIMEOUT);
    nsconf.sched.maxelapsed = NsParamInt("schedmaxelapsed", SCHED_MAXELAPSED);
    nsconf.backlog = NsParamInt("listenbacklog", LISTEN_BACKLOG);
    nsconf.http.major = (unsigned) NsParamInt("httpmajor", HTTP_MAJOR);
    nsconf.http.minor = (unsigned) NsParamInt("httpmajor", HTTP_MINOR);
    nsconf.tcl.lockoninit = NsParamBool("tclinitlock", TCL_INITLCK);

    if (!Ns_ConfigGetInt(NS_CONFIG_THREADS, "stacksize", &stacksize)) {
    	stacksize = NsParamInt("stacksize", THREAD_STACKSIZE);
    }
    Ns_ThreadStackSize(stacksize);

    NsLogConf();
    NsEnableDNSCache();
    NsUpdateEncodings();
    NsUpdateMimeTypes();
}
Пример #3
0
int
Ns_ConnReadHeaders(Ns_Conn *conn, Ns_Set *set, int *nreadPtr)
{
    Ns_DString      ds;
    Conn           *connPtr = (Conn *) conn;
    NsServer	   *servPtr = connPtr->servPtr;
    int             status, nread, nline, maxhdr;

    Ns_DStringInit(&ds);
    nread = 0;
    maxhdr = connPtr->drvPtr->maxinput;
    status = NS_OK;
    while (nread < maxhdr && status == NS_OK) {
        Ns_DStringTrunc(&ds, 0);
        status = Ns_ConnReadLine(conn, &ds, &nline);
        if (status == NS_OK) {
            nread += nline;
            if (nread > maxhdr) {
                status = NS_ERROR;
            } else {
                if (ds.string[0] == '\0') {
                    break;
                }
                status = Ns_ParseHeader(set, ds.string, servPtr->opts.hdrcase);
            }
        }
    }
    if (nreadPtr != NULL) {
	*nreadPtr = nread;
    }
    Ns_DStringFree(&ds);
    return status;
}
Пример #4
0
char *
Ns_GetMimeType(char *file)
{
    char          *start, *ext;
    Ns_DString     ds;
    Tcl_HashEntry *hePtr;

    start = strrchr(file, '/');
    if (start == NULL) {
	start = file;
    }

    ext = strrchr(start, '.');
    if (ext == NULL) {
	return noextType;
    }

    Ns_DStringInit(&ds);
    ext = LowerDString(&ds, ext);
    hePtr = Tcl_FindHashEntry(&types, ext);
    if (hePtr == NULL) {
	return defaultType;
    }
    return Tcl_GetHashValue(hePtr);
}
Пример #5
0
int
Ns_ParseHeader(Ns_Set *set, char *line, Ns_HeaderCaseDisposition disp)
{
    char           *key, *sep;
    char           *value;
    int             index;
    Ns_DString	    ds;

    /* 
     * Header lines are first checked if they continue a previous
     * header indicated by any preceeding white space.  Otherwise,
     * they must be in well form key: value form.
     */

    if (isspace(UCHAR(*line))) {
        index = Ns_SetLast(set);
        if (index < 0) {
	    return NS_ERROR;	/* Continue before first header. */
        }
        while (isspace(UCHAR(*line))) {
            ++line;
        }
        if (*line != '\0') {
	    value = Ns_SetValue(set, index);
	    Ns_DStringInit(&ds);
	    Ns_DStringVarAppend(&ds, value, " ", line, NULL);
	    Ns_SetPutValue(set, index, ds.string);
	    Ns_DStringFree(&ds);
	}
    } else {
        sep = strchr(line, ':');
        if (sep == NULL) {
	    return NS_ERROR;	/* Malformed header. */
	}
        *sep = '\0';
        value = sep + 1;
        while (*value != '\0' && isspace(UCHAR(*value))) {
            ++value;
        }
        index = Ns_SetPut(set, line, value);
        key = Ns_SetKey(set, index);
	if (disp == ToLower) {
            while (*key != '\0') {
	        if (isupper(UCHAR(*key))) {
            	    *key = tolower(UCHAR(*key));
		}
            	++key;
	    }
	} else if (disp == ToUpper) {
            while (*key != '\0') {
	        if (islower(UCHAR(*key))) {
		    *key = toupper(UCHAR(*key));
		}
		++key;
	    }
        }
        *sep = ':';
    }
    return NS_OK;
}
Пример #6
0
void
NsInitConf(void)
{
    Ns_DString addr;
    static char cwd[PATH_MAX];
    extern char *nsBuildDate; /* NB: Declared in stamp.c */

    Ns_ThreadSetName("-main-");

    /*
     * Set various core environment variables.
     */

    nsconf.build	 = nsBuildDate;
    nsconf.name          = NSD_NAME;
    nsconf.version       = NSD_VERSION;
    nsconf.tcl.version	 = TCL_VERSION;
    nsconf.http.major    = HTTP_MAJOR;
    nsconf.http.minor    = HTTP_MINOR;
    time(&nsconf.boot_t);
    nsconf.pid = getpid();
    nsconf.home = getcwd(cwd, sizeof(cwd));
    if (gethostname(nsconf.hostname, sizeof(nsconf.hostname)) != 0) {
        strcpy(nsconf.hostname, "localhost");
    }
    Ns_DStringInit(&addr);
    if (Ns_GetAddrByHost(&addr, nsconf.hostname)) {
        strcpy(nsconf.address, addr.string);
    } else {
        strcpy(nsconf.address, "0.0.0.0");
    }
    Ns_DStringFree(&addr);

    /*
     * Set various default values.
     */

    nsconf.shutdowntimeout = SHUTDOWNTIMEOUT;
    nsconf.sched.maxelapsed = SCHED_MAXELAPSED;
    nsconf.backlog = LISTEN_BACKLOG;
    nsconf.http.major = HTTP_MAJOR;
    nsconf.http.minor = HTTP_MINOR;
    nsconf.tcl.lockoninit = TCL_INITLCK;
    
    /*
     * At library load time the server is considered started. 
     * Normally it's marked stopped immediately by Ns_Main unless
     * libnsd is being used for some other, non-server program.
     */
     
    Ns_MutexSetName(&nsconf.state.lock, "nsd:state");
    nsconf.state.started = 1;
}
Пример #7
0
int
NsAdpProc(void *arg, Ns_Conn *conn)
{
    Ns_Time *ttlPtr = arg;
    Ns_DString file;
    int status;

    Ns_DStringInit(&file);
    Ns_UrlToFile(&file, Ns_ConnServer(conn), conn->request->url);
    status = Ns_AdpRequestEx(conn, file.string, ttlPtr);
    Ns_DStringFree(&file);
    return status;
}
Пример #8
0
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);
}
Пример #9
0
int
NsTclQuoteHtmlCmd(ClientData dummy, Tcl_Interp *interp, int argc, char **argv)
{
    Ns_DString ds;

    if (argc != 2) {
        Tcl_AppendResult(interp, "wrong # args:  should be \"",
                         argv[0], " html\"", NULL);
        return TCL_ERROR;
    }
    Ns_DStringInit(&ds);
    Ns_QuoteHtml(&ds, argv[1]);
    Tcl_DStringResult(interp, &ds);
    return TCL_OK;
}
Пример #10
0
static void 
php_ns_request_ctor(void)
{
	char *server;
	Ns_DString ds;
	char *root;
	int index;
	char *tmp;
	
	server = Ns_ConnServer(NSG(conn));
	
#define safe_strdup(x) ((x)?strdup((x)):NULL)
	SG(request_info).query_string = safe_strdup(NSG(conn->request->query));

	Ns_DStringInit(&ds);
	Ns_UrlToFile(&ds, server, NSG(conn->request->url));
	
	/* path_translated is the absolute path to the file */
	SG(request_info).path_translated = safe_strdup(Ns_DStringValue(&ds));
	Ns_DStringFree(&ds);
	root = Ns_PageRoot(server);
	SG(request_info).request_uri = strdup(SG(request_info).path_translated + strlen(root));
	SG(request_info).request_method = NSG(conn)->request->method;
	if(NSG(conn)->request->version > 1.0) SG(request_info).proto_num = 1001;
	else SG(request_info).proto_num = 1000;
	SG(request_info).content_length = Ns_ConnContentLength(NSG(conn));
	index = Ns_SetIFind(NSG(conn)->headers, "content-type");
	SG(request_info).content_type = index == -1 ? NULL : 
		Ns_SetValue(NSG(conn)->headers, index);
	SG(sapi_headers).http_response_code = 200;

	tmp = Ns_ConnAuthUser(NSG(conn));
	if (tmp)
		tmp = estrdup(tmp);
	SG(request_info).auth_user = tmp;

	tmp = Ns_ConnAuthPasswd(NSG(conn));
	if (tmp)
		tmp = estrdup(tmp);
	SG(request_info).auth_password = tmp;

	NSG(data_avail) = SG(request_info).content_length;
}
Пример #11
0
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);
}
Пример #12
0
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;
}
Пример #13
0
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;
}
Пример #14
0
int
Ns_ExecArgv(char *exec, char *dir, int fdin, int fdout,
	    char **argv, Ns_Set *env)
{
#ifdef _WIN32
    /*
     * Win32 ExecArgv simply calls ExecArgblk.
     */
    int             pid;     
    Ns_DString      ads;
    char	   *args;
    int		    i;

    Ns_DStringInit(&ads);
    if (argv == NULL) {
        args = NULL;
    } else {
        for (i = 0; argv[i] != NULL; ++i) {
            Ns_DStringNAppend(&ads, argv[i], strlen(argv[i]) + 1);
        }
        args = ads.string;
    }
    pid = Ns_ExecArgblk(exec, dir, fdin, fdout, args, env);
    Ns_DStringFree(&ads);
    return pid;
#else
    Ns_DString eds;
    char *argvSh[4], **envp;
    int i, pid;
    
    if (exec == NULL) {
        return -1;
    }
    if (argv == NULL) {
        argv = argvSh;
        argv[0] = "/bin/sh";
        argv[1] = "-c";
        argv[2] = exec;
        argv[3] = NULL;
        exec = argv[0];
    }
    Ns_DStringInit(&eds);
    if (env == NULL) {
	envp = Ns_CopyEnviron(&eds);
    } else {
	for (i = 0; i < Ns_SetSize(env); ++i) {
            Ns_DStringVarAppend(&eds,
		Ns_SetKey(env, i), "=", Ns_SetValue(env, i), NULL);
            Ns_DStringNAppend(&eds, "", 1);
	}
	Ns_DStringNAppend(&eds, "", 1);
	envp = Ns_DStringAppendArgv(&eds);
    }
    if (fdin < 0) {
	fdin = 0;
    }
    if (fdout < 0) {
	fdout = 1;
    }
    pid = ExecProc(exec, dir, fdin, fdout, argv, envp);
    Ns_DStringFree(&eds);
    return pid;
#endif
}
Пример #15
0
int
Ns_ExecArgblk(char *exec, char *dir, int fdin, int fdout,
		char *args, Ns_Set *env)
{
#ifndef _WIN32
    int    pid;
    char **argv;
    Ns_DString vds;

    Ns_DStringInit(&vds);
    if (args == NULL) {
        argv = NULL;
    } else {
	while (*args != '\0') {
            Ns_DStringNAppend(&vds, (char *) &args, sizeof(args));
            args += strlen(args) + 1;
	}
	args = NULL;
	Ns_DStringNAppend(&vds, (char *) &args, sizeof(args));
	argv = (char **) vds.string;
    }
    pid = Ns_ExecArgv(exec, dir, fdin, fdout, argv, env);
    Ns_DStringFree(&vds);
    return pid;
#else
    STARTUPINFO     si;
    PROCESS_INFORMATION pi;
    HANDLE          hCurrentProcess;
    int             pid;
    Ns_DString      cds, xds, eds;
    char           *envp;
    OSVERSIONINFO   oinfo;
    char           *cmd;

    if (exec == NULL) {
        return -1;
    }
    oinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    if (GetVersionEx(&oinfo) == TRUE && oinfo.dwPlatformId != VER_PLATFORM_WIN32_NT) {
        cmd = "command.com";
    } else {
        cmd = "cmd.exe";
    }

    /*
     * Setup STARTUPINFO with stdin, stdout, and stderr.
     */
    memset(&si, 0, sizeof(si));
    si.cb = sizeof(si);
    si.dwFlags = STARTF_USESTDHANDLES;
    si.hStdError = (HANDLE) _get_osfhandle(_fileno(stderr));
    hCurrentProcess = GetCurrentProcess();
    if (fdout < 0) {
        fdout = 1;
    }
    if (DuplicateHandle(hCurrentProcess, (HANDLE) _get_osfhandle(fdout), hCurrentProcess,
            &si.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS) != TRUE) {
        Ns_Log(Error, "exec: failed to duplicate handle: %s",
        NsWin32ErrMsg(GetLastError()));
        return -1;
    }
    if (fdin < 0) {
        fdin = 0;
    }
    if (DuplicateHandle(hCurrentProcess, (HANDLE) _get_osfhandle(fdin), hCurrentProcess,
            &si.hStdInput, 0, TRUE, DUPLICATE_SAME_ACCESS) != TRUE) {
        Ns_Log(Error, "exec: failed to duplicate handle: %s",
        NsWin32ErrMsg(GetLastError()));
        (void) CloseHandle(si.hStdOutput);
        return -1;
    }

    /*
     * Setup the command line and environment block and create the new
     * subprocess.
     */

    Ns_DStringInit(&cds);
    Ns_DStringInit(&xds);
    Ns_DStringInit(&eds);
    if (args == NULL) {
        /* NB: exec specifies a complete cmd.exe command string. */
        Ns_DStringVarAppend(&cds, cmd, " /c ", exec, NULL);
        exec = NULL;
    } else {
        char           *s;

        s = args;
        while (*s != '\0') {
            int             len;

            len = strlen(s);
            Ns_DStringNAppend(&cds, s, len);
            s += len + 1;
            if (*s != '\0') {
                Ns_DStringNAppend(&cds, " ", 1);
            }
        }
    Ns_NormalizePath(&xds, exec);
    s = xds.string;
    while (*s != '\0') {
        if (*s == '/') {
            *s = '\\';
        }
        ++s;
    }
    exec = xds.string;
    }
    if (env == NULL) {
        envp = NULL;
    } else {
        Set2Argv(&eds, env);
        envp = eds.string;
    }
    if (CreateProcess(exec, cds.string, NULL, NULL, TRUE, 0, envp, dir, &si, &pi) != TRUE) {
        Ns_Log(Error, "exec: failed to create process: %s: %s",
        exec ? exec : cds.string, NsWin32ErrMsg(GetLastError()));
        pid = -1;
    } else {
        CloseHandle(pi.hThread);
        pid = (int) pi.hProcess;
    }
    Ns_DStringFree(&cds);
    Ns_DStringFree(&xds);
    Ns_DStringFree(&eds);
    CloseHandle(si.hStdInput);
    CloseHandle(si.hStdOutput);
    return pid;
#endif
}