コード例 #1
0
ファイル: InitRequest.cpp プロジェクト: boone/passenger
void
Controller::initializeUnionStation(Client *client, Request *req, RequestAnalysis &analysis) {
	if (analysis.unionStationSupport) {
		Options &options = req->options;
		ServerKit::HeaderTable &headers = req->secureHeaders;

		const LString *key = headers.lookup("!~UNION_STATION_KEY");
		if (key == NULL || key->size == 0) {
			disconnectWithError(&client, "header !~UNION_STATION_KEY must be set.");
			return;
		}
		key = psg_lstr_make_contiguous(key, req->pool);

		const LString *filters = headers.lookup("!~UNION_STATION_FILTERS");
		if (filters != NULL) {
			filters = psg_lstr_make_contiguous(filters, req->pool);
		}

		options.transaction = unionStationContext->newTransaction(
			options.getAppGroupName(), "requests",
			string(key->start->data, key->size),
			(filters != NULL)
				? string(filters->start->data, filters->size)
				: string());
		if (!options.transaction->isNull()) {
			options.analytics = true;
			options.unionStationKey = StaticString(key->start->data, key->size);
		}

		req->beginStopwatchLog(&req->stopwatchLogs.requestProcessing, "request processing");
		req->logMessage(string("Request method: ") + http_method_str(req->method));
		req->logMessage("URI: " + StaticString(req->path.start->data, req->path.size));
	}
}
コード例 #2
0
ファイル: InitRequest.cpp プロジェクト: boone/passenger
void
Controller::fillPoolOption(Request *req, StaticString &field,
	const HashedStaticString &name)
{
	const LString *value = req->secureHeaders.lookup(name);
	if (value != NULL && value->size > 0) {
		value = psg_lstr_make_contiguous(value, req->pool);
		field = StaticString(value->start->data, value->size);
	}
}
コード例 #3
0
ファイル: InitRequest.cpp プロジェクト: boone/passenger
void
Controller::fillPoolOptionSecToMsec(Request *req, unsigned int &field,
	const HashedStaticString &name)
{
	const LString *value = req->secureHeaders.lookup(name);
	if (value != NULL && value->size > 0) {
		value = psg_lstr_make_contiguous(value, req->pool);
		field = stringToInt(StaticString(value->start->data, value->size)) * 1000;
	}
}
コード例 #4
0
ファイル: InitRequest.cpp プロジェクト: boone/passenger
void
Controller::createNewPoolOptions(Client *client, Request *req,
	const HashedStaticString &appGroupName)
{
	ServerKit::HeaderTable &secureHeaders = req->secureHeaders;
	Options &options = req->options;

	SKC_TRACE(client, 2, "Creating new pool options: app group name=" << appGroupName);

	options = Options();

	const LString *scriptName = secureHeaders.lookup("!~SCRIPT_NAME");
	const LString *appRoot = secureHeaders.lookup("!~PASSENGER_APP_ROOT");
	if (scriptName == NULL || scriptName->size == 0) {
		if (appRoot == NULL || appRoot->size == 0) {
			const LString *documentRoot = secureHeaders.lookup("!~DOCUMENT_ROOT");
			if (OXT_UNLIKELY(documentRoot == NULL || documentRoot->size == 0)) {
				disconnectWithError(&client, "client did not send a !~PASSENGER_APP_ROOT or a !~DOCUMENT_ROOT header");
				return;
			}

			documentRoot = psg_lstr_make_contiguous(documentRoot, req->pool);
			appRoot = psg_lstr_create(req->pool,
				extractDirNameStatic(StaticString(documentRoot->start->data,
					documentRoot->size)));
		} else {
			appRoot = psg_lstr_make_contiguous(appRoot, req->pool);
		}
		options.appRoot = HashedStaticString(appRoot->start->data, appRoot->size);
	} else {
		if (appRoot == NULL || appRoot->size == 0) {
			const LString *documentRoot = secureHeaders.lookup("!~DOCUMENT_ROOT");
			if (OXT_UNLIKELY(documentRoot == NULL || documentRoot->size == 0)) {
				disconnectWithError(&client, "client did not send a !~DOCUMENT_ROOT header");
				return;
			}

			documentRoot = psg_lstr_null_terminate(documentRoot, req->pool);
			documentRoot = resolveSymlink(StaticString(documentRoot->start->data,
				documentRoot->size), req->pool);
			appRoot = psg_lstr_create(req->pool,
				extractDirNameStatic(StaticString(documentRoot->start->data,
					documentRoot->size)));
		} else {
			appRoot = psg_lstr_make_contiguous(appRoot, req->pool);
		}
		options.appRoot = HashedStaticString(appRoot->start->data, appRoot->size);
		scriptName = psg_lstr_make_contiguous(scriptName, req->pool);
		options.baseURI = StaticString(scriptName->start->data, scriptName->size);
	}

	fillPoolOptionsFromConfigCaches(options, req->pool, req->config);

	const LString *appType = secureHeaders.lookup("!~PASSENGER_APP_TYPE");
	if (appType == NULL || appType->size == 0) {
		AppTypeDetector detector;
		PassengerAppType type = detector.checkAppRoot(options.appRoot);
		if (type == PAT_NONE || type == PAT_ERROR) {
			disconnectWithError(&client, "client did not send a recognized !~PASSENGER_APP_TYPE header");
			return;
		}
		options.appType = getAppTypeName(type);
	} else {
		fillPoolOption(req, options.appType, "!~PASSENGER_APP_TYPE");
	}

	options.appGroupName = appGroupName;

	fillPoolOption(req, options.appType, "!~PASSENGER_APP_TYPE");
	fillPoolOption(req, options.environment, "!~PASSENGER_APP_ENV");
	fillPoolOption(req, options.ruby, "!~PASSENGER_RUBY");
	fillPoolOption(req, options.python, "!~PASSENGER_PYTHON");
	fillPoolOption(req, options.nodejs, "!~PASSENGER_NODEJS");
	fillPoolOption(req, options.meteorAppSettings, "!~PASSENGER_METEOR_APP_SETTINGS");
	fillPoolOption(req, options.user, "!~PASSENGER_USER");
	fillPoolOption(req, options.group, "!~PASSENGER_GROUP");
	fillPoolOption(req, options.minProcesses, "!~PASSENGER_MIN_PROCESSES");
	fillPoolOption(req, options.maxProcesses, "!~PASSENGER_MAX_PROCESSES");
	fillPoolOption(req, options.spawnMethod, "!~PASSENGER_SPAWN_METHOD");
	fillPoolOption(req, options.startCommand, "!~PASSENGER_START_COMMAND");
	fillPoolOptionSecToMsec(req, options.startTimeout, "!~PASSENGER_START_TIMEOUT");
	fillPoolOption(req, options.maxPreloaderIdleTime, "!~PASSENGER_MAX_PRELOADER_IDLE_TIME");
	fillPoolOption(req, options.maxRequestQueueSize, "!~PASSENGER_MAX_REQUEST_QUEUE_SIZE");
	fillPoolOption(req, options.abortWebsocketsOnProcessShutdown, "!~PASSENGER_ABORT_WEBSOCKETS_ON_PROCESS_SHUTDOWN");
	fillPoolOption(req, options.forceMaxConcurrentRequestsPerProcess, "!~PASSENGER_FORCE_MAX_CONCURRENT_REQUESTS_PER_PROCESS");
	fillPoolOption(req, options.restartDir, "!~PASSENGER_RESTART_DIR");
	fillPoolOption(req, options.startupFile, "!~PASSENGER_STARTUP_FILE");
	fillPoolOption(req, options.loadShellEnvvars, "!~PASSENGER_LOAD_SHELL_ENVVARS");
	fillPoolOption(req, options.fileDescriptorUlimit, "!~PASSENGER_APP_FILE_DESCRIPTOR_ULIMIT");
	fillPoolOption(req, options.raiseInternalError, "!~PASSENGER_RAISE_INTERNAL_ERROR");
	fillPoolOption(req, options.lveMinUid, "!~PASSENGER_LVE_MIN_UID");
	/******************/

	boost::shared_ptr<Options> optionsCopy = boost::make_shared<Options>(options);
	optionsCopy->persist(options);
	optionsCopy->clearPerRequestFields();
	optionsCopy->detachFromUnionStationTransaction();
	poolOptionsCache.insert(options.getAppGroupName(), optionsCopy);
}
コード例 #5
0
ファイル: SendRequest.cpp プロジェクト: 1234-/passenger
unsigned int
Controller::determineHeaderSizeForSessionProtocol(Request *req,
	SessionProtocolWorkingState &state, string delta_monotonic)
{
	unsigned int dataSize = sizeof(boost::uint32_t);

	state.path        = req->getPathWithoutQueryString();
	state.hasBaseURI  = req->options.baseURI != P_STATIC_STRING("/")
		&& startsWith(state.path, req->options.baseURI);
	if (state.hasBaseURI) {
		state.path = state.path.substr(req->options.baseURI.size());
		if (state.path.empty()) {
			state.path = P_STATIC_STRING("/");
		}
	}
	state.queryString = req->getQueryString();
	state.methodStr   = StaticString(http_method_str(req->method));
	state.remoteAddr  = req->secureHeaders.lookup(REMOTE_ADDR);
	state.remotePort  = req->secureHeaders.lookup(REMOTE_PORT);
	state.remoteUser  = req->secureHeaders.lookup(REMOTE_USER);
	state.contentType   = req->headers.lookup(HTTP_CONTENT_TYPE);
	if (req->hasBody()) {
		state.contentLength = req->headers.lookup(HTTP_CONTENT_LENGTH);
	} else {
		state.contentLength = NULL;
	}
	if (req->envvars != NULL) {
		size_t len = modp_b64_decode_len(req->envvars->size);
		state.environmentVariablesData = (char *) malloc(len);
		if (state.environmentVariablesData == NULL) {
			throw RuntimeException("Unable to allocate memory for base64 "
				"decoding of environment variables");
		}
		len = modp_b64_decode(state.environmentVariablesData,
			req->envvars->start->data,
			req->envvars->size);
		if (len == (size_t) -1) {
			throw RuntimeException("Unable to base64 decode environment variables");
		}
		state.environmentVariablesSize = len;
	}

	dataSize += sizeof("REQUEST_URI");
	dataSize += req->path.size + 1;

	dataSize += sizeof("PATH_INFO");
	dataSize += state.path.size() + 1;

	dataSize += sizeof("SCRIPT_NAME");
	if (state.hasBaseURI) {
		dataSize += req->options.baseURI.size();
	} else {
		dataSize += sizeof("");
	}

	dataSize += sizeof("QUERY_STRING");
	dataSize += state.queryString.size() + 1;

	dataSize += sizeof("REQUEST_METHOD");
	dataSize += state.methodStr.size() + 1;

	if (req->host != NULL && req->host->size > 0) {
		const LString *host = psg_lstr_make_contiguous(req->host, req->pool);
		const char *sep = (const char *) memchr(host->start->data, ':', host->size);
		if (sep != NULL) {
			state.serverName = StaticString(host->start->data, sep - host->start->data);
			state.serverPort = StaticString(sep + 1,
				host->start->data + host->size - sep - 1);
		} else {
			state.serverName = StaticString(host->start->data, host->size);
			if (req->https) {
				state.serverPort = P_STATIC_STRING("443");
			} else {
				state.serverPort = P_STATIC_STRING("80");
			}
		}
	} else {
		state.serverName = defaultServerName;
		state.serverPort = defaultServerPort;
	}

	dataSize += sizeof("SERVER_NAME");
	dataSize += state.serverName.size() + 1;

	dataSize += sizeof("SERVER_PORT");
	dataSize += state.serverPort.size() + 1;

	dataSize += sizeof("SERVER_SOFTWARE");
	dataSize += serverSoftware.size() + 1;

	dataSize += sizeof("SERVER_PROTOCOL");
	dataSize += sizeof("HTTP/1.1");

	dataSize += sizeof("REMOTE_ADDR");
	if (state.remoteAddr != NULL) {
		dataSize += state.remoteAddr->size + 1;
	} else {
		dataSize += sizeof("127.0.0.1");
	}

	dataSize += sizeof("REMOTE_PORT");
	if (state.remotePort != NULL) {
		dataSize += state.remotePort->size + 1;
	} else {
		dataSize += sizeof("0");
	}

	if (state.remoteUser != NULL) {
		dataSize += sizeof("REMOTE_USER");
		dataSize += state.remoteUser->size + 1;
	}

	if (state.contentType != NULL) {
		dataSize += sizeof("CONTENT_TYPE");
		dataSize += state.contentType->size + 1;
	}

	if (state.contentLength != NULL) {
		dataSize += sizeof("CONTENT_LENGTH");
		dataSize += state.contentLength->size + 1;
	}

	dataSize += sizeof("PASSENGER_CONNECT_PASSWORD");
	dataSize += ApplicationPool2::ApiKey::SIZE + 1;

	if (req->https) {
		dataSize += sizeof("HTTPS");
		dataSize += sizeof("on");
	}

	if (req->options.analytics) {
		dataSize += sizeof("PASSENGER_TXN_ID");
		dataSize += req->options.transaction->getTxnId().size() + 1;

		dataSize += sizeof("PASSENGER_DELTA_MONOTONIC");
		dataSize += delta_monotonic.size() + 1;
	}

	if (req->upgraded()) {
		dataSize += sizeof("HTTP_CONNECTION");
		dataSize += sizeof("upgrade");
	}

	ServerKit::HeaderTable::Iterator it(req->headers);
	while (*it != NULL) {
		dataSize += sizeof("HTTP_") - 1 + it->header->key.size + 1;
		dataSize += it->header->val.size + 1;
		it.next();
	}

	if (state.environmentVariablesData != NULL) {
		dataSize += state.environmentVariablesSize;
	}

	return dataSize + 1;
}