1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : *
24 : * Alternatively, the contents of this file may be used under the terms of
25 : * either the GNU General Public License Version 2 or later (the "GPL"), or
26 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 : * in which case the provisions of the GPL or the LGPL are applicable instead
28 : * of those above. If you wish to allow use of your version of this file only
29 : * under the terms of either the GPL or the LGPL, and not to allow others to
30 : * use your version of this file under the terms of the MPL, indicate your
31 : * decision by deleting the provisions above and replace them with the notice
32 : * and other provisions required by the GPL or the LGPL. If you do not delete
33 : * the provisions above, a recipient may use your version of this file under
34 : * the terms of any one of the MPL, the GPL or the LGPL.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 : #ifndef __nsmultimixedconv__h__
38 : #define __nsmultimixedconv__h__
39 :
40 : #include "nsIStreamConverter.h"
41 : #include "nsIChannel.h"
42 : #include "nsIURI.h"
43 : #include "nsString.h"
44 : #include "nsXPIDLString.h"
45 : #include "nsCOMPtr.h"
46 : #include "nsIByteRangeRequest.h"
47 : #include "nsIMultiPartChannel.h"
48 : #include "nsAutoPtr.h"
49 :
50 : #define NS_MULTIMIXEDCONVERTER_CID \
51 : { /* 7584CE90-5B25-11d3-A175-0050041CAF44 */ \
52 : 0x7584ce90, \
53 : 0x5b25, \
54 : 0x11d3, \
55 : {0xa1, 0x75, 0x0, 0x50, 0x4, 0x1c, 0xaf, 0x44} \
56 : }
57 :
58 : //
59 : // nsPartChannel is a "dummy" channel which represents an individual part of
60 : // a multipart/mixed stream...
61 : //
62 : // Instances on this channel are passed out to the consumer through the
63 : // nsIStreamListener interface.
64 : //
65 : class nsPartChannel : public nsIChannel,
66 : public nsIByteRangeRequest,
67 : public nsIMultiPartChannel
68 : {
69 : public:
70 : nsPartChannel(nsIChannel *aMultipartChannel, PRUint32 aPartID,
71 : nsIStreamListener* aListener);
72 :
73 : void InitializeByteRange(PRInt64 aStart, PRInt64 aEnd);
74 0 : void SetIsLastPart() { mIsLastPart = true; }
75 : nsresult SendOnStartRequest(nsISupports* aContext);
76 : nsresult SendOnDataAvailable(nsISupports* aContext, nsIInputStream* aStream,
77 : PRUint32 aOffset, PRUint32 aLen);
78 : nsresult SendOnStopRequest(nsISupports* aContext, nsresult aStatus);
79 : /* SetContentDisposition expects the full value of the Content-Disposition
80 : * header */
81 : void SetContentDisposition(const nsACString& aContentDispositionHeader);
82 :
83 : NS_DECL_ISUPPORTS
84 : NS_DECL_NSIREQUEST
85 : NS_DECL_NSICHANNEL
86 : NS_DECL_NSIBYTERANGEREQUEST
87 : NS_DECL_NSIMULTIPARTCHANNEL
88 :
89 : protected:
90 : ~nsPartChannel();
91 :
92 : protected:
93 : nsCOMPtr<nsIChannel> mMultipartChannel;
94 : nsCOMPtr<nsIStreamListener> mListener;
95 :
96 : nsresult mStatus;
97 : nsLoadFlags mLoadFlags;
98 :
99 : nsCOMPtr<nsILoadGroup> mLoadGroup;
100 :
101 : nsCString mContentType;
102 : nsCString mContentCharset;
103 : PRUint32 mContentDisposition;
104 : nsString mContentDispositionFilename;
105 : nsCString mContentDispositionHeader;
106 : PRUint64 mContentLength;
107 :
108 : bool mIsByteRangeRequest;
109 : PRInt64 mByteRangeStart;
110 : PRInt64 mByteRangeEnd;
111 :
112 : PRUint32 mPartID; // unique ID that can be used to identify
113 : // this part of the multipart document
114 : bool mIsLastPart;
115 : };
116 :
117 : // The nsMultiMixedConv stream converter converts a stream of type "multipart/x-mixed-replace"
118 : // to it's subparts. There was some debate as to whether or not the functionality desired
119 : // when HTTP confronted this type required a stream converter. After all, this type really
120 : // prompts various viewer related actions rather than stream conversion. There simply needs
121 : // to be a piece in place that can strip out the multiple parts of a stream of this type, and
122 : // "display" them accordingly.
123 : //
124 : // With that said, this "stream converter" spends more time packaging up the sub parts of the
125 : // main stream and sending them off the destination stream listener, than doing any real
126 : // stream parsing/converting.
127 : //
128 : // WARNING: This converter requires that it's destination stream listener be able to handle
129 : // multiple OnStartRequest(), OnDataAvailable(), and OnStopRequest() call combinations.
130 : // Each series represents the beginning, data production, and ending phase of each sub-
131 : // part of the original stream.
132 : //
133 : // NOTE: this MIME-type is used by HTTP, *not* SMTP, or IMAP.
134 : //
135 : // NOTE: For reference, a general description of how this MIME type should be handled via
136 : // HTTP, see http://home.netscape.com/assist/net_sites/pushpull.html . Note that
137 : // real world server content deviates considerably from this overview.
138 : //
139 : // Implementation assumptions:
140 : // Assumed structue:
141 : // --BoundaryToken[\r]\n
142 : // content-type: foo/bar[\r]\n
143 : // ... (other headers if any)
144 : // [\r]\n (second line feed to delimit end of headers)
145 : // data
146 : // --BoundaryToken-- (end delimited by final "--")
147 : //
148 : // linebreaks can be either CRLF or LFLF. linebreaks preceding
149 : // boundary tokens are considered part of the data. BoundaryToken
150 : // is any opaque string.
151 : //
152 : //
153 :
154 : class nsMultiMixedConv : public nsIStreamConverter {
155 : public:
156 : NS_DECL_ISUPPORTS
157 : NS_DECL_NSISTREAMCONVERTER
158 : NS_DECL_NSISTREAMLISTENER
159 : NS_DECL_NSIREQUESTOBSERVER
160 :
161 : nsMultiMixedConv();
162 : virtual ~nsMultiMixedConv();
163 :
164 : protected:
165 : nsresult SendStart(nsIChannel *aChannel);
166 : nsresult SendStop(nsresult aStatus);
167 : nsresult SendData(char *aBuffer, PRUint32 aLen);
168 : nsresult ParseHeaders(nsIChannel *aChannel, char *&aPtr,
169 : PRUint32 &aLen, bool *_retval);
170 : PRInt32 PushOverLine(char *&aPtr, PRUint32 &aLen);
171 : char *FindToken(char *aCursor, PRUint32 aLen);
172 : nsresult BufferData(char *aData, PRUint32 aLen);
173 :
174 : // member data
175 : bool mNewPart; // Are we processing the beginning of a part?
176 : bool mProcessingHeaders;
177 : nsCOMPtr<nsIStreamListener> mFinalListener; // this guy gets the converted data via his OnDataAvailable()
178 :
179 : nsCString mToken;
180 : PRUint32 mTokenLen;
181 :
182 : nsRefPtr<nsPartChannel> mPartChannel; // the channel for the given part we're processing.
183 : // one channel per part.
184 : nsCOMPtr<nsISupports> mContext;
185 : nsCString mContentType;
186 : nsCString mContentDisposition;
187 : PRUint64 mContentLength;
188 :
189 : char *mBuffer;
190 : PRUint32 mBufLen;
191 : PRUint64 mTotalSent;
192 : bool mFirstOnData; // used to determine if we're in our first OnData callback.
193 :
194 : // The following members are for tracking the byte ranges in
195 : // multipart/mixed content which specified the 'Content-Range:'
196 : // header...
197 : PRInt64 mByteRangeStart;
198 : PRInt64 mByteRangeEnd;
199 : bool mIsByteRangeRequest;
200 :
201 : PRUint32 mCurrentPartID;
202 : };
203 :
204 : #endif /* __nsmultimixedconv__h__ */
|