Esempio n. 1
0
        ReaderWriterAVFoundation()
        {
            supportsExtension("mov","Quicktime movie format");
            supportsExtension("mpg","Mpeg movie format");
            supportsExtension("mp4","Mpeg movie format");
            supportsExtension("m4v","Mpeg movie format");
            supportsExtension("mpeg","Mpeg movie format");
            supportsExtension("avfoundation","AVFoundation movie format");

            supportsProtocol("http", "streaming media per http");
            supportsProtocol("rtsp", "streaming media per rtsp");     
        }
Esempio n. 2
0
void MediaRendererDevice::prepareForConnection(const ProtocolInfo& protocolInfo, ConnectionManager::ConnectionInfo& info)
{
    if (info.direction != ConnectionManager::Direction::Input)
    {
        throw ConnectionManager::IncompatibleDirectionsException();
    }
    
    if (!supportsProtocol(protocolInfo))
    {
        throw ConnectionManager::IncompatibleProtocolException();
    }
    
    // currently we only support one instance
    info.connectionId = 0;
    info.avTransportId = 0;
    info.renderingControlServiceId = 0;
}
Esempio n. 3
0
/** serializes the HTTP response status line plus headers into a byte-stream.
 *
 * This method is invoked right before the response content is written or the
 * response is flushed at all.
 *
 * It first sets the status code (if not done yet), invoked post_process callback,
 * performs connection-level response header modifications and then
 * builds the response chunk for status line and headers.
 *
 * Post-modification done <b>after</b> the post_process hook has been invoked:
 * <ol>
 *   <li>set status code to 200 (Ok) if not set yet.</li>
 *   <li>set Content-Type header to a default if not set yet.</li>
 *   <li>set Connection header to keep-alive or close (computed value)</li>
 *   <li>append Transfer-Encoding chunked if no Content-Length header is set.</li>
 *   <li>optionally enable TCP_CORK if this is no keep-alive connection and the administrator allows it.</li>
 * </ol>
 *
 * \note this does not serialize the message body.
 */
Source* HttpRequest::serialize()
{
	Buffer buffers;

	if (expectingContinue)
		status = HttpStatus::ExpectationFailed;
	else if (status == static_cast<HttpStatus>(0))
		status = HttpStatus::Ok;

	if (!responseHeaders.contains("Content-Type")) {
		responseHeaders.push_back("Content-Type", "text/plain"); //!< \todo pass "default" content-type instead!
	}

	if (connection.worker().server().advertise() && !connection.worker().server().tag().empty()) {
		if (!responseHeaders.contains("Server")) {
			responseHeaders.push_back("Server", connection.worker().server().tag());
		} else {
			responseHeaders.push_back("Via", connection.worker().server().tag());
		}
	}

	// post-response hook
	connection.worker().server().onPostProcess(this);

	// setup (connection-level) response transfer
	if (supportsProtocol(1, 1)
		&& !responseHeaders.contains("Content-Length")
		&& !responseHeaders.contains("Transfer-Encoding")
		&& !isResponseContentForbidden())
	{
		responseHeaders.push_back("Transfer-Encoding", "chunked");
		outputFilters.push_back(std::make_shared<ChunkedEncoder>());
	}

	bool keepalive = connection.shouldKeepAlive();
	if (!connection.worker().server().maxKeepAlive())
		keepalive = false;

	// remaining request count, that is allowed on a persistent connection
	std::size_t rlim = connection.worker().server().maxKeepAliveRequests();
	if (rlim) {
		rlim = connection.requestCount_ <= rlim
			? rlim - connection.requestCount_ + 1
			: 0;

		if (rlim == 0)
			// disable keep-alive, if max request count has been reached
			keepalive = false;
	}

	// only set Connection-response-header if found as request-header, too
	if (!requestHeader("Connection").empty() || keepalive != connection.shouldKeepAlive()) {
		if (keepalive) {
			responseHeaders.overwrite("Connection", "keep-alive");

			if (rlim) {
				// sent keep-alive timeout and remaining request count
				char buf[80];
				snprintf(buf, sizeof(buf), "timeout=%ld, max=%ld",
					static_cast<time_t>(connection.worker().server().maxKeepAlive().value()), rlim);
				responseHeaders.overwrite("Keep-Alive", buf);
			} else {
				// sent keep-alive timeout only (infinite request count)
				char buf[80];
				snprintf(buf, sizeof(buf), "timeout=%ld",
					static_cast<time_t>(connection.worker().server().maxKeepAlive().value()));
				responseHeaders.overwrite("Keep-Alive", buf);
			}
		} else
			responseHeaders.overwrite("Connection", "close");
	}

	connection.setShouldKeepAlive(keepalive);

	if (!connection.worker().server().tcpCork())
		connection.socket()->setTcpCork(true);

	if (supportsProtocol(1, 1))
		buffers.push_back("HTTP/1.1 ");
	else if (supportsProtocol(1, 0))
		buffers.push_back("HTTP/1.0 ");
	else
		buffers.push_back("HTTP/0.9 ");

	buffers.push_back(statusCodes_[static_cast<int>(status)]);
	buffers.push_back(' ');
	buffers.push_back(statusStr(status));
	buffers.push_back("\r\n");

	for (auto& i: responseHeaders) {
		buffers.push_back(i.name.data(), i.name.size());
		buffers.push_back(": ");
		buffers.push_back(i.value.data(), i.value.size());
		buffers.push_back("\r\n");
	};

	buffers.push_back("\r\n");

	return new BufferSource(std::move(buffers));
}