Пример #1
0
static void copyMappings(HttpRoute *route, MprJson *dest, MprJson *obj)
{
    MprJson     *child, *job, *jvalue;
    cchar       *key, *value;
    int         ji;

    for (ITERATE_CONFIG(route, obj, child, ji)) {
        if (child->type & MPR_JSON_OBJ) {
            job = mprCreateJson(MPR_JSON_OBJ);
            copyMappings(route, job, child);
            mprSetJsonObj(dest, child->name, job);
        } else {
            key = child->value;
            if (sends(key, "|time")) {
                key = ssplit(sclone(key), " \t|", NULL);
                if ((value = mprGetJson(route->config, key)) != 0) {
                    mprSetJson(dest, child->name, itos(httpGetTicks(value)), MPR_JSON_NUMBER);
                }
            } else {
                if ((jvalue = mprGetJsonObj(route->config, key)) != 0) {
                    mprSetJsonObj(dest, child->name, mprCloneJson(jvalue));
                }
            }
        }
    }
}
Пример #2
0
PUBLIC void espDefineAction(HttpRoute *route, cchar *target, void *callback)
{
    EspRoute    *eroute;
    char        *action, *controller;

    assert(route);
    assert(target && *target);
    assert(callback);

    eroute = ((EspRoute*) route->eroute)->top;
    if (target) {
#if DEPRECATED || 1
        /*
            Keep till version 6
         */
        if (scontains(target, "-cmd-")) {
            target = sreplace(target, "-cmd-", "/");
        } else if (schr(target, '-')) {
            controller = ssplit(sclone(target), "-", (char**) &action);
            target = sjoin(controller, "/", action, NULL);
        }
#endif
        if (!eroute->actions) {
            eroute->actions = mprCreateHash(-1, MPR_HASH_STATIC_VALUES);
        }
        mprAddKey(eroute->actions, target, callback);
    }
}
Пример #3
0
Файл: ls.c Проект: rdavid42/ft_p
int				ls(char *root, int *cs, char *cmd, int *id)
{
	pid_t					pid;
	pid_t					tpid;

	(void)root;
	pid = fork();
	if (pid == -1)
		error("Fork error !\n");
	g_except = 1;
	if (pid == 0)
	{
		dup2(*cs, 0), dup2(*cs, 1), dup2(*cs, 2);
		execv("/bin/ls", ssplit(cmd, ' '));
	}
	else
	{
		tpid = wait4(pid, NULL, 0, NULL);
		while (tpid != pid)
			tpid = wait4(pid, NULL, 0, NULL);
		(void)!write(*cs, "\0", 1);
		printf("Sent ls results to client %d\n", *id);
	}
	return (1);
}
Пример #4
0
/*
    Parse the cert info and write properties to the buffer. Modifies the info argument.
 */
static void parseCertFields(MprBuf *buf, char *info)
{
    char    c, *cp, *term, *key, *value;

    if (info) {
        key = 0;
        term = cp = info;
        do {
            c = *cp;
            if (c == '/' || c == '\0') {
                *cp = '\0';
                key = ssplit(term, "=", &value);
                if (smatch(key, "emailAddress")) {
                    key = "email";
                }
                mprPutToBuf(buf, "\"%s\":\"%s\",", key, value);
                term = &cp[1];
                *cp = c;
            }
        } while (*cp++ != '\0');
        if (key) {
            mprAdjustBufEnd(buf, -1);
        }
    }
}
Пример #5
0
/*********************************************************************
 *
 * Function    :  compile_host_pattern
 *
 * Description :  Parses and "compiles" an old-school host pattern.
 *
 * Parameters  :
 *          1  :  url = Target pattern_spec to be filled in.
 *          2  :  host_pattern = Host pattern to parse.
 *
 * Returns     :  JB_ERR_OK - Success
 *                JB_ERR_PARSE - Cannot parse regex
 *
 *********************************************************************/
static jb_err compile_host_pattern(struct pattern_spec *url, const char *host_pattern)
{
   char *v[150];
   size_t size;
   char *p;

   /*
    * Parse domain part
    */
   if (host_pattern[strlen(host_pattern) - 1] == '.')
   {
      url->pattern.url_spec.unanchored |= ANCHOR_RIGHT;
   }
   if (host_pattern[0] == '.')
   {
      url->pattern.url_spec.unanchored |= ANCHOR_LEFT;
   }

   /*
    * Split domain into components
    */
   url->pattern.url_spec.dbuffer = strdup_or_die(host_pattern);

   /*
    * Map to lower case
    */
   for (p = url->pattern.url_spec.dbuffer; *p ; p++)
   {
      *p = (char)privoxy_tolower(*p);
   }

   /*
    * Split the domain name into components
    */
   url->pattern.url_spec.dcount = ssplit(url->pattern.url_spec.dbuffer, ".", v, SZ(v));

   if (url->pattern.url_spec.dcount < 0)
   {
      free_pattern_spec(url);
      return JB_ERR_PARSE;
   }
   else if (url->pattern.url_spec.dcount != 0)
   {
      /*
       * Save a copy of the pointers in dvec
       */
      size = (size_t)url->pattern.url_spec.dcount * sizeof(*url->pattern.url_spec.dvec);

      url->pattern.url_spec.dvec = malloc_or_die(size);

      memcpy(url->pattern.url_spec.dvec, v, size);
   }
   /*
    * else dcount == 0 in which case we needn't do anything,
    * since dvec will never be accessed and the pattern will
    * match all domains.
    */
   return JB_ERR_OK;
}
Пример #6
0
Файл: cd.c Проект: rdavid42/ft_p
int						cd(char *root, int *cs, char *cmd, int *id)
{
	char				**arg;
	char const			*cur = get_cwd();

	(void)id;
	arg = ssplit(cmd, ' ');
	if (scmp(root, cur, slen(root)) != 0)
		return (afree(arg), sc(cs, -2), error(CWD_DENIED), 0);
	go_dir(cs, root, cur, arg[1]);
	return (afree(arg), 1);
}
Пример #7
0
/*
    password and authType can be null
    User may be a combined user:password
 */
PUBLIC void httpSetCredentials(HttpConn *conn, cchar *username, cchar *password, cchar *authType)
{
    char    *ptok;

    httpResetCredentials(conn);
    if (password == NULL && strchr(username, ':') != 0) {
        conn->username = ssplit(sclone(username), ":", &ptok);
        conn->password = sclone(ptok);
    } else {
        conn->username = sclone(username);
        conn->password = sclone(password);
    }
    if (authType) {
        conn->authType = sclone(authType);
    }
}
Пример #8
0
/*  
    Get all environment vars
    function get env(): Object
 */
static EjsAny *app_env(Ejs *ejs, EjsObj *app, int argc, EjsObj **argv)
{
#if VXWORKS
    return ESV(null);
#else
    EjsPot  *result;
    char        **ep, *pair, *key, *value;

    result = ejsCreatePot(ejs, ESV(Object), 0);
    for (ep = environ; ep && *ep; ep++) {
        pair = sclone(*ep);
        key = ssplit(pair, "=", &value);
        ejsSetPropertyByName(ejs, result, EN(key), ejsCreateStringFromAsc(ejs, value));
    }
    return result;
#endif
}
Пример #9
0
/*
    Parse the cert info and write properties to the buffer. Modifies the info argument.
 */
static void parseCertFields(MprBuf *buf, char *prefix, char *prefix2, char *info)
{
    char    c, *cp, *term, *key, *value;

    if (info) {
        term = cp = info;
        do {
            c = *cp;
            if (c == '/' || c == '\0') {
                *cp = '\0';
                key = ssplit(term, "=", &value);
                if (smatch(key, "emailAddress")) {
                    key = "EMAIL";
                }
                mprPutToBuf(buf, "%s%s%s=%s,", prefix, prefix2, key, value);
                term = &cp[1];
                *cp = c;
            }
        } while (*cp++ != '\0');
    }
}
Пример #10
0
struct url_spec
dsplit(char *domain)
{
	struct url_spec ret[1];
	char *v[BUFSIZ];
	int size;
	char *p;

	memset(ret, '\0', sizeof(*ret));

	if((p = strrchr(domain, '.'))) {
		if(*(++p) == '\0') {
			ret->toplevel = 1;
		}
	}

	ret->dbuf = strdup(domain);

	/* map to lower case */
	for(p = ret->dbuf; *p ; p++) *p = tolower(*p);

	/* split the domain name into components */
	ret->dcnt = ssplit(ret->dbuf, ".", v, SZ(v), 1, 1);

	if(ret->dcnt <= 0) {
		memset(ret, '\0', sizeof(ret));
		return(*ret);
	}

	/* save a copy of the pointers in dvec */
	size = ret->dcnt * sizeof(*ret->dvec);
		
	if((ret->dvec = malloc(size))) {
		memcpy(ret->dvec, v, size);
	}

	return(*ret);
}
Пример #11
0
int					put(char *root, int *cs, char *cmd, int *id)
{
	int				fd;
	char			**cmd_args;
	int				len;
	int				ret;

	(void)root;
	cmd_args = ssplit(cmd, ' ');
	if (!check_errors(cs, cmd_args))
		return (0);
	ret = 0, send(*cs, (void *)&ret, sizeof(uint32_t), 0);
	if (!receive_file_header(cs, cmd_args, &len))
		return (afree(cmd_args), 0);
	if ((fd = open(cmd_args[1], O_RDWR | O_CREAT, 0644)) == -1)
		return (afree(cmd_args), err_msg(OPEN_ERR), 0);
	write_streaming_packets(cs, fd, &len, id);
	close(fd);
	afree(cmd_args);
	if (ret = 1, send(*cs, (void *)&ret, sizeof(uint32_t), 0) == -1)
		return (0);
	return (1);
}
Пример #12
0
/*
    Write upload data. This routine blocks. If you need non-blocking ... cut and paste.
 */
PUBLIC ssize httpWriteUploadData(HttpConn *conn, MprList *fileData, MprList *formData)
{
    char    *path, *pair, *key, *value, *name;
    cchar   *type;
    ssize   rc;
    int     next;

    rc = 0;
    if (formData) {
        for (rc = next = 0; rc >= 0 && (pair = mprGetNextItem(formData, &next)) != 0; ) {
            key = ssplit(sclone(pair), "=", &value);
            rc += httpWrite(conn->writeq, "%s\r\nContent-Disposition: form-data; name=\"%s\";\r\n", conn->boundary, key);
            rc += httpWrite(conn->writeq, "Content-Type: application/x-www-form-urlencoded\r\n\r\n%s\r\n", value);
        }
    }
    if (fileData) {
        for (rc = next = 0; rc >= 0 && (path = mprGetNextItem(fileData, &next)) != 0; ) {
            if (!mprPathExists(path, R_OK)) {
                httpError(conn, HTTP_CODE_NOT_FOUND, "Cannot open %s", path);
                return MPR_ERR_CANT_OPEN;
            }
            name = mprGetPathBase(path);
            rc += httpWrite(conn->writeq, "%s\r\nContent-Disposition: form-data; name=\"file%d\"; filename=\"%s\"\r\n",
                conn->boundary, next - 1, name);
            if ((type = mprLookupMime(MPR->mimeTypes, path)) != 0) {
                rc += httpWrite(conn->writeq, "Content-Type: %s\r\n", mprLookupMime(MPR->mimeTypes, path));
            }
            httpWrite(conn->writeq, "\r\n");
            if (blockingFileCopy(conn, path) < 0) {
                return MPR_ERR_CANT_WRITE;
            }
            rc += httpWrite(conn->writeq, "\r\n");
        }
    }
    rc += httpWrite(conn->writeq, "%s--\r\n--", conn->boundary);
    return rc;
}
Пример #13
0
/*********************************************************************
 *
 * Function    :  init_domain_components
 *
 * Description :  Splits the domain name so we can compare it
 *                against wildcards. It used to be part of
 *                parse_http_url, but was separated because the
 *                same code is required in chat in case of
 *                intercepted requests.
 *
 * Parameters  :
 *          1  :  http = pointer to the http structure to hold elements.
 *
 * Returns     :  JB_ERR_OK on success
 *                JB_ERR_PARSE on malformed command/URL
 *                             or >100 domains deep.
 *
 *********************************************************************/
jb_err init_domain_components(struct http_request *http)
{
   char *vec[BUFFER_SIZE];
   size_t size;
   char *p;

   http->dbuffer = strdup_or_die(http->host);

   /* map to lower case */
   for (p = http->dbuffer; *p ; p++)
   {
      *p = (char)privoxy_tolower(*p);
   }

   /* split the domain name into components */
   http->dcount = ssplit(http->dbuffer, ".", vec, SZ(vec));

   if (http->dcount <= 0)
   {
      /*
       * Error: More than SZ(vec) components in domain
       *    or: no components in domain
       */
      log_error(LOG_LEVEL_ERROR, "More than SZ(vec) components in domain or none at all.");
      return JB_ERR_PARSE;
   }

   /* save a copy of the pointers in dvec */
   size = (size_t)http->dcount * sizeof(*http->dvec);

   http->dvec = malloc_or_die(size);

   memcpy(http->dvec, vec, size);

   return JB_ERR_OK;
}
Пример #14
0
/*
    Determine the windows program to invoke.
    Support UNIX style "#!/program" bang directives on windows.
    Also supports ".cmd" and ".bat" alternatives.
 */
static void prepWinProgram(MprCmd *cmd)
{
#if ME_WIN_LIKE
    MprFile     *file;
    cchar       *bat, *ext, *shell, *cp, *start;
    char        bang[ME_MAX_FNAME + 1], *path, *pp;

    /*
        Map separators, convert carriage-returns and newlines to spaces and remove quotes on the command
     */
    path = mprAlloc(slen(cmd->argv[0]) * 2 + 1);
    strcpy(path, cmd->argv[0]);
    for (pp = path; *pp; pp++) {
        if (*pp == '/') {
            *pp = '\\';
        } else if (*pp == '\r' || *pp == '\n') {
            *pp = ' ';
        }
    }
    if (*path == '\"') {
        if ((pp = strrchr(++path, '"')) != 0) {
            *pp = '\0';
        }
        path = sclone(path);
    }
    cmd->argv[0] = path;

    /*
        Support ".cmd" and ".bat" files that take precedence
     */
    if ((ext = mprGetPathExt(path)) == 0) {
        if ((bat = mprSearchPath(mprJoinPathExt(path, ".cmd"), MPR_SEARCH_EXE, cmd->searchPath, NULL)) == 0) {
            bat = mprSearchPath(mprJoinPathExt(path, ".bat"), MPR_SEARCH_EXE, cmd->searchPath, NULL);
        }
        if (bat) {
            if ((shell = getenv("COMSPEC")) == 0) {
                shell = "cmd.exe";
            }
            cmd->argv = mprRealloc((void*) cmd->argv, (cmd->argc + 4) * sizeof(char*));
            memmove((void*) &cmd->argv[3], (void*) cmd->argv, sizeof(char*) * (cmd->argc + 1));
            cmd->argv[0] = sclone(shell);
            cmd->argv[1] = sclone("/Q");
            cmd->argv[2] = sclone("/C");
            cmd->argv[3] = bat;
            cmd->argc += 3;
            cmd->argv[cmd->argc] = 0;
            return;
        }
    }
    if ((file = mprOpenFile(path, O_RDONLY, 0)) != 0) {
        if (mprReadFile(file, bang, ME_MAX_FNAME) > 0) {
            mprCloseFile(file);
            bang[ME_MAX_FNAME] = '\0';
            if (bang[0] == '#' && bang[1] == '!') {
                cp = start = &bang[2];
                shell = ssplit(&bang[2], "\r\n", NULL);
                if (!mprIsPathAbs(shell)) {
                    /*
                        If we cannot access the command shell and the command is not an absolute path,
                        look in the same directory as the script.
                     */
                    if (mprPathExists(shell, X_OK)) {
                        shell = mprJoinPath(mprGetPathDir(path), shell);
                    }
                }
                /*
                    Get length of argv with NULL and add one
                 */
                assert(cmd->argv[cmd->argc] == 0);
                cmd->argv = mprRealloc((void*) cmd->argv, (cmd->argc + 2) * sizeof(char*));
                cmd->argv[cmd->argc + 1] = 0;

                /*
                    Copy up to make room to insert the shell argument. This copies the original NULL
                 */
                memmove((void*) &cmd->argv[1], (void*) cmd->argv, sizeof(char*) * cmd->argc);
                cmd->argv[0] = sclone(shell);
                cmd->argv[1] = path;
                cmd->argc += 1;
                assert(cmd->argv[cmd->argc] == 0);
            }
        } else {
            mprCloseFile(file);
        }
    }
#endif
}
Пример #15
0
/*
    WARNING: may yield
 */
PUBLIC int espLoadConfig(HttpRoute *route)
{
    EspRoute    *eroute;
    cchar       *name, *package;
    bool        modified;

    eroute = route->eroute;
    if (!route->update) {
        return 0;
    }
    package = mprJoinPath(mprGetPathDir(eroute->configFile), "package.json");
    modified = 0;
    ifConfigModified(route, eroute->configFile, &modified);
    ifConfigModified(route, package, &modified);

    if (modified) {
        lock(esp);
        httpInitConfig(route);
#if DEPRECATED || 1
        /* Don't reload if configFile == package.json */
        if (!mprSamePath(package, eroute->configFile)) {
#endif
            if (mprPathExists(package, R_OK)) {
                if (httpLoadConfig(route, package) < 0) {
                    unlock(esp);
                    return MPR_ERR_CANT_LOAD;
                }
            }
        }
        if (httpLoadConfig(route, eroute->configFile) < 0) {
            unlock(esp);
            return MPR_ERR_CANT_LOAD;
        }
        if ((name = espGetConfig(route, "name", 0)) != 0) {
            eroute->appName = name;
        }
        if (espLoadCompilerRules(route) < 0) {
            return MPR_ERR_CANT_OPEN;
        }
        unlock(esp);
    }
    if (!route->cookie) {
        httpSetRouteCookie(route, sfmt("esp-%s", eroute->appName));
    }
    if (route->database && !eroute->edi) {
        if (espOpenDatabase(route, route->database) < 0) {
            mprLog("error esp", 0, "Cannot open database %s", route->database);
            return MPR_ERR_CANT_LOAD;
        }
    }
#if !ME_STATIC
    if (!(route->flags & HTTP_ROUTE_NO_LISTEN)) {
        MprJson     *preload, *item;
        cchar       *errMsg, *source;
        char        *kind;
        int         i;

        /*
            WARNING: may yield when compiling modules
         */
        if (eroute->combine) {
            source = mprJoinPaths(route->home, httpGetDir(route, "CACHE"), sfmt("%s.c", eroute->appName), NULL);
        } else {
            source = mprJoinPaths(route->home, httpGetDir(route, "SRC"), "app.c", NULL);
        }
        lock(esp);
        if (espLoadModule(route, NULL, "app", source, &errMsg) < 0) {
            if (eroute->combine) {
                mprLog("error esp", 0, "%s", errMsg);
                unlock(esp);
                return MPR_ERR_CANT_LOAD;
            }
        }
        if (!eroute->combine && (preload = mprGetJsonObj(route->config, "esp.preload")) != 0) {
            for (ITERATE_JSON(preload, item, i)) {
                source = ssplit(sclone(item->value), ":", &kind);
                if (*kind == '\0') {
                    kind = "controller";
                }
                source = mprJoinPaths(route->home, httpGetDir(route, "CONTROLLERS"), source, NULL);
                if (espLoadModule(route, NULL, kind, source, &errMsg) < 0) {
                    mprLog("error esp", 0, "Cannot preload esp module %s. %s", source, errMsg);
                    unlock(esp);
                    return MPR_ERR_CANT_LOAD;
                }
            }
        }
        unlock(esp);
    }
Пример #16
0
/*********************************************************************
 *
 * Function    :  parse_http_request
 *
 * Description :  Parse out the host and port from the URL.  Find the
 *                hostname & path, port (if ':'), and/or password (if '@')
 *
 * Parameters  :
 *          1  :  req = HTTP request line to break down
 *          2  :  http = pointer to the http structure to hold elements
 *
 * Returns     :  JB_ERR_OK on success
 *                JB_ERR_CGI_PARAMS on malformed command/URL
 *                                  or >100 domains deep.
 *
 *********************************************************************/
jb_err parse_http_request(const char *req, struct http_request *http)
{
   char *buf;
   char *v[3];
   int n;
   jb_err err;

   memset(http, '\0', sizeof(*http));

   buf = strdup_or_die(req);

   n = ssplit(buf, " \r\n", v, SZ(v));
   if (n != 3)
   {
      freez(buf);
      return JB_ERR_PARSE;
   }

   /*
    * Fail in case of unknown methods
    * which we might not handle correctly.
    *
    * XXX: There should be a config option
    * to forward requests with unknown methods
    * anyway. Most of them don't need special
    * steps.
    */
   if (unknown_method(v[0]))
   {
      log_error(LOG_LEVEL_ERROR, "Unknown HTTP method detected: %s", v[0]);
      freez(buf);
      return JB_ERR_PARSE;
   }

   if (JB_ERR_OK != normalize_http_version(v[2]))
   {
      freez(buf);
      return JB_ERR_PARSE;
   }

   http->ssl = !strcmpic(v[0], "CONNECT");

   err = parse_http_url(v[1], http, !http->ssl);
   if (err)
   {
      freez(buf);
      return err;
   }

   /*
    * Copy the details into the structure
    */
   http->cmd = strdup_or_die(req);
   http->gpc = strdup_or_die(v[0]);
   http->ver = strdup_or_die(v[2]);
   http->ocmd = strdup_or_die(http->cmd);

   freez(buf);

   return JB_ERR_OK;

}
Пример #17
0
static void processUploadHeader(Webs *wp, char *line)
{
    WebsUpload  *file;
    char        *key, *headerTok, *rest, *nextPair, *value;

    if (line[0] == '\0') {
        wp->uploadState = UPLOAD_CONTENT_DATA;
        return;
    }
    trace(7, "Header line: %s", line);

    headerTok = line;
    stok(line, ": ", &rest);

    if (scaselesscmp(headerTok, "Content-Disposition") == 0) {
        /*
            The content disposition header describes either a form variable or an uploaded file.

            Content-Disposition: form-data; name="field1"
            >>blank line
            Field Data
            ---boundary

            Content-Disposition: form-data; name="field1" filename="user.file"
            >>blank line
            File data
            ---boundary
         */
        key = rest;
        wfree(wp->uploadVar);
        wfree(wp->clientFilename);
        wp->uploadVar = wp->clientFilename = 0;
        while (key && stok(key, ";\r\n", &nextPair)) {

            key = strim(key, " ", WEBS_TRIM_BOTH);
            ssplit(key, "= ", &value);
            value = strim(value, "\"", WEBS_TRIM_BOTH);

            if (scaselesscmp(key, "form-data") == 0) {
                /* Nothing to do */

            } else if (scaselesscmp(key, "name") == 0) {
                wfree(wp->uploadVar);
                wp->uploadVar = sclone(value);

            } else if (scaselesscmp(key, "filename") == 0) {
                if (wp->uploadVar == 0) {
                    websError(wp, HTTP_CODE_BAD_REQUEST, "Bad upload state. Missing name field");
                    return;
                }
                value = websNormalizeUriPath(value);
                if (*value == '.' || !websValidUriChars(value) || strpbrk(value, "\\/:*?<>|~\"'%`^\n\r\t\f")) {
                    websError(wp, HTTP_CODE_INTERNAL_SERVER_ERROR, "Bad upload client filename");
                    wfree(value);
                    return;
                }
                wfree(wp->clientFilename);
                wp->clientFilename = value;

                /*
                    Create the file to hold the uploaded data
                 */
                wfree(wp->uploadTmp);
                if ((wp->uploadTmp = websTempFile(uploadDir, "tmp")) == 0) {
                    websError(wp, HTTP_CODE_INTERNAL_SERVER_ERROR,
                        "Cannot create upload temp file %s. Check upload temp dir %s", wp->uploadTmp, uploadDir);
                    return;
                }
                trace(5, "File upload of: %s stored as %s", wp->clientFilename, wp->uploadTmp);

                if ((wp->upfd = open(wp->uploadTmp, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0600)) < 0) {
                    websError(wp, HTTP_CODE_INTERNAL_SERVER_ERROR, "Cannot open upload temp file %s", wp->uploadTmp);
                    return;
                }
                /*
                    Create the files[id]
                 */
                file = wp->currentFile = walloc(sizeof(WebsUpload));
                memset(file, 0, sizeof(WebsUpload));
                file->clientFilename = sclone(wp->clientFilename);
                file->filename = sclone(wp->uploadTmp);
            }
            key = nextPair;
        }

    } else if (scaselesscmp(headerTok, "Content-Type") == 0) {
        if (wp->clientFilename) {
            trace(5, "Set files[%s][CONTENT_TYPE] = %s", wp->uploadVar, rest);
            wp->currentFile->contentType = sclone(rest);
        }
    }
}
Пример #18
0
/*
    If the program has a UNIX style "#!/program" string at the start of the file that program will be selected 
    and the original program will be passed as the first arg to that program with argv[] appended after that. If 
    the program is not found, this routine supports a safe intelligent search for the command. If all else fails, 
    we just return in program the fileName we were passed in. script will be set if we are modifying the program 
    to run and we have extracted the name of the file to run as a script.
 */
static void findExecutable(HttpConn *conn, char **program, char **script, char **bangScript, cchar *fileName)
{
    HttpRx      *rx;
    HttpTx      *tx;
    HttpRoute   *route;
    MprKey      *kp;
    MprFile     *file;
    cchar       *actionProgram, *ext, *cmdShell, *cp, *start, *path;
    char        buf[ME_MAX_FNAME + 1];

    rx = conn->rx;
    tx = conn->tx;
    route = rx->route;

    *bangScript = 0;
    *script = 0;
    *program = 0;
    path = 0;

    actionProgram = mprGetMimeProgram(rx->route->mimeTypes, rx->mimeType);
    ext = tx->ext;

    /*
        If not found, go looking for the fileName with the extensions defined in appweb.conf. 
        NOTE: we don't use PATH deliberately!!!
     */
    if (access(fileName, X_OK) < 0) {
        for (kp = 0; (kp = mprGetNextKey(route->extensions, kp)) != 0; ) {
            path = sjoin(fileName, ".", kp->key, NULL);
            if (access(path, X_OK) == 0) {
                break;
            }
            path = 0;
        }
        if (kp) {
            ext = kp->key;
        } else {
            path = fileName;
        }

    } else {
        path = fileName;
    }
    assert(path && *path);

#if ME_WIN_LIKE
    if (ext && (strcmp(ext, ".bat") == 0 || strcmp(ext, ".cmd") == 0)) {
        /*
            Let a mime action override COMSPEC
         */
        if (actionProgram) {
            cmdShell = actionProgram;
        } else {
            cmdShell = getenv("COMSPEC");
        }
        if (cmdShell == 0) {
            cmdShell = "cmd.exe";
        }
        *script = sclone(path);
        *program = sclone(cmdShell);
        return;
    }
#endif

    if (actionProgram) {
        *program = sclone(actionProgram);

    } else if ((file = mprOpenFile(path, O_RDONLY, 0)) != 0) {
        if (mprReadFile(file, buf, ME_MAX_FNAME) > 0) {
            mprCloseFile(file);
            buf[ME_MAX_FNAME] = '\0';
            if (buf[0] == '#' && buf[1] == '!') {
                cp = start = &buf[2];
                cmdShell = ssplit(&buf[2], "\r\n", NULL);
                if (!mprIsPathAbs(cmdShell)) {
                    /*
                        If we cannot access the command shell and the command is not an absolute path, 
                        look in the same directory as the script.
                     */
                    if (mprPathExists(cmdShell, X_OK)) {
                        cmdShell = mprJoinPath(mprGetPathDir(path), cmdShell);
                    }
                }
                *program = sclone(cmdShell);
                *bangScript = sclone(path);
                return;
            }
        } else {
            mprCloseFile(file);
        }
    }

    if (actionProgram) {
        *program = sclone(actionProgram);
        *bangScript = sclone(path);
    } else {
        *program = sclone(path);
    }
    return;
}
Пример #19
0
/*
    Parse the CGI output headers. Sample CGI program output:
        Content-type: text/html

        <html.....
 */
static bool parseCgiHeaders(Cgi *cgi, HttpPacket *packet)
{
    HttpConn    *conn;
    MprBuf      *buf;
    char        *endHeaders, *headers, *key, *value;
    ssize       blen;
    int         len;

    conn = cgi->conn;
    value = 0;
    buf = packet->content;
    headers = mprGetBufStart(buf);
    blen = mprGetBufLength(buf);
    
    /*
        Split the headers from the body. Add null to ensure we can search for line terminators.
     */
    len = 0;
    if ((endHeaders = sncontains(headers, "\r\n\r\n", blen)) == NULL) {
        if ((endHeaders = sncontains(headers, "\n\n", blen)) == NULL) {
            if (mprGetCmdFd(cgi->cmd, MPR_CMD_STDOUT) >= 0 && strlen(headers) < ME_MAX_HEADERS) {
                /* Not EOF and less than max headers and have not yet seen an end of headers delimiter */
                return 0;
            }
        } 
        len = 2;
    } else {
        len = 4;
    }
    if (endHeaders > buf->end) {
        assert(endHeaders <= buf->end);
        return 0;
    }
    if (endHeaders) {
        endHeaders[len - 1] = '\0';
        endHeaders += len;
    }
    /*
        Want to be tolerant of CGI programs that omit the status line.
     */
    if (strncmp((char*) buf->start, "HTTP/1.", 7) == 0) {
        if (!parseFirstCgiResponse(cgi, packet)) {
            /* httpError already called */
            return 0;
        }
    }
    if (endHeaders && strchr(mprGetBufStart(buf), ':')) {
        while (mprGetBufLength(buf) > 0 && buf->start[0] && (buf->start[0] != '\r' && buf->start[0] != '\n')) {
            if ((key = getCgiToken(buf, ":")) == 0) {
                key = "Bad Header";
            }
            value = getCgiToken(buf, "\n");
            while (isspace((uchar) *value)) {
                value++;
            }
            len = (int) strlen(value);
            while (len > 0 && (value[len - 1] == '\r' || value[len - 1] == '\n')) {
                value[len - 1] = '\0';
                len--;
            }
            key = slower(key);

            if (strcmp(key, "location") == 0) {
                cgi->location = value;

            } else if (strcmp(key, "status") == 0) {
                httpSetStatus(conn, atoi(value));

            } else if (strcmp(key, "content-type") == 0) {
                httpSetHeaderString(conn, "Content-Type", value);

            } else if (strcmp(key, "content-length") == 0) {
                httpSetContentLength(conn, (MprOff) stoi(value));
                httpSetChunkSize(conn, 0);

            } else {
                /*
                    Now pass all other headers back to the client
                 */
                key = ssplit(key, ":\r\n\t ", NULL);
                httpSetHeaderString(conn, key, value);
            }
        }
        buf->start = endHeaders;
    }
    return 1;
}
Пример #20
0
static ssize parseCgiHeaders(Webs *wp, char *buf)
{
    char    *end, *cp, *key, *value, *location, *contentType;
    ssize   len, contentLength;
    int     status, doneHeaders;

    status = HTTP_CODE_OK;
    contentLength = -1;
    contentType = 0;
    location = 0;
    doneHeaders = 0;

    /*
        Look for end of headers
     */
    if ((end = strstr(buf, "\r\n\r\n")) == NULL) {
        if ((end = strstr(buf, "\n\n")) == NULL) {
            return 0;
        }
        len = 2;
    } else {
        len = 4;
    }
    end[len - 1] = '\0';
    end += len;
    cp = buf;
    if (!strchr(cp, ':')) {
        /* No headers found */
        return 0;
    }
    if (strncmp(cp, "HTTP/1.", 7) == 0) {
        ssplit(cp, "\r\n", &cp);
    }
    for (; cp && *cp && (*cp != '\r' && *cp != '\n') && cp < end; ) {
        key = slower(ssplit(cp, ":", &value));
        if (strcmp(key, "location") == 0) {
            location = value;
        } else if (strcmp(key, "status") == 0) {
            status = atoi(value);
        } else if (strcmp(key, "content-type") == 0) {
            contentType = value;
        } else if (strcmp(key, "content-length") == 0) {
            contentLength = atoi(value);
        } else {
            /*
                Now pass all other headers back to the client
             */
            if (!doneHeaders) {
                writeCgiHeaders(wp, status, contentLength, location, contentType);
                doneHeaders = 1;
            }
            if (key && value && !strspn(key, "%<>/\\")) {
                websWriteHeader(wp, key, "%s", value);
            } else {
                trace(5, "cgi: bad response http header: \"%s\": \"%s\"", key, value);
            }
        }
        stok(value, "\r\n", &cp);
    }
    if (!doneHeaders) {
        writeCgiHeaders(wp, status, contentLength, location, contentType);
     }
    websWriteEndHeaders(wp);
    return end - buf;
}