Пример #1
0
void maSetHostTraceFilter(MaHost *host, int len, cchar *include, cchar *exclude)
{
    char    *word, *tok, *line;

    host->traceMaxLength = len;

    if (include && strcmp(include, "*") != 0) {
        host->traceInclude = mprCreateHash(host, 0);
        line = mprStrdup(host, include);
        word = mprStrTok(line, ", \t\r\n", &tok);
        while (word) {
            if (word[0] == '*' && word[1] == '.') {
                word += 2;
            }
            mprAddHash(host->traceInclude, word, host);
            word = mprStrTok(NULL, ", \t\r\n", &tok);
        }
        mprFree(line);
    }
    if (exclude) {
        host->traceExclude = mprCreateHash(host, 0);
        line = mprStrdup(host, exclude);
        word = mprStrTok(line, ", \t\r\n", &tok);
        while (word) {
            if (word[0] == '*' && word[1] == '.') {
                word += 2;
            }
            mprAddHash(host->traceExclude, word, host);
            word = mprStrTok(NULL, ", \t\r\n", &tok);
        }
        mprFree(line);
    }
}
Пример #2
0
void mprSetModuleSearchPath(char *dirs)
{
	char	full[MPR_MAX_FNAME], native[MPR_MAX_FNAME];
	char	*oldPath, sep, *np, *tok, *newPath, *searchPath, *cp;
	int		len, modified;

	mprAssert(dirs && *dirs);

	oldPath = getenv("PATH");
	mprAssert(oldPath);

	if (oldPath == 0 || dirs == 0) {
		return;
	}

	/*
	 *	Prepare to tokenize the search path
	 */
	searchPath = mprStrdup(dirs);
	sep = strchr(searchPath, '"') ? '"' : ' ';
	for (cp = searchPath; *cp; cp++) {
		if (*cp == sep) {
			*cp = '\001';
		}
	}

	len = mprAllocSprintf(&newPath, -1, "PATH=%s", oldPath);
	mprAssert(len > 0);

	np = mprStrTok(searchPath, "\001\n", &tok);
	for (modified = 0; np; ) {
		mprGetFullPathName(full, sizeof(full), np);
		mprGetNativePathName(native, sizeof(native), full);

		//	TODO - this should really do a case insensitive scan
		if ((cp = strstr(oldPath, native)) != 0) {
			cp = &oldPath[strlen(native)];
			if (*cp == ';' || *cp == '\0') {
				np = mprStrTok(0, "\001\n", &tok);
				continue;
			}
		}

		len = mprReallocStrcat(&newPath, -1, len, ";", native, 0);
		mprAssert(len >= 0);
		np = mprStrTok(0, "\001\n", &tok);
		modified = 1;
	}
	if (modified) {
		mprLog(7, "Set %s\n", newPath);

		if (putenv(newPath) < 0) {
			mprAssert(0);
		}
	}

	mprFree(searchPath);
	mprFree(newPath);
}
Пример #3
0
static void parseQuery(MaConn *conn)
{
    MaRequest   *req;
    MaResponse  *resp;
    Dir         *dir;
    char        *value, *query, *next, *tok;

    req = conn->request;
    resp = conn->response;
    dir = resp->handler->stageData;
    
    query = mprStrdup(req, req->parsedUri->query);
    if (query == 0) {
        return;
    }

    tok = mprStrTok(query, ";&", &next);
    while (tok) {
        if ((value = strchr(tok, '=')) != 0) {
            *value++ = '\0';
            if (*tok == 'C') {                  /* Sort column */
                mprFree(dir->sortField);
                if (*value == 'N') {
                    dir->sortField = "Name";
                } else if (*value == 'M') {
                    dir->sortField = "Date";
                } else if (*value == 'S') {
                    dir->sortField = "Size";
                }
                dir->sortField = mprStrdup(dir, dir->sortField);

            } else if (*tok == 'O') {           /* Sort order */
                if (*value == 'A') {
                    dir->sortOrder = 1;
                } else if (*value == 'D') {
                    dir->sortOrder = -1;
                }

            } else if (*tok == 'F') {           /* Format */ 
                if (*value == '0') {
                    dir->fancyIndexing = 0;
                } else if (*value == '1') {
                    dir->fancyIndexing = 1;
                } else if (*value == '2') {
                    dir->fancyIndexing = 2;
                }

            } else if (*tok == 'P') {           /* Pattern */ 
                dir->pattern = mprStrdup(dir, value);
            }
        }
        tok = mprStrTok(next, ";&", &next);
    }
    
    mprFree(query);
}
Пример #4
0
static void addFormVars(MprCtx ctx, cchar *buf)
{
    char    *pair, *tok;

    pair = mprStrTok(mprStrdup(ctx, buf), "&", &tok);
    while (pair != 0) {
        mprAddItem(formData, pair);
        pair = mprStrTok(0, "&", &tok);
    }
}
Пример #5
0
int maGetConfigValue(MprCtx ctx, char **arg, char *buf, char **nextToken, int quotes)
{
    char    *endp;

    if (buf == 0) {
        return -1;
    }
    while (isspace((int) *buf)) {
        buf++;
    }

    if (quotes && *buf == '\"') {
        *arg = ++buf;
        if ((endp = strchr(buf, '\"')) != 0) {
            *endp++ = '\0';
        } else {
            return MPR_ERR_BAD_SYNTAX;
        }
        while ((int) isspace((int) *endp)) {
            endp++;
        }
        *nextToken = endp;
    } else {
        *arg = mprStrTok(buf, " \t\n", nextToken);
    }
    return 0;
}
Пример #6
0
static void parseWords(MprList *list, cchar *str)
{
    char    *word, *tok, *strTok;

    mprAssert(str);
    if (str == 0 || *str == '\0') {
        return;
    }

    strTok = mprStrdup(list, str);
    word = mprStrTok(strTok, " \t\r\n", &tok);
    while (word) {
        mprAddItem(list, word);
        word = mprStrTok(0, " \t\r\n", &tok);
    }
}
Пример #7
0
static int getVars(MaQueue *q, char ***keys, char *buf, int len)
{
    char**  keyList;
    char    *eq, *cp, *pp, *tok;
    int     i, keyCount;

    *keys = 0;

    /*
     *  Change all plus signs back to spaces
     */
    keyCount = (len > 0) ? 1 : 0;
    for (cp = buf; cp < &buf[len]; cp++) {
        if (*cp == '+') {
            *cp = ' ';
        } else if (*cp == '&' && (cp > buf && cp < &buf[len - 1])) {
            keyCount++;
        }
    }

    if (keyCount == 0) {
        return 0;
    }

    /*
     *  Crack the input into name/value pairs 
     */
    keyList = (char**) mprAlloc(q, (keyCount * 2) * sizeof(char**));

    i = 0;
    tok = 0;
    for (pp = mprStrTok(buf, "&", &tok); pp; pp = mprStrTok(0, "&", &tok)) {
        if ((eq = strchr(pp, '=')) != 0) {
            *eq++ = '\0';
            mprUrlDecode(pp, (int) strlen(pp) + 1, pp);
            mprUrlDecode(eq, (int) strlen(eq) + 1, eq);
        } else {
            mprUrlDecode(pp, (int) strlen(pp) + 1, pp);
        }
        if (i < (keyCount * 2)) {
            keyList[i++] = pp;
            keyList[i++] = eq;
        }
    }
    *keys = keyList;
    return keyCount;
}
Пример #8
0
int MaHost::openMimeTypes(char *path)
{
	MprFile		*file;
	char		buf[80], *tok, *ext, *type;
	int			line;

	mimeFile = mprStrdup(path);
	mprAssert(mimeTypes == 0);
	file = server->fileSystem->newFile();
	
	if (mimeTypes == 0) {
		mimeTypes = new MprHashTable(157);
	}

/* WINCE may need to prepend server root to the path */

	if (file->open(path, O_RDONLY | O_TEXT, 0) < 0) {
		mprError(MPR_L, MPR_LOG, "Can't open mime file %s", path);
		delete file;
		return MPR_ERR_CANT_OPEN;
	}
	line = 0;
	while (file->gets(buf, sizeof(buf)) != 0) {
		line++;
		if (buf[0] == '#' || isspace((uchar) buf[0])) {
			continue;
		}
		type = mprStrTok(buf, " \t\n\r", &tok);
		ext = mprStrTok(0, " \t\n\r", &tok);
		if (type == 0 || ext == 0) {
			mprError(MPR_L, MPR_LOG, "Bad mime spec in %s at line %d", 
				path, line);
			continue;
		}
		while (ext) {
			addMimeType(ext, type);
			ext = mprStrTok(0, " \t\n\r", &tok);
		}
	}
	file->close();
	delete file;
	return 0;
}
Пример #9
0
static int readPassFile(char *passFile)
{
	FILE	*fp;
	char	buf[MPR_HTTP_MAX_PASS * 2];
	char	*tok, *enabledSpec, *user, *realm, *password;
	bool	enabled;
	int		line;

	fp = fopen(passFile, "r" MPR_TEXT);
	if (fp == 0) {
		mprError(MPR_L, MPR_USER, "Can't open %s\n", passFile);
		return MPR_ERR_CANT_OPEN;
	}
	line = 0;
	while (fgets(buf, sizeof(buf), fp) != 0) {
		line++;
		enabledSpec = mprStrTok(buf, ":", &tok);
		user = mprStrTok(0, ":", &tok);
		realm = mprStrTok(0, ":", &tok);
		password = mprStrTok(0, "\n\r", &tok);
		if (enabledSpec == 0 || user == 0 || realm == 0 || password == 0) {
			mprError(MPR_L, MPR_USER, 
				"Badly formed password on line %d\n", line);
			return MPR_ERR_CANT_OPEN;
		}
		user = trimWhiteSpace(user);
		if (*user == '#' || *user == '\0') {
			continue;
		}
		enabled = (enabledSpec[0] == '1'); 
		
		realm = trimWhiteSpace(realm);
		password = trimWhiteSpace(password);

		users.insert(new User(user, realm, password, enabled));
	}
	fclose(fp);
	return 0;
}
Пример #10
0
int maReadGroupFile(MaServer *server, MaAuth *auth, char *path)
{
    MprFile     *file;
    MaAcl       acl;
    char        buf[MPR_MAX_STRING];
    char        *users, *group, *enabled, *aclSpec, *tok, *cp;

    mprFree(auth->groupFile);
    auth->groupFile = mprStrdup(server, path);

    if ((file = mprOpen(auth, path, O_RDONLY | O_TEXT, 0444)) == 0) {
        return MPR_ERR_CANT_OPEN;
    }

    while (mprGets(file, buf, sizeof(buf))) {
        enabled = mprStrTok(buf, " :\t", &tok);
        if (!enabled) {
            continue;
        }
        for (cp = enabled; isspace((int) *cp); cp++) {
            ;
        }
        if (*cp == '\0' || *cp == '#') {
            continue;
        }
        aclSpec = mprStrTok(0, " :\t", &tok);
        group = mprStrTok(0, " :\t", &tok);
        users = mprStrTok(0, "\r\n", &tok);

        acl = maParseAcl(auth, aclSpec);
        maAddGroup(auth, group, acl, (*enabled == '0') ? 0 : 1);
        maAddUsersToGroup(auth, group, users);
    }
    mprFree(file);

    maUpdateUserAcls(auth);
    return 0;
}
Пример #11
0
int maReadUserFile(MaServer *server, MaAuth *auth, char *path)
{
    MprFile     *file;
    char        buf[MPR_MAX_STRING];
    char        *enabled, *user, *password, *realm, *tok, *cp;

    mprFree(auth->userFile);
    auth->userFile = mprStrdup(auth, path);

    if ((file = mprOpen(auth, path, O_RDONLY | O_TEXT, 0444)) == 0) {
        return MPR_ERR_CANT_OPEN;
    }

    while (mprGets(file, buf, sizeof(buf))) {
        enabled = mprStrTok(buf, " :\t", &tok);
        if (!enabled) {
            continue;
        }
        for (cp = enabled; isspace((int) *cp); cp++) {
            ;
        }
        if (*cp == '\0' || *cp == '#') {
            continue;
        }
        user = mprStrTok(0, ":", &tok);
        realm = mprStrTok(0, ":", &tok);
        password = mprStrTok(0, " \t\r\n", &tok);

        user = trimWhiteSpace(user);
        realm = trimWhiteSpace(realm);
        password = trimWhiteSpace(password);

        maAddUser(auth, realm, user, password, (*enabled == '0' ? 0 : 1));
    }
    mprFree(file);
    maUpdateUserAcls(auth);
    return 0;
}
Пример #12
0
int MaClient::parseFirst(char *line)
{
	char	*code, *tok;

	mprAssert(line && *line);

	responseProto = mprStrTok(line, " \t", &tok);
	if (responseProto == 0 || responseProto[0] == '\0') {
		formatError("Bad HTTP response");
		responseCode = MPR_HTTP_CLIENT_ERROR;
		finishRequest(1);
		return MPR_ERR_BAD_STATE;
	}
	responseProto = mprStrdup(responseProto);

	if (strncmp(responseProto, "HTTP/1.", 7) != 0) {
		formatError("Unsupported protocol: %s", responseProto);
		responseCode = MPR_HTTP_CLIENT_ERROR;
		finishRequest(1);
		return MPR_ERR_BAD_STATE;
	}

	code = mprStrTok(0, " \t\r\n", &tok);
	if (code == 0 || *code == '\0') {
		formatError("Bad HTTP response");
		responseCode = MPR_HTTP_CLIENT_ERROR;
		finishRequest(1);
		return MPR_ERR_BAD_STATE;
	}
	responseCode = atoi(code);

	responseText = mprStrTok(0, "\r\n", &tok);
	if (responseText && *responseText) {
		responseText = mprStrdup(responseText);
	}
	return 0;
}
Пример #13
0
/*
 *  Parse the request headers. Return true if the header parsed.
 */
static bool parseHeaders(MaConn *conn, MaPacket *packet)
{
    MaHostAddress   *address;
    MaRequest       *req;
    MaHost          *host, *hp;
    MaLimits        *limits;
    MprBuf          *content;
    char            keyBuf[MPR_MAX_STRING];
    char            *key, *value, *cp, *tok;
    int             count, keepAlive;

    req = conn->request;
    host = req->host;
    content = packet->content;
    conn->request->headerPacket = packet;
    limits = &conn->http->limits;
    keepAlive = 0;

    strcpy(keyBuf, "HTTP_");
    mprAssert(strstr((char*) content->start, "\r\n"));

    for (count = 0; content->start[0] != '\r' && !conn->connectionFailed; count++) {

        if (count >= limits->maxNumHeaders) {
            maFailConnection(conn, MPR_HTTP_CODE_BAD_REQUEST, "Too many headers");
            return 0;
        }
        if ((key = getToken(conn, ":")) == 0 || *key == '\0') {
            maFailConnection(conn, MPR_HTTP_CODE_BAD_REQUEST, "Bad header format");
            return 0;
        }

        value = getToken(conn, "\r\n");
        while (isspace((int) *value)) {
            value++;
        }
        if (conn->requestFailed) {
            continue;
        }
        mprStrUpper(key);
        for (cp = key; *cp; cp++) {
            if (*cp == '-') {
                *cp = '_';
            }
        }
        mprLog(req, 8, "Key %s, value %s", key, value);
        if (strspn(key, "%<>/\\") > 0) {
            maFailConnection(conn, MPR_HTTP_CODE_BAD_REQUEST, "Bad header key value");
            continue;
        }

        /*
         *  Define the header with a "HTTP_" prefix
         */
        mprStrcpy(&keyBuf[5], sizeof(keyBuf) - 5, key);
        mprAddDuplicateHash(req->headers, keyBuf, value);

        switch (key[0]) {
        case 'A':
            if (strcmp(key, "AUTHORIZATION") == 0) {
                value = mprStrdup(req, value);
                req->authType = mprStrTok(value, " \t", &tok);
                req->authDetails = tok;

            } else if (strcmp(key, "ACCEPT_CHARSET") == 0) {
                req->acceptCharset = value;

            } else if (strcmp(key, "ACCEPT") == 0) {
                req->accept = value;

            } else if (strcmp(key, "ACCEPT_ENCODING") == 0) {
                req->acceptEncoding = value;
            }
            break;

        case 'C':
            if (strcmp(key, "CONTENT_LENGTH") == 0) {
                if (req->length >= 0) {
                    maFailConnection(conn, MPR_HTTP_CODE_BAD_REQUEST, "Mulitple content length headers");
                    continue;
                }
                req->length = mprAtoi(value, 10);
                if (req->length < 0) {
                    maFailConnection(conn, MPR_HTTP_CODE_BAD_REQUEST, "Bad content length");
                    continue;
                }
                if (req->length >= host->limits->maxBody) {
                    maFailConnection(conn, MPR_HTTP_CODE_REQUEST_TOO_LARGE, 
                        "Request content length %Ld is too big. Limit %Ld", req->length, host->limits->maxBody);
                    continue;
                }
                mprAssert(req->length >= 0);
                req->remainingContent = req->length;
                req->contentLengthStr = value;

            } else if (strcmp(key, "CONTENT_RANGE") == 0) {
                /*
                 *  This headers specifies the range of any posted body data
                 *  Format is:  Content-Range: bytes n1-n2/length
                 *  Where n1 is first byte pos and n2 is last byte pos
                 */
                char    *sp;
                int     start, end, size;

                start = end = size = -1;
                sp = value;
                while (*sp && !isdigit((int) *sp)) {
                    sp++;
                }
                if (*sp) {
                    start = (int) mprAtoi(sp, 10);

                    if ((sp = strchr(sp, '-')) != 0) {
                        end = (int) mprAtoi(++sp, 10);
                    }
                    if ((sp = strchr(sp, '/')) != 0) {
                        /*
                         *  Note this is not the content length transmitted, but the original size of the input of which 
                         *  the client is transmitting only a portion.
                         */
                        size = (int) mprAtoi(++sp, 10);
                    }
                }
                if (start < 0 || end < 0 || size < 0 || end <= start) {
                    maFailRequest(conn, MPR_HTTP_CODE_RANGE_NOT_SATISFIABLE, "Bad content range");
                    continue;
                }
                req->inputRange = maCreateRange(conn, start, end);

            } else if (strcmp(key, "CONTENT_TYPE") == 0) {
                req->mimeType = value;
                req->form = strstr(value, "application/x-www-form-urlencoded") != 0;

            } else if (strcmp(key, "COOKIE") == 0) {
                if (req->cookie && *req->cookie) {
                    req->cookie = mprStrcat(req, -1, req->cookie, "; ", value, NULL);
                } else {
                    req->cookie = value;
                }

            } else if (strcmp(key, "CONNECTION") == 0) {
                req->connection = value;
                if (mprStrcmpAnyCase(value, "KEEP-ALIVE") == 0) {
                    keepAlive++;

                } else if (mprStrcmpAnyCase(value, "CLOSE") == 0) {
                    conn->keepAliveCount = 0;
                }
                if (!host->keepAlive) {
                    conn->keepAliveCount = 0;
                }
            }
            break;

        case 'F':
            req->forwarded = value;
            break;

        case 'H':
            if (strcmp(key, "HOST") == 0) {
                req->hostName = value;
                address = conn->address;
                if (maIsNamedVirtualHostAddress(address)) {
                    hp = maLookupVirtualHost(address, value);
                    if (hp == 0) {
                        maFailRequest(conn, 404, "No host to serve request. Searching for %s", value);
                        mprLog(conn, 1, "Can't find virtual host %s", value);
                        continue;
                    }
                    req->host = hp;
                    /*
                     *  Reassign this request to a new host
                     */
                    maRemoveConn(host, conn);
                    host = hp;
                    conn->host = hp;
                    maAddConn(hp, conn);
                }
            }
            break;

        case 'I':
            if ((strcmp(key, "IF_MODIFIED_SINCE") == 0) || (strcmp(key, "IF_UNMODIFIED_SINCE") == 0)) {
                MprTime     newDate = 0;
                char        *cp;
                bool        ifModified = (key[3] == 'M');

                if ((cp = strchr(value, ';')) != 0) {
                    *cp = '\0';
                }
                if (mprParseTime(conn, &newDate, value, MPR_UTC_TIMEZONE, NULL) < 0) {
                    mprAssert(0);
                    break;
                }
                if (newDate) {
                    setIfModifiedDate(conn, newDate, ifModified);
                    req->flags |= MA_REQ_IF_MODIFIED;
                }

            } else if ((strcmp(key, "IF_MATCH") == 0) || (strcmp(key, "IF_NONE_MATCH") == 0)) {
                char    *word, *tok;
                bool    ifMatch = key[3] == 'M';

                if ((tok = strchr(value, ';')) != 0) {
                    *tok = '\0';
                }
                req->ifMatch = ifMatch;
                req->flags |= MA_REQ_IF_MODIFIED;

                value = mprStrdup(conn, value);
                word = mprStrTok(value, " ,", &tok);
                while (word) {
                    addMatchEtag(conn, word);
                    word = mprStrTok(0, " ,", &tok);
                }

            } else if (strcmp(key, "IF_RANGE") == 0) {
                char    *word, *tok;

                if ((tok = strchr(value, ';')) != 0) {
                    *tok = '\0';
                }
                req->ifMatch = 1;
                req->flags |= MA_REQ_IF_MODIFIED;

                value = mprStrdup(conn, value);
                word = mprStrTok(value, " ,", &tok);
                while (word) {
                    addMatchEtag(conn, word);
                    word = mprStrTok(0, " ,", &tok);
                }
            }
            break;

        case 'P':
            if (strcmp(key, "PRAGMA") == 0) {
                req->pragma = value;
            }
            break;

        case 'R':
            if (strcmp(key, "RANGE") == 0) {
                if (!parseRange(conn, value)) {
                    maFailRequest(conn, MPR_HTTP_CODE_RANGE_NOT_SATISFIABLE, "Bad range");
                }
            } else if (strcmp(key, "REFERER") == 0) {
                /* NOTE: yes the header is misspelt in the spec */
                req->referer = value;
            }
            break;

        case 'T':
            if (strcmp(key, "TRANSFER_ENCODING") == 0) {
                mprStrLower(value);
                if (strcmp(value, "chunked") == 0) {
                    req->flags |= MA_REQ_CHUNKED;
                    /*
                     *  This will be revised by the chunk filter as chunks are processed and will be set to zero when the
                     *  last chunk has been received.
                     */
                    req->remainingContent = MAXINT;
                }
            }
            break;
        
#if BLD_DEBUG
        case 'X':
            if (strcmp(key, "X_APPWEB_CHUNK_SIZE") == 0) {
                mprStrUpper(value);
                conn->response->chunkSize = atoi(value);
                if (conn->response->chunkSize <= 0) {
                    conn->response->chunkSize = 0;
                } else if (conn->response->chunkSize > conn->http->limits.maxChunkSize) {
                    conn->response->chunkSize = conn->http->limits.maxChunkSize;
                }
            }
            break;
#endif

        case 'U':
            if (strcmp(key, "USER_AGENT") == 0) {
                req->userAgent = value;
            }
            break;
        }
    }
    if (conn->protocol == 0 && !keepAlive) {
        conn->keepAliveCount = 0;
    }
    if (!(req->flags & MA_REQ_CHUNKED)) {
        /*  
         *  Step over "\r\n" after headers. As an optimization, don't do this if chunked so chunking can parse a single
         *  chunk delimiter of "\r\nSIZE ...\r\n"
         */
        mprAdjustBufStart(content, 2);
    }
    mprLog(conn, 3, "Select host \"%s\"", conn->host->name);

    if (maSetRequestUri(conn, req->url, "") < 0) {
        maFailConnection(conn, MPR_HTTP_CODE_BAD_REQUEST, "Bad URI format");
        return 0;
    }
    if (conn->host->secure) {
        req->parsedUri->scheme = mprStrdup(req, "https");
    }
    req->parsedUri->port = conn->sock->port;
    req->parsedUri->host = req->hostName ? req->hostName : conn->host->name;
    return 1;
}
Пример #14
0
static void doTests(void *data, void *threadp)
#endif
{
	MprBuf		post;
	FILE		*fp;
	MaClient	*client;
	char		urlBuf[4096], urlBuf2[4096];
	char		postBuf[4096];
	char		*cp, *operation, *url, *tok;
	int			rc, j, line;

	fp = 0;

	client = new MaClient();
	client->setTimeout(timeout);
	client->setRetries(retries);
	if (httpVersion == 0) {
		client->setKeepAlive(0);
	}

	post.setBuf(MPR_HTTP_CLIENT_BUFSIZE, MPR_HTTP_MAX_BODY);

	while (!mpr->isExiting() && success) {
		lock();
		if (fetchCount >= iterations) {
			unlock();
			break;
		}
		unlock();
		rc = 0;

		for (j = 0; j < saveArgc; j++) {
			url = saveArgv[j];
			if (*url == '/') {
				mprSprintf(urlBuf2, sizeof(urlBuf2), "%s%s", host, url);
				url = urlBuf2;
			}
			rc = fetch(client, method, url, postData, postLen);
			if (rc < 0 && !continueOnErrors) {
				success = 0;
				goto commonExit;
			}
		}
		if (fileList == 0) {
			continue;
		}
		fp = fopen(fileList, "rt");
		if (fp == 0) {
			mprError(MPR_L, MPR_USER, "Can't open %s", fileList);
			goto commonExit;
		}

		line = 0;
		while (fgets(urlBuf, sizeof(urlBuf), fp) != NULL && !mpr->isExiting()) {
			lock();
			if (fetchCount >= iterations) {
				unlock();
				break;
			}
			unlock();
			if ((cp = strchr(urlBuf, '\n')) != 0) {
				*cp = '\0';
			}
			operation = mprStrTok(urlBuf, " \t\n", &tok);
			url = mprStrTok(0, " \t\n", &tok);
	
			if (*url == '/') {
				mprSprintf(urlBuf2, sizeof(urlBuf2), "%s%s", host, url);
				url = urlBuf2;
			}

			if (strcmp(operation, "GET") == 0) {
				rc = fetch(client, operation, url, postData, postLen);

			} else if (strcmp(operation, "HEAD") == 0) {
				rc = fetch(client, operation, url, postData, postLen);

			} else if (strcmp(operation, "POST") == 0) {
				while (fgets(postBuf, sizeof(postBuf), fp) != NULL) {
					if (postBuf[0] != '\t') {
						break;
					}
					if (strlen(postBuf) == 1) {
						break;
					}
					post.put((uchar*) &postBuf[1], strlen(postBuf) - 2);
					post.addNull();
					if (post.getLength() >= (MPR_HTTP_MAX_BODY - 1)) {
						mprError(MPR_L, MPR_USER, "Bad post data on line %d",
							line);
						if (!continueOnErrors) {
							success = 0;
							fclose(fp);
							fp = 0;
							goto commonExit;
						}
					}
				}
				if (post.getLength() > 0) {
					rc = fetch(client, operation, url, post.getStart(), 
						post.getLength());
				} else {
					rc = fetch(client, operation, url, postBuf, postLen);
				}
				post.flush();

			} else {
				rc = -1;
				mprError(MPR_L, MPR_USER, "Bad operation on line %d", line);
			}
			if (rc < 0 && !continueOnErrors) {
				success = 0;
				fclose(fp);
				fp = 0;
				goto commonExit;
			}
		}
		fclose(fp);
		fp = 0;
	}

commonExit:

#if BLD_FEATURE_MULTITHREAD
	if (threadp) {
		lock();
		activeLoadThreads--;
		unlock();
	}
#endif

	delete client;
}
Пример #15
0
void MaCgiHandler::parseHeader(MaRequest *rq)
{
	MaDataStream	*dynBuf;
	char			*endHeaders, *header, *key, *value, *tok;
	char			*cp, *lp, *saveHeader;
	int				len;

	header = headerBuf->getStart();
	endHeaders = strstr(header, "\r\n\r\n");
	if (endHeaders == 0) {
		endHeaders = strstr(header, "\n\n");
		if (endHeaders == 0) {
			endHeaders = strstr(header, "\r\r\n\r\r\n");
			if (endHeaders == 0) {
				return;
			}
		}
		headerBuf->adjustStart(endHeaders + 2 - header);
	} else {
		headerBuf->adjustStart(endHeaders + 4 - header);
	}
	*endHeaders = '\0';

	mprLog(5, log, "%d: parseHeader: header\n%s\n", rq->getFd(), header);

	if (endHeaders) {
		lp = header;
		tok = lp;
		while (tok && *tok) {

			for (cp = tok; *cp && *cp != '\r' && *cp != '\n'; cp++) 
				;
			len = cp - tok + 1;
			mprAssert(len >= 0);

			mprAllocMemcpy(&saveHeader, len, tok, len);
			saveHeader[len - 1] = '\0';

			if ((key = mprStrTok(lp, ": \t\r\n", &tok)) == 0) {
				break;
			}
			lp = 0;

			if ((value = mprStrTok(0, "\r\n", &tok)) == 0) {
				rq->requestError(503, "Bad header format");
				rq->finishRequest();
				mprFree(saveHeader);
				return;
			}
			while (isspace((uchar) *value)) {
				value++;
			}
			mprStrLower(key);

			if (strcmp(key, "location") == 0) {
				mprFree(newLocation);
				newLocation = mprStrdup(value);

			} else if (strcmp(key, "status") == 0) {
				rq->setResponseCode(atoi(value));

			} else if (strcmp(key, "content-type") == 0) {
				rq->setResponseMimeType(value);

#if OLD
			} else if ((key[0] == 'x' || key[0] == 'X') && key[1] == '-') {
				//
				//	Pass "X-Headers" through to the client
				//
				rq->setHeader(saveHeader);
			}
#endif
			} else {
				//
				//	Now pass all other headers back to the client
				//
				rq->setHeader(saveHeader);
			}
			mprFree(saveHeader);
		}
Пример #16
0
/*
 *  Format is:  Range: bytes=n1-n2,n3-n4,...
 *  Where n1 is first byte pos and n2 is last byte pos
 *
 *  Examples:
 *      Range: 0-49             first 50 bytes
 *      Range: 50-99,200-249    Two 50 byte ranges from 50 and 200
 *      Range: -50              Last 50 bytes
 *      Range: 1-               Skip first byte then emit the rest
 *
 *  Return 1 if more ranges, 0 if end of ranges, -1 if bad range.
 */
static bool parseRange(MaConn *conn, char *value)
{
    MaRequest   *req;
    MaResponse  *resp;
    MaRange     *range, *last, *next;
    char        *tok, *ep;

    req = conn->request;
    resp = conn->response;

    value = mprStrdup(conn, value);
    if (value == 0) {
        return 0;
    }

    /*
     *  Step over the "bytes="
     */
    tok = mprStrTok(value, "=", &value);

    for (last = 0; value && *value; ) {
        range = mprAllocObjZeroed(req, MaRange);
        if (range == 0) {
            return 0;
        }

        /*
         *  A range "-7" will set the start to -1 and end to 8
         */
        tok = mprStrTok(value, ",", &value);
        if (*tok != '-') {
            range->start = (int) mprAtoi(tok, 10);
        } else {
            range->start = -1;
        }
        range->end = -1;

        if ((ep = strchr(tok, '-')) != 0) {
            if (*++ep != '\0') {
                /*
                 *  End is one beyond the range. Makes the math easier.
                 */
                range->end = (int) mprAtoi(ep, 10) + 1;
            }
        }
        if (range->start >= 0 && range->end >= 0) {
            range->len = range->end - range->start;
        }
        if (last == 0) {
            req->ranges = range;
        } else {
            last->next = range;
        }
        last = range;
    }

    /*
     *  Validate ranges
     */
    for (range = req->ranges; range; range = range->next) {
        if (range->end != -1 && range->start >= range->end) {
            return 0;
        }
        if (range->start < 0 && range->end < 0) {
            return 0;
        }
        next = range->next;
        if (range->start < 0 && next) {
            /* This range goes to the end, so can't have another range afterwards */
            return 0;
        }
        if (next) {
            if (next->start >= 0 && range->end > next->start) {
                return 0;
            }
        }
    }
    resp->currentRange = req->ranges;
    return (last) ? 1: 0;
}
Пример #17
0
static int locateServerRoot(char *path)
{
#if BLD_FEATURE_CONFIG_PARSE && !BLD_FEATURE_ROMFS

	if (serverRoot == 0) {
		MprFileInfo	info;
		char		searchPath[MPR_MAX_FNAME * 8], pathBuf[MPR_MAX_FNAME];
		char 		cwd[MPR_MAX_FNAME];
		char		*tok, *searchBuf;

		//
		//	No explicit server root switch was supplied so search for 
		//	"mime.types" in the search path:
		//		.
		//		..
		//		../productName
		//		../../productName
		//	For windows, we also do:
		//		modDir							(where the exe was loaded from)
		//		modDir/..  
		//		modDir/../productName  
		//		modDir/../../productName 
		//	For all:
		//		BLD_PREFIX
		//
#if WIN || WINCE
		char modDir[MPR_MAX_FNAME], modPath[MPR_MAX_FNAME];
		char module[MPR_MAX_FNAME];

		//
		//	Initially change directory to where the exe lives
		//
		GetModuleFileName(0, module, sizeof(module));
		mprGetDirName(modDir, sizeof(modDir), module);
		mprGetFullPathName(modPath, sizeof(modPath), modDir);

#if WIN
		/* NOTE: use tabs not spaces between items */
		mprSprintf(searchPath, sizeof(searchPath), 
			".	..	../%s	../../%s	"
			"%s	%s/..	%s/../%s	%s/../../%s	%s",
			BLD_PRODUCT, BLD_PRODUCT,
			modPath, modPath, modPath, BLD_PRODUCT, modPath, BLD_PRODUCT, BLD_PREFIX);
#else
		/* NOTE: use tabs not spaces between items */
		mprSprintf(searchPath, sizeof(searchPath), 
			"%s	%s	../%s	../../%s	"
			"%s/..	%s/../%s",
			MPR_STORAGE, modPath, BLD_PRODUCT, BLD_PRODUCT,
			modPath, modPath, modPath);
#endif
#else
		mprSprintf(searchPath, sizeof(searchPath), 
			".	..	../%s	../../%s	%s",
			BLD_PRODUCT, BLD_PRODUCT, BLD_PREFIX);
#endif
		
		getcwd(cwd, sizeof(cwd) - 1);
		mprLog(3, "Root search path %s, cwd %s\n", searchPath, cwd);

		searchBuf = mprStrdup(searchPath);
		path = mprStrTok(searchBuf, "\t", &tok);
		while (path) {
			mprSprintf(pathBuf, sizeof(pathBuf), "%s/mime.types", path);
			mprLog(4, "Searching for %s\n", pathBuf);
			if (fileSystem->stat(pathBuf, &info) == 0) {
				break;
			}
			path = mprStrTok(0, "\t", &tok);
		}
		if (path == 0) {
			mprError(MPR_L, MPR_USER, 
				"Can't find suitable server root directory\n"
				"Using search path %s, and current directory %s\n"
				"Ensure you have adequate permissions to access the required "
				"directories.\n", searchPath, cwd);
			mprFree(searchBuf);
			return MPR_ERR_CANT_ACCESS;
		}
		server->setServerRoot(path);
		mprFree(searchBuf);

	} else {

		//
		//	Must program the server up for the server root. It will convert this
		//	path to an absolute path which we reassign to our notion of
		//	serverRoot.
		//
		server->setServerRoot(path);
	}
	serverRoot = server->getServerRoot();

#endif

#if !BLD_FEATURE_ROMFS
	chdir(serverRoot);
#endif
	return 0;
}
Пример #18
0
/*
 *  Create the host addresses for a host. Called for hosts or for NameVirtualHost directives (host == 0).
 */
int maCreateHostAddresses(MaServer *server, MaHost *host, cchar *configValue)
{
    MaListen        *listen;
    MaHostAddress   *address;
    char            *ipAddrPort, *ipAddr, *value, *tok;
    char            addrBuf[MPR_MAX_IP_ADDR_PORT];
    int             next, port;

    address = 0;
    value = mprStrdup(server, configValue);
    ipAddrPort = mprStrTok(value, " \t", &tok);

    while (ipAddrPort) {
        if (mprStrcmpAnyCase(ipAddrPort, "_default_") == 0) {
            mprAssert(0);
            ipAddrPort = "*:*";
        }

        if (mprParseIp(server, ipAddrPort, &ipAddr, &port, -1) < 0) {
            mprError(server, "Can't parse ipAddr %s", ipAddrPort);
            continue;
        }
        mprAssert(ipAddr && *ipAddr);
        if (ipAddr[0] == '*') {
            ipAddr = mprStrdup(server, "");
        }

        /*
         *  For each listening endpiont,
         */
        for (next = 0; (listen = mprGetNextItem(server->listens, &next)) != 0; ) {
            if (port > 0 && port != listen->port) {
                continue;
            }
            if (listen->ipAddr[0] != '\0' && ipAddr[0] != '\0' && strcmp(ipAddr, listen->ipAddr) != 0) {
                continue;
            }

            /*
             *  Find the matching host address or create a new one
             */
            if ((address = maLookupHostAddress(server, listen->ipAddr, listen->port)) == 0) {
                address = maCreateHostAddress(server, listen->ipAddr, listen->port);
                mprAddItem(server->hostAddresses, address);
            }

            /*
             *  If a host is specified
             */
            if (host == 0) {
                maSetNamedVirtualHostAddress(address);

            } else {
                maInsertVirtualHost(address, host);
                if (listen->ipAddr[0] != '\0') {
                    mprSprintf(addrBuf, sizeof(addrBuf), "%s:%d", listen->ipAddr, listen->port);
                } else {
                    mprSprintf(addrBuf, sizeof(addrBuf), "%s:%d", ipAddr, listen->port);
                }
                maSetHostName(host, addrBuf);
            }
        }
        mprFree(ipAddr);
        ipAddrPort = mprStrTok(0, " \t", &tok);
    }

    if (host) {
        if (address == 0) {
            mprError(server, "No valid IP address for host %s", host->name);
            mprFree(value);
            return MPR_ERR_CANT_INITIALIZE;
        }
        if (maIsNamedVirtualHostAddress(address)) {
            maSetNamedVirtualHost(host);
        }
    }

    mprFree(value);

    return 0;
}
Пример #19
0
/*
    Build the command arguments. NOTE: argv is untrusted input.
 */
static void buildArgs(MaConn *conn, MprCmd *cmd, int *argcp, char ***argvp)
{
    MaRequest   *req;
    MaResponse  *resp;
    char        *fileName, **argv, status[8], *indexQuery, *cp, *tok;
    cchar       *actionProgram;
    int         argc, argind, len;

    req = conn->request;
    resp = conn->response;
    fileName = resp->filename;
    mprAssert(fileName);

    actionProgram = 0;
    argind = 0;
    argc = *argcp;

    if (resp->extension) {
        actionProgram = maGetMimeActionProgram(req->host, resp->extension);
        if (actionProgram != 0) {
            argc++;
        }
    }
    /*
        This is an Apache compatible hack for PHP 5.3
     */
    mprItoa(status, sizeof(status), MPR_HTTP_CODE_MOVED_TEMPORARILY, 10);
    mprAddHash(req->headers, "REDIRECT_STATUS", mprStrdup(req, status));

    /*
        Count the args for ISINDEX queries. Only valid if there is not a "=" in the query. 
        If this is so, then we must not have these args in the query env also?
     */
    indexQuery = req->parsedUri->query;
    if (indexQuery && !strchr(indexQuery, '=')) {
        argc++;
        for (cp = indexQuery; *cp; cp++) {
            if (*cp == '+') {
                argc++;
            }
        }
    } else {
        indexQuery = 0;
    }

#if BLD_WIN_LIKE || VXWORKS
{
    char    *bangScript, *cmdBuf, *program, *cmdScript;

    /*
        On windows we attempt to find an executable matching the fileName.
        We look for *.exe, *.bat and also do unix style processing "#!/program"
     */
    findExecutable(conn, &program, &cmdScript, &bangScript, fileName);
    mprAssert(program);

    if (cmdScript) {
        /*
            Cmd/Batch script (.bat | .cmd)
            Convert the command to the form where there are 4 elements in argv
            that cmd.exe can interpret.

                argv[0] = cmd.exe
                argv[1] = /Q
                argv[2] = /C
                argv[3] = ""script" args ..."
         */
        argc = 4;

        len = (argc + 1) * sizeof(char*);
        argv = (char**) mprAlloc(cmd, len);
        memset(argv, 0, len);

        argv[argind++] = program;               /* Duped in findExecutable */
        argv[argind++] = mprStrdup(cmd, "/Q");
        argv[argind++] = mprStrdup(cmd, "/C");

        len = (int) strlen(cmdScript) + 2 + 1;
        cmdBuf = (char*) mprAlloc(cmd, len);
        mprSprintf(cmdBuf, len, "\"%s\"", cmdScript);
        argv[argind++] = cmdBuf;

        mprSetCmdDir(cmd, cmdScript);
        mprFree(cmdScript);
        /*  program will get freed when argv[] gets freed */
        
    } else if (bangScript) {
        /*
            Script used "#!/program". NOTE: this may be overridden by a mime
            Action directive.
         */
        argc++;     /* Adding bangScript arg */

        len = (argc + 1) * sizeof(char*);
        argv = (char**) mprAlloc(cmd, len);
        memset(argv, 0, len);

        argv[argind++] = program;       /* Will get freed when argv[] is freed */
        argv[argind++] = bangScript;    /* Will get freed when argv[] is freed */
        mprSetCmdDir(cmd, bangScript);

    } else {
        /*
            Either unknown extension or .exe (.out) program.
         */
        len = (argc + 1) * sizeof(char*);
        argv = (char**) mprAlloc(cmd, len);
        memset(argv, 0, len);

        if (actionProgram) {
            argv[argind++] = mprStrdup(cmd, actionProgram);
        }
        argv[argind++] = program;
    }
}
#else
    len = (argc + 1) * (int) sizeof(char*);
    argv = (char**) mprAlloc(cmd, len);
    memset(argv, 0, len);

    if (actionProgram) {
        argv[argind++] = mprStrdup(cmd, actionProgram);
    }
    argv[argind++] = mprStrdup(cmd, fileName);

#endif

    /*
        ISINDEX queries. Only valid if there is not a "=" in the query. If this is so, then we must not
        have these args in the query env also?
     */
    if (indexQuery) {
        indexQuery = mprStrdup(cmd, indexQuery);

        cp = mprStrTok(indexQuery, "+", &tok);
        while (cp) {
            argv[argind++] = mprEscapeCmd(resp, mprUrlDecode(resp, cp), 0);
            cp = mprStrTok(NULL, "+", &tok);
        }
    }
    
    mprAssert(argind <= argc);
    argv[argind] = 0;
    *argcp = argc;
    *argvp = argv;
}
Пример #20
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(MaConn *conn, char **program, char **script, char **bangScript, char *fileName)
{
    MaRequest       *req;
    MaResponse      *resp;
    MaLocation      *location;
    MprHash         *hp;
    MprFile         *file;
    cchar           *actionProgram, *ext, *cmdShell;
    char            *tok, buf[MPR_MAX_FNAME + 1], *path;

    req = conn->request;
    resp = conn->response;
    location = req->location;

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

    actionProgram = maGetMimeActionProgram(conn->host, req->mimeType);
    ext = resp->extension;

    /*
        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 /* && *ext == '\0' */) {
        for (hp = 0; (hp = mprGetNextHash(location->extensions, hp)) != 0; ) {
            path = mprStrcat(resp, -1, fileName, ".", hp->key, NULL);
            if (access(path, X_OK) == 0) {
                break;
            }
            mprFree(path);
            path = 0;
        }
        if (hp) {
            ext = hp->key;
        } else {
            path = fileName;
        }

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

#if BLD_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 = mprStrdup(resp, path);
        *program = mprStrdup(resp, cmdShell);
        return;
    }
#endif

    if ((file = mprOpen(resp, path, O_RDONLY, 0)) != 0) {
        if (mprRead(file, buf, MPR_MAX_FNAME) > 0) {
            mprFree(file);
            buf[MPR_MAX_FNAME] = '\0';
            if (buf[0] == '#' && buf[1] == '!') {
                cmdShell = mprStrTok(&buf[2], " \t\r\n", &tok);
                if (cmdShell[0] != '/' && (cmdShell[0] != '\0' && cmdShell[1] != ':')) {
                    /*
                        If we can't access the command shell and the command is not an absolute path, 
                        look in the same directory as the script.
                     */
                    if (mprPathExists(resp, cmdShell, X_OK)) {
                        cmdShell = mprJoinPath(resp, mprGetPathDir(resp, path), cmdShell);
                    }
                }
                if (actionProgram) {
                    *program = mprStrdup(resp, actionProgram);
                } else {
                    *program = mprStrdup(resp, cmdShell);
                }
                *bangScript = mprStrdup(resp, path);
                return;
            }
        } else {
            mprFree(file);
        }
    }

    if (actionProgram) {
        *program = mprStrdup(resp, actionProgram);
        *bangScript = mprStrdup(resp, path);
    } else {
        *program = mprStrdup(resp, path);
    }
    return;
}
Пример #21
0
int MaSslModule::parseConfig(char *key, char *value, MaServer *server, 
	MaHost *host, MaAuth *auth, MaDir *dir, MaLocation *location)
{
	MaSslConfig	*config;
	char		pathBuf[MPR_MAX_FNAME], prefix[MPR_MAX_FNAME];
	char		*tok, *word, *enable, *provider;
	int			protoMask, mask;

	mprStrcpy(prefix, sizeof(prefix), key);
	prefix[3] = '\0';
	if (mprStrCmpAnyCase(prefix, "SSL") != 0) {
		return 0;
	}

	if (mprStrCmpAnyCase(key, "SSLEngine") == 0) {
		enable = mprStrTok(value, " \t", &tok);
		provider = mprStrTok(0, " \t", &tok);
		if (mprStrCmpAnyCase(value, "on") == 0) {
			if (sslProvider == 0) {
				mprError(MPR_L, MPR_LOG, "Missing an SSL Provider\n");
				return MPR_ERR_BAD_SYNTAX;
			}
			config = (MaSslConfig*) sslConfigTable->lookup(host->getName());
			if (config == 0) {
				config = sslProvider->newConfig(host);
				mprAssert(config);
				sslConfigTable->insert(config);
			}
			host->setSecure(1);
			host->server->setSslListeners(host, config);
		}
		return 1;
	}

	config = (MaSslConfig*) sslConfigTable->lookup(host->getName());
	if (config == 0) {
		mprError(MPR_L, MPR_LOG, "Missing SSLEngine directive\n");
		return MPR_ERR_BAD_SYNTAX;
	}

	if (host->makePath(pathBuf, sizeof(pathBuf), mprStrTrim(value, '\"')) 
			== 0) {
		mprError(MPR_L, MPR_LOG, "SSL path is too long");
		return MPR_ERR_BAD_SYNTAX;
    }

	if (mprStrCmpAnyCase(key, "SSLCACertificatePath") == 0) {
		config->setCaPath(pathBuf);
		return 1;

	} else if (mprStrCmpAnyCase(key, "SSLCACertificateFile") == 0) {
		config->setCaFile(pathBuf);
		return 1;

	} else if (mprStrCmpAnyCase(key, "SSLCertificateFile") == 0) {
		config->setCertFile(pathBuf);
		return 1;

	} else if (mprStrCmpAnyCase(key, "SSLCertificateKeyFile") == 0) {
		config->setKeyFile(pathBuf);
		return 1;

	} else if (mprStrCmpAnyCase(key, "SSLCipherSuite") == 0) {
		config->setCipherSuite(value);
		return 1;

	} else if (mprStrCmpAnyCase(key, "SSLVerifyClient") == 0) {
		if (mprStrCmpAnyCase(value, "require") == 0) {
			config->setVerifyClient(1);
		} else if (mprStrCmpAnyCase(value, "none") == 0) {
			config->setVerifyClient(0);
		} else {
			return -1;
		}
		return 1;

	} else if (mprStrCmpAnyCase(key, "SSLProtocol") == 0) {
		protoMask = 0;
		word = mprStrTok(value, " \t", &tok);
		while (word) {
			mask = -1;
			if (*word == '-') {
				word++;
				mask = 0;
			} else if (*word == '+') {
				word++;
			}
			if (mprStrCmpAnyCase(word, "SSLv2") == 0) {
				protoMask &= ~(MPR_HTTP_PROTO_SSLV2 & ~mask);
				protoMask |= (MPR_HTTP_PROTO_SSLV2 & mask);

			} else if (mprStrCmpAnyCase(word, "SSLv3") == 0) {
				protoMask &= ~(MPR_HTTP_PROTO_SSLV3 & ~mask);
				protoMask |= (MPR_HTTP_PROTO_SSLV3 & mask);

			} else if (mprStrCmpAnyCase(word, "TLSv1") == 0) {
				protoMask &= ~(MPR_HTTP_PROTO_TLSV1 & ~mask);
				protoMask |= (MPR_HTTP_PROTO_TLSV1 & mask);

			} else if (mprStrCmpAnyCase(word, "ALL") == 0) {
				protoMask &= ~(MPR_HTTP_PROTO_ALL & ~mask);
				protoMask |= (MPR_HTTP_PROTO_ALL & mask);
			}
			word = mprStrTok(0, " \t", &tok);
		}
		config->setSslProto(protoMask);
		return 1;
	}
	return 0;
}
Пример #22
0
int MaClient::parseHeader(char *line)
{
	char	*key, *value, *tok, *tp;

	mprAssert(line && *line);

	if ((key = mprStrTok(line, ": \t\n", &tok)) == 0) {
		formatError("Bad HTTP header");
		responseCode = MPR_HTTP_CLIENT_ERROR;
		finishRequest(1);
		return MPR_ERR_BAD_STATE;
	}
	if ((value = mprStrTok(0, "\n", &tok)) == 0) {
		value = "";
	}
	while (isspace((uchar) *value)) {
		value++;
	}

	//	Upper to be consistent with Request?
	mprStrLower(key);
	headerValues->insert(new MprStringHashEntry(key, value));

	if (strcmp("www-authenticate", key) == 0) {
		tp = value;
		while (*value && !isspace((uchar) *value)) {
			value++;
		}
		*value++ = '\0';
		mprStrLower(tp);
		mprFree(serverAuthType);
		serverAuthType = mprStrdup(tp);

		if (parseAuthenticate(value) < 0) {
			formatError("Bad Authenticate header");
			responseCode = MPR_HTTP_CLIENT_ERROR;
			finishRequest(1);
			return MPR_ERR_BAD_STATE;
		}

	} else if (strcmp("content-length", key) == 0) {
		contentLength = atoi(value);
		if (mprStrCmpAnyCase(method, "HEAD") != 0) {
			contentRemaining = atoi(value);
		}

	} else if (strcmp("connection", key) == 0) {
		mprStrLower(value);
		if (strcmp(value, "close") == 0) {
			flags &= ~MPR_HTTP_KEEP_ALIVE;
#if BLD_FEATURE_KEEP_ALIVE
		} else if (strcmp(value, "keep-alive") == 0) {
			if (userFlags & MPR_HTTP_KEEP_ALIVE) {
				flags |= MPR_HTTP_KEEP_ALIVE;
			}
#endif
		}
	} else if (strcmp("transfer-encoding", key) == 0) {
		mprStrLower(value);
		if (strcmp(value, "chunked") == 0) {
			flags |= MPR_HTTP_INPUT_CHUNKED;
		}
	}
	return 0;
}
Пример #23
0
    MAIN(ejscMain, int argc, char **argv)
#endif
{
    Mpr             *mpr;
    Ejs             *ejs;
    EcCompiler      *cp;
    EjsService      *vmService;
    MprList         *useModules;
    char            *argp, *searchPath, *outputFile, *certFile, *name, *tok, *modules, *spec;
    int             nextArg, err, ejsFlags, ecFlags, bind, debug, doc, empty, merge;
    int             warnLevel, noout, parseOnly, tabWidth, optimizeLevel, compilerMode, lang;

    /*
     *  Create the Embedthis Portable Runtime (MPR) and setup a memory failure handler
     */
    mpr = mprCreate(argc, argv, ejsMemoryFailure);
    mprSetAppName(mpr, argv[0], 0, 0);

    if (mprStart(mpr, 0) < 0) {
        mprError(mpr, "Can't start mpr services");
        return EJS_ERR;
    }

    err = 0;
    searchPath = 0;
    compilerMode = PRAGMA_MODE_STANDARD;
    certFile = 0;
    ecFlags = 0;

    bind = 0;
    debug = 0;
    doc = 0;
    empty = 0;
    merge = 0;
    noout = 0;
    parseOnly = 0;
    tabWidth = 4;
    warnLevel = 1;
    outputFile = 0;
    optimizeLevel = 9;
    lang = BLD_FEATURE_EJS_LANG;

    useModules = mprCreateList(mpr);

    for (nextArg = 1; nextArg < argc; nextArg++) {
        argp = argv[nextArg];
        if (*argp != '-') {
            break;
        }
        if (strcmp(argp, "--bind") == 0) {
            bind = 1;

        } else if (strcmp(argp, "--debug") == 0) {
            debug = 1;

        } else if (strcmp(argp, "--doc") == 0) {
            doc = 1;

        } else if (strcmp(argp, "--lang") == 0) {
            if (nextArg >= argc) {
                err++;
            } else {
                spec = argv[++nextArg];
                if (mprStrcmpAnyCase(spec, "ecma") == 0) {
                    lang = EJS_SPEC_ECMA;
                } else if (mprStrcmpAnyCase(spec, "plus") == 0) {
                    lang = EJS_SPEC_PLUS;
                } else if (mprStrcmpAnyCase(spec, "fixed") == 0) {
                    lang = EJS_SPEC_FIXED;
                }
            }

        } else if (strcmp(argp, "--empty") == 0) {
            empty = 1;

        } else if (strcmp(argp, "--log") == 0) {
            /*
             *  Undocumented logging switch
             */
            if (nextArg >= argc) {
                err++;
            } else {
                ejsStartLogging(mpr, argv[++nextArg]);
            }

        } else if (strcmp(argp, "--merge") == 0) {
            merge = 1;

        } else if (strcmp(argp, "--nobind") == 0) {
            bind = 0;

        } else if (strcmp(argp, "--noout") == 0) {
            noout = 1;

        } else if (strcmp(argp, "--standard") == 0) {
            compilerMode = PRAGMA_MODE_STANDARD;

        } else if (strcmp(argp, "--strict") == 0) {
            compilerMode = PRAGMA_MODE_STRICT;

        } else if (strcmp(argp, "--optimize") == 0) {
            if (nextArg >= argc) {
                err++;
            } else {
                optimizeLevel = atoi(argv[++nextArg]);
            }

        } else if (strcmp(argp, "--out") == 0) {
            /*
             *  Create a single output module file containing all modules
             */
            if (nextArg >= argc) {
                err++;
            } else {
                outputFile = argv[++nextArg];
            }

        } else if (strcmp(argp, "--parse") == 0) {
            parseOnly = 1;

        } else if (strcmp(argp, "--search") == 0 || strcmp(argp, "--searchpath") == 0) {
            if (nextArg >= argc) {
                err++;
            } else {
                searchPath = argv[++nextArg];
            }

        } else if (strcmp(argp, "--sign") == 0) {
            if (nextArg >= argc) {
                err++;
            } else {
                certFile = argv[++nextArg];
            }

        } else if (strcmp(argp, "--tabWidth") == 0) {
            if (nextArg >= argc) {
                err++;
            } else {
                tabWidth = atoi(argv[++nextArg]);
            }

        } else if (strcmp(argp, "--use") == 0) {
            if (nextArg >= argc) {
                err++;
            } else {
                modules = mprStrdup(mpr, argv[++nextArg]);
                name = mprStrTok(modules, " \t", &tok);
                while (name != NULL) {
                    mprAddItem(useModules, name);
                    name = mprStrTok(NULL, " \t", &tok);
                }
            }

        } else if (strcmp(argp, "--version") == 0 || strcmp(argp, "-V") == 0) {
            mprPrintfError(mpr, "%s %s-%s\n", BLD_NAME, BLD_VERSION, BLD_VERSION);
            return 0;

        } else if (strcmp(argp, "--warn") == 0) {
            if (nextArg >= argc) {
                err++;
            } else {
                warnLevel = atoi(argv[++nextArg]);
            }

#if BLD_FEATURE_EJS_WEB
        } else if (strcmp(argp, "--web") == 0) {
#if BLD_FEATURE_EJS_DB
            mprAddItem(useModules, "ejs.db");
#endif
            mprAddItem(useModules, "ejs.web");
#endif

        } else {
            err++;
            break;
        }
    }
    if (noout || merge) {
        bind = 1;
    }
    if (outputFile && noout) {
        mprPrintfError(mpr, "Can't use --out and --noout\n");
        err++;
    }
    if (argc == nextArg) {
        err++;
    }
    if (err) {
        /*
         *  Usage Examples:
         *      ejsc Person.es User.es Customer.es
         *      ejsc --out group.mod Person.es User.es Customer.es
         *      ejsc --out group.mod Person.es User.es Customer.es
         */
        mprPrintfError(mpr,
            "Usage: %s [options] files...\n"
            "  Ejscript compiler options:\n"
            "  --bind               # Bind global properties to slots. Requires --out.\n"
            "  --debug              # Include symbolic debugging information in output\n"
            "  --doc                # Include documentation strings in output\n"
            "  --lang               # Language compliance (ecma|plus|fixed)\n"
            "  --empty              # Create empty interpreter\n"
            "  --merge              # Merge dependent input modules into the output\n"
            "  --noout              # Do not generate any output\n"
            "  --optimize level     # Set optimization level (0-9)\n"
            "  --out filename       # Name a single output module (default: \"default.mod\")\n"
            "  --parse              # Just parse source. No output\n"
            "  --search ejsPath     # Module search path\n"
            "  --standard           # Default compilation mode to standard (default)\n"
            "  --strict             # Default compilation mode to strict\n"
#if FUTURE
            "  --sign certFile      # Sign the module file (not implemented) \n"
            "  --tabwidth           # Tab width for '^' error reporting\n"
#endif
            "  --use 'module, ...'  # List of modules to pre-load\n"
            "  --version            # Emit the compiler version information\n"
            "  --warn level         # Set the warning message level (0-9)\n\n",
            mpr->name);
        return -1;
    }

    /*
     *  Need an interpreter when compiling
     */
    vmService = ejsCreateService(mpr);
    if (vmService == 0) {
        return MPR_ERR_NO_MEMORY;
    }

    ejsFlags = EJS_FLAG_NO_EXE;
    if (empty) {
        ejsFlags |= EJS_FLAG_EMPTY;
    }
    if (doc) {
        ejsFlags |= EJS_FLAG_DOC;
    }
    ejs = ejsCreate(vmService, NULL, searchPath, ejsFlags);
    if (ejs == 0) {
        return MPR_ERR_NO_MEMORY;
    }

    ecFlags = 0;
    ecFlags |= (debug) ? EC_FLAGS_DEBUG: 0;
    ecFlags |= (empty) ? EC_FLAGS_EMPTY: 0;
    ecFlags |= (merge) ? EC_FLAGS_MERGE: 0;
    ecFlags |= (bind) ? EC_FLAGS_BIND: 0;
    ecFlags |= (noout) ? EC_FLAGS_NO_OUT: 0;
    ecFlags |= (parseOnly) ? EC_FLAGS_PARSE_ONLY: 0;

    cp = ecCreateCompiler(ejs, ecFlags, lang);
    if (cp == 0) {
        return MPR_ERR_NO_MEMORY;
    }

    ecSetOptimizeLevel(cp, optimizeLevel);
    ecSetWarnLevel(cp, warnLevel);
    ecSetDefaultMode(cp, compilerMode);
    ecSetTabWidth(cp, tabWidth);
    ecSetOutputFile(cp, outputFile);
    ecSetCertFile(cp, certFile);

    if (preloadModules(cp, useModules) < 0) {
        return EJS_ERR;
    }
    if (nextArg < argc) {
        /*
         *  Compile the source files supplied on the command line. This will compile in-memory and
         *  optionally also save to module files.
         */
        if (ecCompile(cp, argc - nextArg, &argv[nextArg], 0) < 0) {
            err++;
        }
    }
    if (cp->errorCount > 0) {
        err++;
    }
#if VXWORKS
    mprFree(cp);
    mprFree(ejs);
    if (mprStop(mpr)) {
        mprFree(mpr);
    }
#endif
    return err;
}
Пример #24
0
int main(int argc, char **argv)
{
    Mpr             *mpr;
    EcCompiler      *cp;
    EjsService      *vmService;
    Ejs             *ejs;
    MprList         *useModules, *files;
    cchar           *cmd, *className, *methodName;
    char            *argp, *searchPath, *modules, *name, *tok, *extraFiles, *spec;
    int             nextArg, err, ejsFlags, ecFlags, stats, run, merge, bind, noout, debug, optimizeLevel, nobind, warnLevel;
    int             compilerMode, lang;

    /*
     *  Create the Embedthis Portable Runtime (MPR) and setup a memory failure handler
     */
    mpr = mprCreate(argc, argv, ejsMemoryFailure);
    mprSetAppName(mpr, argv[0], 0, 0);

    if (mprStart(mpr, 0) < 0) {
        mprError(mpr, "Can't start mpr services");
        return EJS_ERR;
    }

    err = 0;
    className = 0;
    cmd = 0;
    methodName = 0;
    searchPath = 0;
    stats = 0;
    run = 1;
    merge = 0;
    bind = 1;
    nobind = 0;
    noout = 1;
    debug = 1;
    warnLevel = 1;
    optimizeLevel = 9;
    compilerMode = PRAGMA_MODE_STANDARD;
    lang = BLD_FEATURE_EJS_LANG;

    useModules = mprCreateList(mpr);
    files = mprCreateList(mpr);

    ejsFlags = EJS_FLAG_COMPILER;

    for (nextArg = 1; nextArg < argc; nextArg++) {
        argp = argv[nextArg];
        if (*argp != '-') {
            break;
        }

        if (strcmp(argp, "--bind") == 0) {
            /* Ignore. Not required and only here for compatibility with ec */

        } else if (strcmp(argp, "--class") == 0) {
            if (nextArg >= argc) {
                err++;
            } else {
                className = argv[++nextArg];
            }

        } else if (strcmp(argp, "--cmd") == 0 || strcmp(argp, "-c") == 0) {
            if (nextArg >= argc) {
                err++;
            } else {
                cmd = argv[++nextArg];
            }

        } else if (strcmp(argp, "--debug") == 0) {
            debug = 1;

        } else if (strcmp(argp, "--lang") == 0) {
            if (nextArg >= argc) {
                err++;
            } else {
                spec = argv[++nextArg];
                if (mprStrcmpAnyCase(spec, "ecma") == 0) {
                    lang = EJS_SPEC_ECMA;
                } else if (mprStrcmpAnyCase(spec, "plus") == 0) {
                    lang = EJS_SPEC_PLUS;
                } else if (mprStrcmpAnyCase(spec, "fixed") == 0) {
                    lang = EJS_SPEC_FIXED;
                }
            }

        } else if (strcmp(argp, "--files") == 0 || strcmp(argp, "-f") == 0) {
            if (nextArg >= argc) {
                err++;
            } else {
                extraFiles = mprStrdup(mpr, argv[++nextArg]);
                name = mprStrTok(extraFiles, " \t", &tok);
                while (name != NULL) {
                    mprAddItem(files, name);
                    name = mprStrTok(NULL, " \t", &tok);
                }
            }

        } else if (strcmp(argp, "--log") == 0) {
            if (nextArg >= argc) {
                err++;
            } else {
                ejsStartLogging(mpr, argv[++nextArg]);
            }

        } else if (strcmp(argp, "--method") == 0) {
            if (nextArg >= argc) {
                err++;
            } else {
                methodName = argv[++nextArg];
            }

        } else if (strcmp(argp, "--nobind") == 0) {
            /*
             *  This is a hidden switch just for the compiler developers
             */
            nobind = 1;
            bind = 0;

        } else if (strcmp(argp, "--nodebug") == 0) {
            debug = 0;

        } else if (strcmp(argp, "--optimize") == 0) {
            if (nextArg >= argc) {
                err++;
            } else {
                optimizeLevel = atoi(argv[++nextArg]);
            }

        } else if (strcmp(argp, "--searchpath") == 0) {
            if (nextArg >= argc) {
                err++;
            } else {
                searchPath = argv[++nextArg];
            }

        } else if (strcmp(argp, "--standard") == 0) {
            compilerMode = PRAGMA_MODE_STANDARD;

        } else if (strcmp(argp, "--stats") == 0) {
            stats = 1;

        } else if (strcmp(argp, "--strict") == 0) {
            compilerMode = PRAGMA_MODE_STRICT;

        } else if (strcmp(argp, "--use") == 0) {
            if (nextArg >= argc) {
                err++;
            } else {
                modules = mprStrdup(mpr, argv[++nextArg]);
                name = mprStrTok(modules, " \t", &tok);
                while (name != NULL) {
                    mprAddItem(useModules, name);
                    name = mprStrTok(NULL, " \t", &tok);
                }
            }

        } else if (strcmp(argp, "--version") == 0 || strcmp(argp, "-V") == 0) {
            mprErrorPrintf(mpr, "%s %s\n"
                "Copyright (C) Embedthis Software 2003-2009\n"
                "Copyright (C) Michael O'Brien 2003-2009\n",
               BLD_NAME, BLD_VERSION);
            exit(0);

        } else if (strcmp(argp, "--warn") == 0) {
            if (nextArg >= argc) {
                err++;
            } else {
                warnLevel = atoi(argv[++nextArg]);
            }

        } else {
            err++;
            break;
        }
    }

    if (err) {
        /*
         *  If --method or --class is specified, then the named class.method will be run (method defaults to "main", class
         *  defaults to first class with a "main").
         *
         *  Examples:
         *      ejs
         *      ejs script.es arg1 arg2 arg3
         *      ejs --class "Customer" --method "start" --files "script1.es script2.es" main.es
         */
        mprErrorPrintf(mpr,
            "Usage: %s [options] script.es [arguments] ...\n"
            "  Ejscript shell program options:\n"
            "  --class className        # Name of class containing method to run\n"
            "  --cmd ejscriptCode       # Literal ejscript statements to execute\n"
            "  --debug                  # Include symbolic debugging information in output\n"
            "  --lang                   # Language compliance (ecma|plus|fixed)\n"
            "  --files \"files..\"        # Extra source to compile\n"
            "  --log logSpec            # Internal compiler diagnostics logging\n"
            "  --method methodName      # Name of method to run. Defaults to main\n"
            "  --nodebug                # Omit symbolic debugging information in output\n"
            "  --optimize level         # Set the optimization level (0-9 default is 9)\n"
            "  --searchpath ejsPath     # Module search path\n"
            "  --standard               # Default compilation mode to standard (default)\n"
            "  --stats                  # Print stats on exit\n"
            "  --strict                 # Default compilation mode to strict\n"
            "  --use 'module, ...'      # List of modules to pre-load\n"
            "  --version                # Emit the compiler version information\n"
            "  --warn level             # Set the warning message level (0-9 default is 0)\n\n",
            mpr->name);
        return -1;
    }

    vmService = ejsCreateService(mpr);
    if (vmService == 0) {
        return MPR_ERR_NO_MEMORY;
    }

    if (searchPath) {
        ejsSetSearchPath(vmService, searchPath);
    }

    ejs = ejsCreate(vmService, 0, ejsFlags);
    if (ejs == 0) {
        return MPR_ERR_NO_MEMORY;
    }

    ecFlags = 0;
    ecFlags |= (run) ? EC_FLAGS_RUN: 0;
    ecFlags |= (merge) ? EC_FLAGS_MERGE: 0;
    ecFlags |= (bind) ? EC_FLAGS_BIND_GLOBALS: 0;
    ecFlags |= (nobind) ? EC_FLAGS_NO_BIND: 0;
    ecFlags |= (noout) ? EC_FLAGS_NO_OUT: 0;
    ecFlags |= (debug) ? EC_FLAGS_DEBUG: 0;

    cp = ecCreateCompiler(ejs, ecFlags, lang);
    if (cp == 0) {
        return MPR_ERR_NO_MEMORY;
    }

    ecSetOptimizeLevel(cp, optimizeLevel);
    ecSetWarnLevel(cp, warnLevel);
    ecSetDefaultMode(cp, compilerMode);

    if (preloadModules(cp, useModules) < 0) {
        return EJS_ERR;
    }

    if (cmd) {
        if (interpretCommands(cp, cmd) < 0) {
            err++;
        }

    } else if (nextArg < argc) {
        name = argv[nextArg];
        mprAddItem(files, argv[nextArg]);
        if (interpretFiles(cp, files, argc - nextArg, &argv[nextArg], className, methodName) < 0) {
            err++;
        }

    } else {
        /*
         *  No args - run as an interactive shell
         */
        if (interpretCommands(cp, NULL) < 0) {
            err++;
        }
    }

#if BLD_DEBUG
    if (stats) {
        mprSetLogLevel(ejs, 1);
        ejsPrintAllocReport(ejs);
    }
#endif

    mprFree(mpr);
    return err;
}
Пример #25
0
static int parseDir(MaHttp *http, cchar *key, char *value, MaConfigState *state)
{
    MaStage     *handler;
    Dir         *dir;
    
    char    *name, *extensions, *option, *nextTok, *junk;

    handler = maLookupStage(http, "dirHandler");
    dir = handler->stageData;
    mprAssert(dir);
    
    if (mprStrcmpAnyCase(key, "AddIcon") == 0) {
        /*  AddIcon file ext ext ext */
        /*  Not yet supported */
        name = mprStrTok(value, " \t", &extensions);
        parseWords(dir->extList, extensions);
        return 1;

    } else if (mprStrcmpAnyCase(key, "DefaultIcon") == 0) {
        /*  DefaultIcon file */
        /*  Not yet supported */
        dir->defaultIcon = mprStrTok(value, " \t", &junk);
        return 1;

    } else if (mprStrcmpAnyCase(key, "IndexOrder") == 0) {
        /*  IndexOrder ascending|descending name|date|size */
        mprFree(dir->sortField);
        dir->sortField = 0;
        option = mprStrTok(value, " \t", &dir->sortField);
        if (mprStrcmpAnyCase(option, "ascending") == 0) {
            dir->sortOrder = 1;
        } else {
            dir->sortOrder = -1;
        }
        if (dir->sortField) {
            dir->sortField = mprStrdup(dir, dir->sortField);
        }
        return 1;

    } else if (mprStrcmpAnyCase(key, "IndexIgnore") == 0) {
        /*  IndexIgnore pat ... */
        /*  Not yet supported */
        parseWords(dir->ignoreList, value);
        return 1;

    } else if (mprStrcmpAnyCase(key, "IndexOptions") == 0) {
        /*  IndexOptions FancyIndexing|FoldersFirst ... (set of options) */
        option = mprStrTok(value, " \t", &nextTok);
        while (option) {
            if (mprStrcmpAnyCase(option, "FancyIndexing") == 0) {
                dir->fancyIndexing = 1;
            } else if (mprStrcmpAnyCase(option, "HTMLTable") == 0) {
                dir->fancyIndexing = 2;
            } else if (mprStrcmpAnyCase(option, "FoldersFirst") == 0) {
                dir->foldersFirst = 1;
            }
            option = mprStrTok(nextTok, " \t", &nextTok);
        }
        return 1;

    } else if (mprStrcmpAnyCase(key, "Options") == 0) {
        /*  Options Indexes */
        option = mprStrTok(value, " \t", &nextTok);
        while (option) {
            if (mprStrcmpAnyCase(option, "Indexes") == 0) {
                dir->enabled = 1;
            }
            option = mprStrTok(nextTok, " \t", &nextTok);
        }
        return 1;
    }
    return 0;
}