CUPnPTimer::~CUPnPTimer() { if(PendingRequest()) { Cancel(); } }
void CUPnPTimer::DoCancel() { if(PendingRequest()) { Cancel(); } }
bool MediaKeySystemAccessManager::AwaitInstall(DetailedPromise* aPromise, const nsAString& aKeySystem, const Sequence<MediaKeySystemConfiguration>& aConfigs) { EME_LOG("MediaKeySystemAccessManager::AwaitInstall %s", NS_ConvertUTF16toUTF8(aKeySystem).get()); if (!EnsureObserversAdded()) { NS_WARNING("Failed to add pref observer"); return false; } nsCOMPtr<nsITimer> timer(do_CreateInstance("@mozilla.org/timer;1")); if (!timer || NS_FAILED(timer->Init(this, 60 * 1000, nsITimer::TYPE_ONE_SHOT))) { NS_WARNING("Failed to create timer to await CDM install."); return false; } mRequests.AppendElement(PendingRequest(aPromise, aKeySystem, aConfigs, timer)); return true; }
nsresult HttpServer::Connection::ConsumeLine(const char* aBuffer, size_t aLength) { MOZ_ASSERT(mState == eRequestLine || mState == eHeaders); if (MOZ_LOG_TEST(gHttpServerLog, mozilla::LogLevel::Verbose)) { nsCString line(aBuffer, aLength); LOG_V("HttpServer::Connection::ConsumeLine(%p) - \"%s\"", this, line.get()); } if (mState == eRequestLine) { LOG_V("HttpServer::Connection::ConsumeLine(%p) - Parsing request line", this); NS_ENSURE_FALSE(mCloseAfterRequest, NS_ERROR_UNEXPECTED); if (aLength == 0) { // Ignore empty lines before the request line return NS_OK; } MOZ_ASSERT(!mPendingReq); // Process request line nsCWhitespaceTokenizer tokens(Substring(aBuffer, aLength)); NS_ENSURE_TRUE(tokens.hasMoreTokens(), NS_ERROR_UNEXPECTED); nsDependentCSubstring method = tokens.nextToken(); NS_ENSURE_TRUE(NS_IsValidHTTPToken(method), NS_ERROR_UNEXPECTED); NS_ENSURE_TRUE(tokens.hasMoreTokens(), NS_ERROR_UNEXPECTED); nsDependentCSubstring url = tokens.nextToken(); // Seems like it's also allowed to pass full urls with scheme+host+port. // May need to support that. NS_ENSURE_TRUE(url.First() == '/', NS_ERROR_UNEXPECTED); mPendingReq = new InternalRequest(url, /* aURLFragment */ EmptyCString()); mPendingReq->SetMethod(method); NS_ENSURE_TRUE(tokens.hasMoreTokens(), NS_ERROR_UNEXPECTED); nsDependentCSubstring version = tokens.nextToken(); NS_ENSURE_TRUE(StringBeginsWith(version, NS_LITERAL_CSTRING("HTTP/1.")), NS_ERROR_UNEXPECTED); nsresult rv; // This integer parsing is likely not strict enough. nsCString reqVersion; reqVersion = Substring(version, MOZ_ARRAY_LENGTH("HTTP/1.") - 1); mPendingReqVersion = reqVersion.ToInteger(&rv); NS_ENSURE_SUCCESS(rv, NS_ERROR_UNEXPECTED); NS_ENSURE_FALSE(tokens.hasMoreTokens(), NS_ERROR_UNEXPECTED); LOG_V("HttpServer::Connection::ConsumeLine(%p) - Parsed request line", this); mState = eHeaders; return NS_OK; } if (aLength == 0) { LOG_V("HttpServer::Connection::ConsumeLine(%p) - Found end of headers", this); MaybeAddPendingHeader(); ErrorResult res; mPendingReq->Headers()->SetGuard(HeadersGuardEnum::Immutable, res); // Check for WebSocket if (IsWebSocketRequest(mPendingReq, mPendingReqVersion)) { LOG_V("HttpServer::Connection::ConsumeLine(%p) - Fire OnWebSocket", this); mState = ePause; mPendingWebSocketRequest = mPendingReq.forget(); mPendingReqVersion = 0; RefPtr<HttpServerListener> listener = mServer->mListener; RefPtr<InternalRequest> request = mPendingWebSocketRequest; nsCOMPtr<nsIRunnable> event = NS_NewRunnableFunction( "dom::HttpServer::Connection::ConsumeLine", [listener, request]() { listener->OnWebSocket(request); }); NS_DispatchToCurrentThread(event); return NS_OK; } nsAutoCString header; mPendingReq->Headers()->GetFirst(NS_LITERAL_CSTRING("connection"), header, res); MOZ_ASSERT(!res.Failed()); // 1.0 defaults to closing connections. // 1.1 and higher defaults to keep-alive. if (ContainsToken(header, NS_LITERAL_CSTRING("close")) || (mPendingReqVersion == 0 && !ContainsToken(header, NS_LITERAL_CSTRING("keep-alive")))) { mCloseAfterRequest = true; } mPendingReq->Headers()->GetFirst(NS_LITERAL_CSTRING("content-length"), header, res); MOZ_ASSERT(!res.Failed()); LOG_V("HttpServer::Connection::ConsumeLine(%p) - content-length is \"%s\"", this, header.get()); if (!header.IsEmpty()) { nsresult rv; mRemainingBodySize = header.ToInteger(&rv); NS_ENSURE_SUCCESS(rv, rv); } else { mRemainingBodySize = 0; } if (mRemainingBodySize) { LOG_V("HttpServer::Connection::ConsumeLine(%p) - Starting consume body", this); mState = eBody; // We use an unlimited buffer size here to ensure // that we get to the next request even if the webpage hangs on // to the request indefinitely without consuming the body. nsCOMPtr<nsIInputStream> input; nsCOMPtr<nsIOutputStream> output; nsresult rv = NS_NewPipe(getter_AddRefs(input), getter_AddRefs(output), 0, // Segment size UINT32_MAX, // Unlimited buffer size false, // not nonBlockingInput true); // nonBlockingOutput NS_ENSURE_SUCCESS(rv, rv); mCurrentRequestBody = do_QueryInterface(output); mPendingReq->SetBody(input); } else { LOG_V("HttpServer::Connection::ConsumeLine(%p) - No body", this); mState = eRequestLine; } mPendingRequests.AppendElement(PendingRequest(mPendingReq, nullptr)); LOG_V("HttpServer::Connection::ConsumeLine(%p) - Fire OnRequest", this); RefPtr<HttpServerListener> listener = mServer->mListener; RefPtr<InternalRequest> request = mPendingReq.forget(); nsCOMPtr<nsIRunnable> event = NS_NewRunnableFunction( "dom::HttpServer::Connection::ConsumeLine", [listener, request]() { listener->OnRequest(request); }); NS_DispatchToCurrentThread(event); mPendingReqVersion = 0; return NS_OK; } // Parse header line if (aBuffer[0] == ' ' || aBuffer[0] == '\t') { LOG_V("HttpServer::Connection::ConsumeLine(%p) - Add to header %s", this, mPendingHeaderName.get()); NS_ENSURE_FALSE(mPendingHeaderName.IsEmpty(), NS_ERROR_UNEXPECTED); // We might need to do whitespace trimming/compression here. mPendingHeaderValue.Append(aBuffer, aLength); return NS_OK; } MaybeAddPendingHeader(); const char* colon = static_cast<const char*>(memchr(aBuffer, ':', aLength)); NS_ENSURE_TRUE(colon, NS_ERROR_UNEXPECTED); ToLowerCase(Substring(aBuffer, colon - aBuffer), mPendingHeaderName); mPendingHeaderValue.Assign(colon + 1, aLength - (colon - aBuffer) - 1); NS_ENSURE_TRUE(NS_IsValidHTTPToken(mPendingHeaderName), NS_ERROR_UNEXPECTED); LOG_V("HttpServer::Connection::ConsumeLine(%p) - Parsed header %s", this, mPendingHeaderName.get()); return NS_OK; }