Esempio n. 1
0
CUPnPTimer::~CUPnPTimer()
{
    if(PendingRequest())
    {
        Cancel();
    }
}
Esempio n. 2
0
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;
}
Esempio n. 4
0
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;
}