Beispiel #1
0
nsresult
FetchDriver::BasicFetch()
{
  nsAutoCString url;
  mRequest->GetURL(url);
  nsCOMPtr<nsIURI> uri;
  nsresult rv = NS_NewURI(getter_AddRefs(uri),
                 url,
                 nullptr,
                 nullptr);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    FailWithNetworkError();
    return rv;
  }

  nsAutoCString scheme;
  rv = uri->GetScheme(scheme);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    FailWithNetworkError();
    return rv;
  }

  if (scheme.LowerCaseEqualsLiteral("about")) {
    if (url.EqualsLiteral("about:blank")) {
      nsRefPtr<InternalResponse> response =
        new InternalResponse(200, NS_LITERAL_CSTRING("OK"));
      ErrorResult result;
      response->Headers()->Append(NS_LITERAL_CSTRING("content-type"),
                                  NS_LITERAL_CSTRING("text/html;charset=utf-8"),
                                  result);
      MOZ_ASSERT(!result.Failed());
      nsCOMPtr<nsIInputStream> body;
      rv = NS_NewCStringInputStream(getter_AddRefs(body), EmptyCString());
      if (NS_WARN_IF(NS_FAILED(rv))) {
        FailWithNetworkError();
        return rv;
      }

      response->SetBody(body);
      BeginResponse(response);
      return SucceedWithResponse();
    }
    return FailWithNetworkError();
  }

  if (scheme.LowerCaseEqualsLiteral("blob")) {
    nsRefPtr<BlobImpl> blobImpl;
    rv = NS_GetBlobForBlobURI(uri, getter_AddRefs(blobImpl));
    BlobImpl* blob = static_cast<BlobImpl*>(blobImpl.get());
    if (NS_WARN_IF(NS_FAILED(rv))) {
      FailWithNetworkError();
      return rv;
    }

    nsRefPtr<InternalResponse> response = new InternalResponse(200, NS_LITERAL_CSTRING("OK"));
    ErrorResult result;
    uint64_t size = blob->GetSize(result);
    if (NS_WARN_IF(result.Failed())) {
      FailWithNetworkError();
      return result.StealNSResult();
    }

    nsAutoString sizeStr;
    sizeStr.AppendInt(size);
    response->Headers()->Append(NS_LITERAL_CSTRING("Content-Length"), NS_ConvertUTF16toUTF8(sizeStr), result);
    if (NS_WARN_IF(result.Failed())) {
      FailWithNetworkError();
      return result.StealNSResult();
    }

    nsAutoString type;
    blob->GetType(type);
    response->Headers()->Append(NS_LITERAL_CSTRING("Content-Type"), NS_ConvertUTF16toUTF8(type), result);
    if (NS_WARN_IF(result.Failed())) {
      FailWithNetworkError();
      return result.StealNSResult();
    }

    nsCOMPtr<nsIInputStream> stream;
    blob->GetInternalStream(getter_AddRefs(stream), result);
    if (NS_WARN_IF(result.Failed())) {
      FailWithNetworkError();
      return result.StealNSResult();
    }

    response->SetBody(stream);
    BeginResponse(response);
    return SucceedWithResponse();
  }

  if (scheme.LowerCaseEqualsLiteral("data")) {
    nsAutoCString method;
    mRequest->GetMethod(method);
    if (method.LowerCaseEqualsASCII("get")) {
      nsresult rv;
      nsCOMPtr<nsIProtocolHandler> dataHandler =
        do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "data", &rv);

      if (NS_WARN_IF(NS_FAILED(rv))) {
        return FailWithNetworkError();
      }

      nsCOMPtr<nsIChannel> channel;
      rv = dataHandler->NewChannel(uri, getter_AddRefs(channel));
      if (NS_WARN_IF(NS_FAILED(rv))) {
        return FailWithNetworkError();
      }

      nsCOMPtr<nsIInputStream> stream;
      rv = channel->Open(getter_AddRefs(stream));
      if (NS_WARN_IF(NS_FAILED(rv))) {
        return FailWithNetworkError();
      }

      // nsDataChannel will parse the data URI when it is Open()ed and set the
      // correct content type and charset.
      nsAutoCString contentType;
      if (NS_SUCCEEDED(channel->GetContentType(contentType))) {
        nsAutoCString charset;
        if (NS_SUCCEEDED(channel->GetContentCharset(charset)) && !charset.IsEmpty()) {
          contentType.AppendLiteral(";charset=");
          contentType.Append(charset);
        }
      } else {
        NS_WARNING("Could not get content type from data channel");
      }

      nsRefPtr<InternalResponse> response = new InternalResponse(200, NS_LITERAL_CSTRING("OK"));
      ErrorResult result;
      response->Headers()->Append(NS_LITERAL_CSTRING("Content-Type"), contentType, result);
      if (NS_WARN_IF(result.Failed())) {
        FailWithNetworkError();
        return result.StealNSResult();
      }

      response->SetBody(stream);
      BeginResponse(response);
      return SucceedWithResponse();
    }

    return FailWithNetworkError();
  }

  if (scheme.LowerCaseEqualsLiteral("http") ||
      scheme.LowerCaseEqualsLiteral("https") ||
      scheme.LowerCaseEqualsLiteral("app")) {
    return HttpFetch();
  }

  return FailWithNetworkError();
}
Beispiel #2
0
nsresult
FetchDriver::BasicFetch()
{
  nsAutoCString url;
  mRequest->GetURL(url);
  nsCOMPtr<nsIURI> uri;
  nsresult rv = NS_NewURI(getter_AddRefs(uri),
                 url,
                 nullptr,
                 nullptr);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    FailWithNetworkError();
    return rv;
  }

  nsAutoCString scheme;
  rv = uri->GetScheme(scheme);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    FailWithNetworkError();
    return rv;
  }

  if (scheme.LowerCaseEqualsLiteral("about")) {
    if (url.EqualsLiteral("about:blank")) {
      nsRefPtr<InternalResponse> response =
        new InternalResponse(200, NS_LITERAL_CSTRING("OK"));
      ErrorResult result;
      response->Headers()->Append(NS_LITERAL_CSTRING("content-type"),
                                  NS_LITERAL_CSTRING("text/html;charset=utf-8"),
                                  result);
      MOZ_ASSERT(!result.Failed());
      nsCOMPtr<nsIInputStream> body;
      rv = NS_NewCStringInputStream(getter_AddRefs(body), EmptyCString());
      if (NS_WARN_IF(NS_FAILED(rv))) {
        FailWithNetworkError();
        return rv;
      }

      response->SetBody(body);
      BeginResponse(response);
      return SucceedWithResponse();
    }
    return FailWithNetworkError();
  }

  if (scheme.LowerCaseEqualsLiteral("blob")) {
    nsRefPtr<BlobImpl> blobImpl;
    rv = NS_GetBlobForBlobURI(uri, getter_AddRefs(blobImpl));
    BlobImpl* blob = static_cast<BlobImpl*>(blobImpl.get());
    if (NS_WARN_IF(NS_FAILED(rv))) {
      FailWithNetworkError();
      return rv;
    }

    nsRefPtr<InternalResponse> response = new InternalResponse(200, NS_LITERAL_CSTRING("OK"));
    ErrorResult result;
    uint64_t size = blob->GetSize(result);
    if (NS_WARN_IF(result.Failed())) {
      FailWithNetworkError();
      return result.StealNSResult();
    }

    nsAutoString sizeStr;
    sizeStr.AppendInt(size);
    response->Headers()->Append(NS_LITERAL_CSTRING("Content-Length"), NS_ConvertUTF16toUTF8(sizeStr), result);
    if (NS_WARN_IF(result.Failed())) {
      FailWithNetworkError();
      return result.StealNSResult();
    }

    nsAutoString type;
    blob->GetType(type);
    response->Headers()->Append(NS_LITERAL_CSTRING("Content-Type"), NS_ConvertUTF16toUTF8(type), result);
    if (NS_WARN_IF(result.Failed())) {
      FailWithNetworkError();
      return result.StealNSResult();
    }

    nsCOMPtr<nsIInputStream> stream;
    blob->GetInternalStream(getter_AddRefs(stream), result);
    if (NS_WARN_IF(result.Failed())) {
      FailWithNetworkError();
      return result.StealNSResult();
    }

    response->SetBody(stream);
    BeginResponse(response);
    return SucceedWithResponse();
  }

  if (scheme.LowerCaseEqualsLiteral("data")) {
    nsAutoCString method;
    mRequest->GetMethod(method);
    if (method.LowerCaseEqualsASCII("get")) {
      // Use nsDataHandler directly so that we can extract the content type.
      // XXX(nsm): Is there a way to acquire the charset without such tight
      // coupling with the DataHandler? nsIProtocolHandler does not provide
      // anything similar.
      nsAutoCString contentType, contentCharset, dataBuffer, hashRef;
      bool isBase64;
      rv = nsDataHandler::ParseURI(url,
                                   contentType,
                                   contentCharset,
                                   isBase64,
                                   dataBuffer,
                                   hashRef);
      if (NS_SUCCEEDED(rv)) {
        ErrorResult result;
        nsRefPtr<InternalResponse> response = new InternalResponse(200, NS_LITERAL_CSTRING("OK"));
        if (!contentCharset.IsEmpty()) {
          contentType.Append(";charset=");
          contentType.Append(contentCharset);
        }

        response->Headers()->Append(NS_LITERAL_CSTRING("Content-Type"), contentType, result);
        if (!result.Failed()) {
          nsCOMPtr<nsIInputStream> stream;
          rv = NS_NewCStringInputStream(getter_AddRefs(stream), dataBuffer);
          if (NS_SUCCEEDED(rv)) {
            response->SetBody(stream);
            BeginResponse(response);
            return SucceedWithResponse();
          }
        }
      }
    }

    return FailWithNetworkError();
  }

  if (scheme.LowerCaseEqualsLiteral("http") ||
      scheme.LowerCaseEqualsLiteral("https") ||
      scheme.LowerCaseEqualsLiteral("app")) {
    return HttpFetch();
  }

  return FailWithNetworkError();
}