Back to index

lightning-sunbird  0.9+nobinonly
nsMultiMixedConv.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 #ifndef __nsmultimixedconv__h__
00038 #define __nsmultimixedconv__h__
00039 
00040 #include "nsIStreamConverter.h"
00041 #include "nsIChannel.h"
00042 #include "nsIURI.h"
00043 #include "nsString.h"
00044 #include "nsXPIDLString.h"
00045 #include "nsCOMPtr.h"
00046 #include "nsInt64.h"
00047 #include "nsIByteRangeRequest.h"
00048 #include "nsIMultiPartChannel.h"
00049 #include "nsAutoPtr.h"
00050 
00051 #define NS_MULTIMIXEDCONVERTER_CID                         \
00052 { /* 7584CE90-5B25-11d3-A175-0050041CAF44 */         \
00053     0x7584ce90,                                      \
00054     0x5b25,                                          \
00055     0x11d3,                                          \
00056     {0xa1, 0x75, 0x0, 0x50, 0x4, 0x1c, 0xaf, 0x44}       \
00057 }
00058 
00059 //
00060 // nsPartChannel is a "dummy" channel which represents an individual part of
00061 // a multipart/mixed stream...
00062 //
00063 // Instances on this channel are passed out to the consumer through the
00064 // nsIStreamListener interface.
00065 //
00066 class nsPartChannel : public nsIChannel,
00067                       public nsIByteRangeRequest,
00068                       public nsIMultiPartChannel
00069 {
00070 public:
00071   nsPartChannel(nsIChannel *aMultipartChannel, PRUint32 aPartID);
00072 
00073   void InitializeByteRange(PRInt64 aStart, PRInt64 aEnd);
00074   void SetIsLastPart() { mIsLastPart = PR_TRUE; }
00075 
00076   NS_DECL_ISUPPORTS
00077   NS_DECL_NSIREQUEST
00078   NS_DECL_NSICHANNEL
00079   NS_DECL_NSIBYTERANGEREQUEST
00080   NS_DECL_NSIMULTIPARTCHANNEL
00081 
00082 protected:
00083   ~nsPartChannel();
00084 
00085 protected:
00086   nsCOMPtr<nsIChannel>    mMultipartChannel;
00087   
00088   nsresult                mStatus;
00089   nsLoadFlags             mLoadFlags;
00090 
00091   nsCOMPtr<nsILoadGroup>  mLoadGroup;
00092 
00093   nsCString               mContentType;
00094   nsCString               mContentCharset;
00095   nsCString               mContentDisposition;
00096   nsUint64                mContentLength;
00097 
00098   PRBool                  mIsByteRangeRequest;
00099   nsInt64                 mByteRangeStart;
00100   nsInt64                 mByteRangeEnd;
00101 
00102   PRUint32                mPartID; // unique ID that can be used to identify
00103                                    // this part of the multipart document
00104   PRBool                  mIsLastPart;
00105 };
00106 
00107 // The nsMultiMixedConv stream converter converts a stream of type "multipart/x-mixed-replace"
00108 // to it's subparts. There was some debate as to whether or not the functionality desired
00109 // when HTTP confronted this type required a stream converter. After all, this type really
00110 // prompts various viewer related actions rather than stream conversion. There simply needs
00111 // to be a piece in place that can strip out the multiple parts of a stream of this type, and 
00112 // "display" them accordingly.
00113 //
00114 // With that said, this "stream converter" spends more time packaging up the sub parts of the
00115 // main stream and sending them off the destination stream listener, than doing any real
00116 // stream parsing/converting.
00117 //
00118 // WARNING: This converter requires that it's destination stream listener be able to handle
00119 //   multiple OnStartRequest(), OnDataAvailable(), and OnStopRequest() call combinations.
00120 //   Each series represents the beginning, data production, and ending phase of each sub-
00121 //   part of the original stream.
00122 //
00123 // NOTE: this MIME-type is used by HTTP, *not* SMTP, or IMAP.
00124 //
00125 // NOTE: For reference, a general description of how this MIME type should be handled via
00126 //   HTTP, see http://home.netscape.com/assist/net_sites/pushpull.html . Note that
00127 //   real world server content deviates considerably from this overview.
00128 //
00129 // Implementation assumptions:
00130 //  Assumed structue:
00131 //  --BoundaryToken[\r]\n
00132 //  content-type: foo/bar[\r]\n
00133 //  ... (other headers if any)
00134 //  [\r]\n (second line feed to delimit end of headers)
00135 //  data
00136 //  --BoundaryToken-- (end delimited by final "--")
00137 //
00138 // linebreaks can be either CRLF or LFLF. linebreaks preceeding
00139 // boundary tokens are considered part of the data. BoundaryToken
00140 // is any opaque string.
00141 //  
00142 //
00143 
00144 class nsMultiMixedConv : public nsIStreamConverter {
00145 public:
00146     NS_DECL_ISUPPORTS
00147     NS_DECL_NSISTREAMCONVERTER
00148     NS_DECL_NSISTREAMLISTENER
00149     NS_DECL_NSIREQUESTOBSERVER
00150 
00151     nsMultiMixedConv();
00152     virtual ~nsMultiMixedConv();
00153 
00154 protected:
00155     nsresult SendStart(nsIChannel *aChannel);
00156     nsresult SendStop(nsresult aStatus);
00157     nsresult SendData(char *aBuffer, PRUint32 aLen);
00158     nsresult ParseHeaders(nsIChannel *aChannel, char *&aPtr,
00159                           PRUint32 &aLen, PRBool *_retval);
00160     PRInt32  PushOverLine(char *&aPtr, PRUint32 &aLen);
00161     char *FindToken(char *aCursor, PRUint32 aLen);
00162     nsresult BufferData(char *aData, PRUint32 aLen);
00163 
00164     // member data
00165     PRBool              mNewPart;        // Are we processing the beginning of a part?
00166     PRBool              mProcessingHeaders;
00167     nsCOMPtr<nsIStreamListener> mFinalListener; // this guy gets the converted data via his OnDataAvailable()
00168 
00169     nsCString           mToken;
00170     PRUint32            mTokenLen;
00171 
00172     nsRefPtr<nsPartChannel> mPartChannel;   // the channel for the given part we're processing.
00173                                         // one channel per part.
00174     nsCOMPtr<nsISupports> mContext;
00175     nsCString           mContentType;
00176     nsCString           mContentDisposition;
00177     nsUint64            mContentLength;
00178     
00179     char                *mBuffer;
00180     PRUint32            mBufLen;
00181     nsUint64            mTotalSent;
00182     PRBool              mFirstOnData;   // used to determine if we're in our first OnData callback.
00183 
00184     // The following members are for tracking the byte ranges in
00185     // multipart/mixed content which specified the 'Content-Range:'
00186     // header...
00187     nsInt64             mByteRangeStart;
00188     nsInt64             mByteRangeEnd;
00189     PRBool              mIsByteRangeRequest;
00190 
00191     PRUint32            mCurrentPartID;
00192 };
00193 
00194 #endif /* __nsmultimixedconv__h__ */