Back to index

enigmail  1.4.3
Public Member Functions | Static Public Member Functions | Public Attributes | Protected Member Functions | Protected Attributes
nsEnigMimeListener Class Reference

#include <nsEnigMimeListener.h>

Inheritance diagram for nsEnigMimeListener:
Inheritance graph
[legend]
Collaboration diagram for nsEnigMimeListener:
Collaboration graph
[legend]

List of all members.

Public Member Functions

NS_DECL_ISUPPORTS
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIENIGMIMELISTENER
NS_DECL_NSIINPUTSTREAM 
nsEnigMimeListener ()
virtual ~nsEnigMimeListener ()
NS_METHOD SendStream (const char *buf, PRUint32 count, nsIRequest *aRequest, nsISupports *aContext)
void init (in nsIStreamListener listener, in nsISupports ctxt, in unsigned long maxHeaderBytes, in boolean skipHeaders, in boolean skipBody, in boolean decodeContent)
 Initialized filtering stream listener.
void write (in string buf, in unsigned long count, in nsIRequest request, in nsISupports ctxt)

Static Public Member Functions

static NS_METHOD Create (nsISupports *aOuter, REFNSIID aIID, void **aResult)

Public Attributes

readonly attribute ACString headers
readonly attribute ACString linebreak
readonly attribute ACString contentType
readonly attribute ACString contentCharset
readonly attribute ACString contentBoundary
readonly attribute ACString contentProtocol
readonly attribute ACString contentMicalg
readonly attribute ACString contentEncoding
readonly attribute ACString contentDisposition
readonly attribute long contentLength
 The length of the data, if available.
attribute boolean subPartTreatment
 MIME filtering for multipart stuff: Display first part (should be non-multipart or multipart/alternative) Each message/rfc822 is treated as a plain text (.eml) attachment For display, each message/rfc822 item is emitted with its first "atomic" item, so that the subject headers etc.

Protected Member Functions

NS_METHOD StartRequest (nsIRequest *aRequest, nsISupports *aContext)
NS_METHOD Transmit (const char *buf, PRUint32 count, nsIRequest *aRequest, nsISupports *aContext)
EMBool HeaderSearch (const char *buf, PRUint32 count)
void ParseMimeHeaders (const char *mimeHeaders, PRUint32 count)
void ParseHeader (const char *header, PRUint32 count)

Protected Attributes

EMBool mInitialized
EMBool mRequestStarted
EMBool mSkipHeaders
EMBool mSkipBody
nsCString mContentType
nsCString mContentCharset
nsCString mContentBoundary
nsCString mContentProtocol
nsCString mContentMicalg
nsCString mContentEncoding
nsCString mContentDisposition
PRInt32 mContentLength
EMBool mDecodeContent
MimeDecoderDatamDecoderData
nsCString mLinebreak
nsCString mHeaders
nsCString mDataStr
PRUint32 mHeaderSearchCounter
EMBool mHeadersFinalCR
PRUint32 mHeadersLinebreak
PRUint32 mMaxHeaderBytes
PRUint32 mDataOffset
const char * mStreamBuf
PRUint32 mStreamOffset
PRUint32 mStreamLength
EMBool mSubPartTreatment
nsCOMPtr< nsIStreamListener > mListener
nsCOMPtr< nsISupports > mContext

Detailed Description

Definition at line 47 of file nsEnigMimeListener.h.


Constructor & Destructor Documentation

NS_DECL_ISUPPORTS NS_DECL_NSIREQUESTOBSERVER NS_DECL_NSISTREAMLISTENER NS_DECL_NSIENIGMIMELISTENER NS_DECL_NSIINPUTSTREAM nsEnigMimeListener::nsEnigMimeListener ( )

Definition at line 136 of file nsEnigMimeListener.cpp.

{
  nsresult rv;
#ifdef FORCE_PR_LOG
  nsCOMPtr<nsIThread> myThread;
  rv = ENIG_GET_THREAD(myThread);
  DEBUG_LOG(("nsEnigMimeListener:: >>>>>>>>> DTOR(%p): myThread=%p\n",
         this, myThread.get()));
#endif

  if (mDecoderData) {
    // Clear decoder buffer
    MimeDecoderDestroy(mDecoderData, PR_FALSE);
    mDecoderData = nsnull;
  }

  // Release owning refs
  mListener = nsnull;
  mContext = nsnull;
}

Here is the call graph for this function:


Member Function Documentation

static NS_METHOD nsEnigMimeListener::Create ( nsISupports *  aOuter,
REFNSIID  aIID,
void **  aResult 
) [static]
EMBool nsEnigMimeListener::HeaderSearch ( const char *  buf,
PRUint32  count 
) [protected]

Definition at line 521 of file nsEnigMimeListener.cpp.

{
  DEBUG_LOG(("nsEnigMimeListener::HeaderSearch: (%p) count=%d\n", this, count));

  mHeaderSearchCounter++;

  if (mMaxHeaderBytes <= 0) {
    // Not looking for MIME headers; start request immediately
    return PR_TRUE;
  }

  if (!count)
    return PR_FALSE;

  PRUint32 bytesAvailable = mMaxHeaderBytes - mDataStr.Length();
  NS_ASSERTION(bytesAvailable > 0, "bytesAvailable <= 0");

  EMBool lastSegment = (bytesAvailable <= count);

  PRUint32 scanLen = lastSegment ? bytesAvailable : count;

  EMBool headersFound = PR_FALSE;
  PRUint32 offset = 0;
  PRUint32 startOffset = 0;
  PRUint32 j = 0;
  char ch;
  if (mSubPartTreatment) {
    // FIXME:
    // this is a HACK necessary because Mozilla does not deliver
    // a subpart starting with its headers (so we get the
    // part on a higher level and sort out things manually!)
    // there is (so far) no way to get the headers of an
    // arbitrary message mime part
    DEBUG_LOG(("nsEnigMimeListener::HeaderSearch: subparts treatment\n"));
    ch='\n';
    while(j<scanLen-3) {
      if (((ch=='\n') || (ch=='\r')) &&
          (buf[j]=='-') &&
          (buf[j+1]=='-') &&
          (buf[j+2]!='\n') &&
          (buf[j+2]!='\r'))
      {
          startOffset = j;
          DEBUG_LOG(("nsEnigMimeListener::HeaderSearch: startOffset=%d\n",startOffset));
          break;
      }
      ch=buf[j];
      j++;
    }

    // set j=startOffset needed if startOffset == 0!
    j=startOffset;
/*
    // Solution for how to do it, if the content-type info
    // would be available
    nsCAutoString cType("Content-Type: multipart/signed; micalg=pgp-sha1; protocol=\"application/pgp-signature\"; boundary=\"J2SCkAp4GZ/dPZZf\"\n\n");
    mDataStr.Append(cType.get(), cType.Length());
    mHeaders = cType;
    if (mSkipHeaders)
      mDataStr = "";
    if (!mSkipBody)
      mDataStr.Append(buf, count);

    mHeadersLinebreak = 0;
    mLinebreak = "\n";
*/
    mSubPartTreatment = PR_FALSE;
    // return PR_TRUE;
  }

  while (j<scanLen) {
    ch = buf[j];

    if (mHeadersFinalCR) {
      // End-of-headers found
      mHeadersFinalCR = PR_FALSE;

      if (ch == '\n') {
        offset = j+1;
        mLinebreak = "\r\n";
        DEBUG_LOG(("nsEnigMimeListener::HeaderSearch: Found final CRLF"));

      } else {
        offset = j;
        mLinebreak = "\r";
        DEBUG_LOG(("nsEnigMimeListener::HeaderSearch: Found final CR"));
      }

      headersFound = PR_TRUE;
      break;

    }

    if (ch == '\n') {

      if (mHeadersLinebreak == 2) {
        // End-of-headers found
        headersFound = PR_TRUE;

        offset = j+1;
        mLinebreak = "\n";
        DEBUG_LOG(("nsEnigMimeListener::HeaderSearch: Found final LF"));
        break;
      }

      mHeadersLinebreak = 2;

    } else if (ch == '\r') {

      if (mHeadersLinebreak > 0) {
        // Final CR
        mHeadersFinalCR = PR_TRUE;
      } else {
        mHeadersLinebreak = 1;
      }

    } else {
      mHeadersLinebreak = 0;
    }

    j++;
  }

  DEBUG_LOG(("nsEnigMimeListener::HeaderSearch: offset=%d\n", offset));

  if (headersFound) {
    // Copy headers out of stream buffer
    if (offset > 0)
      mDataStr.Append(buf+startOffset, offset-startOffset);

    mHeaders = mDataStr;

    if (mSkipHeaders) {
      // Skip headers
      mDataStr = "";
    }

    if (!mSkipBody && (offset < count)) {
      // Copy remaining data into stream buffer
     mDataStr.Append(buf+offset, count-offset);
    }

  } else if (!lastSegment) {
    // Save headers data
    mDataStr.Append(buf, count);
  }

  return headersFound || lastSegment;
}
void nsIEnigMimeListener::init ( in nsIStreamListener  listener,
in nsISupports  ctxt,
in unsigned long  maxHeaderBytes,
in boolean  skipHeaders,
in boolean  skipBody,
in boolean  decodeContent 
) [inherited]

Initialized filtering stream listener.

void nsEnigMimeListener::ParseHeader ( const char *  header,
PRUint32  count 
) [protected]

Definition at line 754 of file nsEnigMimeListener.cpp.

{

  //DEBUG_LOG(("nsEnigMimeListener::ParseHeader: header='%s'\n", header));

  if (!header || (count <= 0) )
    return;

  // Create header string
  nsCAutoString headerStr(header, count);

  //DEBUG_LOG(("nsEnigMimeListener::ParseHeader: header='%s'\n", headerStr.get()));
  PRInt32 colonOffset;
  colonOffset = headerStr.FindChar(':');
  if (colonOffset < 0)
    return;

  // Null header key not allowed
  if (colonOffset == 0)
    return;

  // Extract header key (not case-sensitive)
  nsCAutoString headerKey = (nsCString) nsDependentCSubstring (headerStr, 0, colonOffset);
  ToLowerCase(headerKey);


  // Extract header value, trimming leading/trailing whitespace
  nsCAutoString buf = (nsCString) nsDependentCSubstring (headerStr, colonOffset+1, headerStr.Length() - colonOffset);
  buf.Trim(" ", PR_TRUE, PR_TRUE);

  //DEBUG_LOG(("nsEnigMimeListener::ParseHeader: '%s': %s\n", headerKey.get(), buf.get()));

  PRInt32 semicolonOffset = buf.FindChar(';');

  nsCString headerValue;
  if (semicolonOffset < 0) {
    // No parameters
    headerValue = ((nsCString)buf).get();

  } else {
    // Extract value to left of parameters
    headerValue = nsDependentCSubstring (buf, 0, semicolonOffset);
  }

  // Trim leading and trailing spaces in header value
  headerValue.Trim(" ", PR_TRUE, PR_TRUE);

  if (headerKey.Equals("content-type")) {
    mContentType = headerValue;

    DEBUG_LOG(("nsEnigMimeListener::ParseHeader: ContentType=%s\n",
               mContentType.get()));

    if (!buf.IsEmpty()) {
      char *charset  = MimeHeaders_get_parameter(buf.get(),
                              HEADER_PARM_CHARSET, NULL, NULL);
      char *boundary = MimeHeaders_get_parameter(buf.get(),
                              HEADER_PARM_BOUNDARY, NULL, NULL);
      char *protocol = MimeHeaders_get_parameter(buf.get(),
                              PARAM_PROTOCOL, NULL, NULL);
      char *micalg   = MimeHeaders_get_parameter(buf.get(),
                               PARAM_MICALG, NULL, NULL);

      if (charset)
        mContentCharset = charset;

      if (boundary)
        mContentBoundary = boundary;

      if (protocol)
        mContentProtocol = protocol;

      if (micalg)
        mContentMicalg = micalg;

      PR_FREEIF(charset);
      PR_FREEIF(boundary);
      PR_FREEIF(protocol);
      PR_FREEIF(micalg);

      DEBUG_LOG(("nsEnigMimeListener::ParseHeader: ContentCharset=%s\n",
                 mContentCharset.get()));

      DEBUG_LOG(("nsEnigMimeListener::ParseHeader: ContentBoundary=%s\n",
                 mContentBoundary.get()));

      DEBUG_LOG(("nsEnigMimeListener::ParseHeader: ContentProtocol=%s\n",
                 mContentProtocol.get()));

      DEBUG_LOG(("nsEnigMimeListener::ParseHeader: ContentMicalg=%s\n",
                 mContentMicalg.get()));
    }

  } else if (headerKey.Equals("content-transfer-encoding")) {
    mContentEncoding = buf;
    ToLowerCase(mContentEncoding);

    DEBUG_LOG(("nsEnigMimeListener::ParseHeader: ContentEncoding=%s\n",
               mContentEncoding.get()));

  } else if (headerKey.Equals("content-disposition")) {
    mContentDisposition = buf;

    DEBUG_LOG(("nsEnigMimeListener::ParseHeader: ContentDisposition=%s\n",
               mContentDisposition.get()));

  } else if (headerKey.Equals("content-length")) {
    nsresult status;
    PRInt32 value = headerValue.ToInteger(&status);

    if (NS_SUCCEEDED(status))
      mContentLength = value;

    DEBUG_LOG(("nsEnigMimeListener::ParseHeader: ContenLengtht=%d\n",
               mContentLength));
  }

  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsEnigMimeListener::ParseMimeHeaders ( const char *  mimeHeaders,
PRUint32  count 
) [protected]

Definition at line 692 of file nsEnigMimeListener.cpp.

{
  DEBUG_LOG(("nsEnigMimeListener::ParseMimeHeaders, count=%d\n", count));

  // Copy headers string
  nsCAutoString headers(mimeHeaders, count);

  // Replace CRLF with just LF
  __ReplaceCSubstring(headers, "\r\n", "\n");

  // Replace CR with LF (for MAC-style line endings)
  __ReplaceCChar(headers, '\r', '\n');

  // Eliminate all leading whitespace (including linefeeds)
  headers.Trim(" \t\n", PR_TRUE, PR_FALSE);

  if (headers.Length() <= 3) {
    // No headers to parse
    return;
  }

  // Handle continuation of MIME headers, i.e., newline followed by whitespace
  __ReplaceCSubstring(headers, "\n ",  " ");
  __ReplaceCSubstring(headers, "\n\t", "\t");

  //DEBUG_LOG(("nsEnigMimeListener::ParseMimeHeaders: headers='%s'\n", headers.get()));

  PRUint32 offset = 0;
  while (offset < headers.Length()) {
    PRInt32 lineEnd = headers.FindChar('\n', offset);

    if (lineEnd < 0) {
      // Header line terminator not found
      NS_NOTREACHED("lineEnd == kNotFound");
      return;
    }

    // Normal exit if empty header line
    if (lineEnd == (int)offset)
      break;

    // Parse header line
    ParseHeader((headers.get())+offset, lineEnd - offset);

    offset = lineEnd+1;
  }

  if (mDecodeContent) {
    // Decode data
    if (mContentEncoding.Equals("base64", CaseInsensitiveCompare)) {

      mDecoderData = MimeB64DecoderInit(EnigMimeListener_write, (void*) this);

    } else if (mContentEncoding.Equals("quoted-printable", CaseInsensitiveCompare)) {

      mDecoderData = MimeQPDecoderInit(EnigMimeListener_write, (void*) this);
    }
  }
  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

NS_METHOD nsEnigMimeListener::SendStream ( const char *  buf,
PRUint32  count,
nsIRequest *  aRequest,
nsISupports *  aContext 
)

Definition at line 247 of file nsEnigMimeListener.cpp.

{
  nsresult rv;

  DEBUG_LOG(("nsEnigMimeListener::SendStream: (%p) %d\n", this, count));

  if (!mListener)
    return NS_OK;

  // Transmit data to listener
  mStreamBuf = buf;
  mStreamOffset = 0;
  mStreamLength = count;

  rv = mListener->OnDataAvailable(aRequest,
                                  mContext ? mContext.get() : aContext,
                                  (nsIInputStream*)(this),
                                  0, count);
  Close();

  return rv;
}

Here is the caller graph for this function:

NS_IMETHODIMP nsEnigMimeListener::StartRequest ( nsIRequest *  aRequest,
nsISupports *  aContext 
) [protected]

Definition at line 479 of file nsEnigMimeListener.cpp.

{
  nsresult rv;

  DEBUG_LOG(("nsEnigMimeListener::StartRequest: (%p)\n", this));

  if (!mHeaders.IsEmpty()) {
    // Try to parse headers
    ParseMimeHeaders(mHeaders.get(), mHeaders.Length());
  }

  if (mListener) {
    rv = mListener->OnStartRequest(aRequest,
                                   mContext ? mContext.get() : aContext);
    if (NS_FAILED(rv))
      return rv;
  }

  mRequestStarted = PR_TRUE;

  if (mHeaders.IsEmpty() && mSkipBody) {
    // No headers terminated and skipping body; so discard whatever we have
    mDataStr = "";
  }

  if (!mDataStr.IsEmpty()) {
    // Transmit header/body data already in buffer
    nsCAutoString temStr( mDataStr );

    mDataOffset += mDataStr.Length();
    mDataStr = "";

    rv = Transmit(temStr.get(), temStr.Length(), aRequest, aContext);
    if (NS_FAILED(rv))
      return rv;
  }

  return NS_OK;
}

Here is the call graph for this function:

NS_METHOD nsEnigMimeListener::Transmit ( const char *  buf,
PRUint32  count,
nsIRequest *  aRequest,
nsISupports *  aContext 
) [protected]

Definition at line 230 of file nsEnigMimeListener.cpp.

{
  DEBUG_LOG(("nsEnigMimeListener::Transmit: (%p) %d\n", this, count));

  if (!mDecoderData) {
    return SendStream(buf, count, aRequest, aContext);
  }

  // Decode data before transmitting to listener
  int status = MimeDecoderWrite(mDecoderData, buf, count);

  return (status == 0) ? NS_OK : NS_ERROR_FAILURE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsIEnigMimeListener::write ( in string  buf,
in unsigned long  count,
in nsIRequest  request,
in nsISupports  ctxt 
) [inherited]

Member Data Documentation

readonly attribute ACString nsIEnigMimeListener::contentBoundary [inherited]

Definition at line 61 of file nsIEnigMimeListener.idl.

readonly attribute ACString nsIEnigMimeListener::contentCharset [inherited]

Definition at line 60 of file nsIEnigMimeListener.idl.

readonly attribute ACString nsIEnigMimeListener::contentDisposition [inherited]

Definition at line 67 of file nsIEnigMimeListener.idl.

readonly attribute ACString nsIEnigMimeListener::contentEncoding [inherited]

Definition at line 65 of file nsIEnigMimeListener.idl.

readonly attribute long nsIEnigMimeListener::contentLength [inherited]

The length of the data, if available.

A value of -1 indicates that the content length is unknown.

Definition at line 73 of file nsIEnigMimeListener.idl.

readonly attribute ACString nsIEnigMimeListener::contentMicalg [inherited]

Definition at line 63 of file nsIEnigMimeListener.idl.

readonly attribute ACString nsIEnigMimeListener::contentProtocol [inherited]

Definition at line 62 of file nsIEnigMimeListener.idl.

readonly attribute ACString nsIEnigMimeListener::contentType [inherited]

Definition at line 59 of file nsIEnigMimeListener.idl.

readonly attribute ACString nsIEnigMimeListener::headers [inherited]

Definition at line 56 of file nsIEnigMimeListener.idl.

readonly attribute ACString nsIEnigMimeListener::linebreak [inherited]

Definition at line 57 of file nsIEnigMimeListener.idl.

nsCString nsEnigMimeListener::mContentBoundary [protected]

Definition at line 86 of file nsEnigMimeListener.h.

nsCString nsEnigMimeListener::mContentCharset [protected]

Definition at line 85 of file nsEnigMimeListener.h.

Definition at line 91 of file nsEnigMimeListener.h.

nsCString nsEnigMimeListener::mContentEncoding [protected]

Definition at line 90 of file nsEnigMimeListener.h.

Definition at line 92 of file nsEnigMimeListener.h.

nsCString nsEnigMimeListener::mContentMicalg [protected]

Definition at line 88 of file nsEnigMimeListener.h.

nsCString nsEnigMimeListener::mContentProtocol [protected]

Definition at line 87 of file nsEnigMimeListener.h.

nsCString nsEnigMimeListener::mContentType [protected]

Definition at line 84 of file nsEnigMimeListener.h.

nsCOMPtr<nsISupports> nsEnigMimeListener::mContext [protected]

Definition at line 115 of file nsEnigMimeListener.h.

PRUint32 nsEnigMimeListener::mDataOffset [protected]

Definition at line 106 of file nsEnigMimeListener.h.

nsCString nsEnigMimeListener::mDataStr [protected]

Definition at line 99 of file nsEnigMimeListener.h.

Definition at line 94 of file nsEnigMimeListener.h.

Definition at line 95 of file nsEnigMimeListener.h.

nsCString nsEnigMimeListener::mHeaders [protected]

Definition at line 98 of file nsEnigMimeListener.h.

Definition at line 100 of file nsEnigMimeListener.h.

Definition at line 102 of file nsEnigMimeListener.h.

Definition at line 103 of file nsEnigMimeListener.h.

Definition at line 79 of file nsEnigMimeListener.h.

nsCString nsEnigMimeListener::mLinebreak [protected]

Definition at line 97 of file nsEnigMimeListener.h.

nsCOMPtr<nsIStreamListener> nsEnigMimeListener::mListener [protected]

Definition at line 114 of file nsEnigMimeListener.h.

Definition at line 105 of file nsEnigMimeListener.h.

Definition at line 80 of file nsEnigMimeListener.h.

Definition at line 82 of file nsEnigMimeListener.h.

Definition at line 81 of file nsEnigMimeListener.h.

const char* nsEnigMimeListener::mStreamBuf [protected]

Definition at line 108 of file nsEnigMimeListener.h.

PRUint32 nsEnigMimeListener::mStreamLength [protected]

Definition at line 110 of file nsEnigMimeListener.h.

PRUint32 nsEnigMimeListener::mStreamOffset [protected]

Definition at line 109 of file nsEnigMimeListener.h.

Definition at line 111 of file nsEnigMimeListener.h.

MIME filtering for multipart stuff: Display first part (should be non-multipart or multipart/alternative) Each message/rfc822 is treated as a plain text (.eml) attachment For display, each message/rfc822 item is emitted with its first "atomic" item, so that the subject headers etc.

are displayed. Attempt to display all text/ or image/ items inline, if not marked as attachment (also display them as attachments) No. of attachments = no. of "atomic" items - 1 (i.e., firstitem)

  • no. of message/rfc822 items For display, multipart/mixed should not be nested, unless there is an intervening message/rfc822 wrapper

Definition at line 89 of file nsIEnigMimeListener.idl.


The documentation for this class was generated from the following files: