Ejemplo n.º 1
0
nsresult
nsBaseChannel::PushStreamConverter(const char *fromType,
                                   const char *toType,
                                   PRBool invalidatesContentLength,
                                   nsIStreamListener **result)
{
    NS_ASSERTION(mListener, "no listener");

    nsresult rv;
    nsCOMPtr<nsIStreamConverterService> scs =
        do_GetService(NS_STREAMCONVERTERSERVICE_CONTRACTID, &rv);
    if (NS_FAILED(rv))
        return rv;

    nsCOMPtr<nsIStreamListener> converter;
    rv = scs->AsyncConvertData(fromType, toType, mListener, mListenerContext,
                               getter_AddRefs(converter));
    if (NS_SUCCEEDED(rv)) {
        mListener = converter;
        if (invalidatesContentLength)
            SetContentLength64(-1);
        if (result) {
            *result = nsnull;
            converter.swap(*result);
        }
    }
    return rv;
}
Ejemplo n.º 2
0
nsresult
nsInputStreamChannel::OpenContentStream(bool async, nsIInputStream **result,
                                        nsIChannel** channel)
{
  NS_ENSURE_TRUE(mContentStream, NS_ERROR_NOT_INITIALIZED);

  // If content length is unknown, then we must guess.  In this case, we assume
  // the stream can tell us.  If the stream is a pipe, then this will not work.

  PRInt64 len = ContentLength64();
  if (len < 0) {
    PRUint32 avail;
    nsresult rv = mContentStream->Available(&avail);
    if (rv == NS_BASE_STREAM_CLOSED) {
      // This just means there's nothing in the stream
      avail = 0;
    } else if (NS_FAILED(rv)) {
      return rv;
    }
    SetContentLength64(avail);
  }

  EnableSynthesizedProgressEvents(true);
  
  NS_ADDREF(*result = mContentStream);
  return NS_OK;
}
Ejemplo n.º 3
0
nsresult
nsDataChannel::OpenContentStream(PRBool async, nsIInputStream **result,
                                 nsIChannel** channel)
{
    NS_ENSURE_TRUE(URI(), NS_ERROR_NOT_INITIALIZED);

    nsresult rv;

    nsCAutoString spec;
    rv = URI()->GetAsciiSpec(spec);
    if (NS_FAILED(rv)) return rv;

    nsCString contentType, contentCharset, dataBuffer;
    PRBool lBase64;
    rv = nsDataHandler::ParseURI(spec, contentType, contentCharset,
                                 lBase64, dataBuffer);

    NS_UnescapeURL(dataBuffer);

    if (lBase64) {
        // Don't allow spaces in base64-encoded content. This is only
        // relevant for escaped spaces; other spaces are stripped in
        // NewURI.
        dataBuffer.StripWhitespace();
    }
    
    nsCOMPtr<nsIInputStream> bufInStream;
    nsCOMPtr<nsIOutputStream> bufOutStream;
    
    // create an unbounded pipe.
    rv = NS_NewPipe(getter_AddRefs(bufInStream),
                    getter_AddRefs(bufOutStream),
                    nsIOService::gDefaultSegmentSize,
                    PR_UINT32_MAX,
                    async, PR_TRUE);
    if (NS_FAILED(rv))
        return rv;

    PRUint32 contentLen;
    if (lBase64) {
        const PRUint32 dataLen = dataBuffer.Length();
        PRInt32 resultLen = 0;
        if (dataLen >= 1 && dataBuffer[dataLen-1] == '=') {
            if (dataLen >= 2 && dataBuffer[dataLen-2] == '=')
                resultLen = dataLen-2;
            else
                resultLen = dataLen-1;
        } else {
            resultLen = dataLen;
        }
        resultLen = ((resultLen * 3) / 4);

        // XXX PL_Base64Decode will return a null pointer for decoding
        // errors.  Since those are more likely than out-of-memory,
        // should we return NS_ERROR_MALFORMED_URI instead?
        char * decodedData = PL_Base64Decode(dataBuffer.get(), dataLen, nsnull);
        if (!decodedData) {
            return NS_ERROR_OUT_OF_MEMORY;
        }

        rv = bufOutStream->Write(decodedData, resultLen, &contentLen);

        PR_Free(decodedData);
    } else {
        rv = bufOutStream->Write(dataBuffer.get(), dataBuffer.Length(), &contentLen);
    }
    if (NS_FAILED(rv))
        return rv;

    SetContentType(contentType);
    SetContentCharset(contentCharset);
    SetContentLength64(contentLen);

    NS_ADDREF(*result = bufInStream);

    return NS_OK;
}
Ejemplo n.º 4
0
NS_IMETHODIMP
nsBaseChannel::SetContentLength(PRInt32 aContentLength)
{
    SetContentLength64(aContentLength);
    return NS_OK;
}
Ejemplo n.º 5
0
nsresult
nsFileChannel::OpenContentStream(bool async, nsIInputStream **result,
                                 nsIChannel** channel)
{
  // NOTE: the resulting file is a clone, so it is safe to pass it to the
  //       file input stream which will be read on a background thread.
  nsCOMPtr<nsIFile> file;
  nsresult rv = GetFile(getter_AddRefs(file));
  if (NS_FAILED(rv))
    return rv;

  nsCOMPtr<nsIFileProtocolHandler> fileHandler;
  rv = NS_GetFileProtocolHandler(getter_AddRefs(fileHandler));
  if (NS_FAILED(rv))
    return rv;
    
  nsCOMPtr<nsIURI> newURI;
  rv = fileHandler->ReadURLFile(file, getter_AddRefs(newURI));
  if (NS_SUCCEEDED(rv)) {
    nsCOMPtr<nsIChannel> newChannel;
    rv = NS_NewChannel(getter_AddRefs(newChannel), newURI);
    if (NS_FAILED(rv))
      return rv;

    *result = nullptr;
    newChannel.forget(channel);
    return NS_OK;
  }

  nsCOMPtr<nsIInputStream> stream;

  if (mUploadStream) {
    // Pass back a nsFileUploadContentStream instance that knows how to perform
    // the file copy when "read" (the resulting stream in this case does not
    // actually return any data).

    nsCOMPtr<nsIOutputStream> fileStream;
    rv = NS_NewLocalFileOutputStream(getter_AddRefs(fileStream), file,
                                     PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
                                     PR_IRUSR | PR_IWUSR);
    if (NS_FAILED(rv))
      return rv;

    nsFileUploadContentStream *uploadStream =
        new nsFileUploadContentStream(async, fileStream, mUploadStream,
                                      mUploadLength, this);
    if (!uploadStream || !uploadStream->IsInitialized()) {
      delete uploadStream;
      return NS_ERROR_OUT_OF_MEMORY;
    }
    stream = uploadStream;

    SetContentLength64(0);

    // Since there isn't any content to speak of we just set the content-type
    // to something other than "unknown" to avoid triggering the content-type
    // sniffer code in nsBaseChannel.
    // However, don't override explicitly set types.
    if (!HasContentTypeHint())
      SetContentType(NS_LITERAL_CSTRING(APPLICATION_OCTET_STREAM));
  } else {
    nsCAutoString contentType;
    rv = MakeFileInputStream(file, stream, contentType);
    if (NS_FAILED(rv))
      return rv;

    EnableSynthesizedProgressEvents(true);

    // fixup content length and type
    if (ContentLength64() < 0) {
      PRInt64 size;
      rv = file->GetFileSize(&size);
      if (NS_FAILED(rv))
        return rv;
      SetContentLength64(size);
    }
    if (!contentType.IsEmpty())
      SetContentType(contentType);
  }

  *result = nullptr;
  stream.swap(*result);
  return NS_OK;
}