1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/netwerk/streamconv/converters/nsMultiMixedConv.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,171 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 +#ifndef __nsmultimixedconv__h__ 1.9 +#define __nsmultimixedconv__h__ 1.10 + 1.11 +#include "nsIStreamConverter.h" 1.12 +#include "nsIChannel.h" 1.13 +#include "nsString.h" 1.14 +#include "nsCOMPtr.h" 1.15 +#include "nsIByteRangeRequest.h" 1.16 +#include "nsIMultiPartChannel.h" 1.17 +#include "nsAutoPtr.h" 1.18 +#include "mozilla/Attributes.h" 1.19 + 1.20 +#define NS_MULTIMIXEDCONVERTER_CID \ 1.21 +{ /* 7584CE90-5B25-11d3-A175-0050041CAF44 */ \ 1.22 + 0x7584ce90, \ 1.23 + 0x5b25, \ 1.24 + 0x11d3, \ 1.25 + {0xa1, 0x75, 0x0, 0x50, 0x4, 0x1c, 0xaf, 0x44} \ 1.26 +} 1.27 + 1.28 +// 1.29 +// nsPartChannel is a "dummy" channel which represents an individual part of 1.30 +// a multipart/mixed stream... 1.31 +// 1.32 +// Instances on this channel are passed out to the consumer through the 1.33 +// nsIStreamListener interface. 1.34 +// 1.35 +class nsPartChannel MOZ_FINAL : public nsIChannel, 1.36 + public nsIByteRangeRequest, 1.37 + public nsIMultiPartChannel 1.38 +{ 1.39 +public: 1.40 + nsPartChannel(nsIChannel *aMultipartChannel, uint32_t aPartID, 1.41 + nsIStreamListener* aListener); 1.42 + 1.43 + void InitializeByteRange(int64_t aStart, int64_t aEnd); 1.44 + void SetIsLastPart() { mIsLastPart = true; } 1.45 + nsresult SendOnStartRequest(nsISupports* aContext); 1.46 + nsresult SendOnDataAvailable(nsISupports* aContext, nsIInputStream* aStream, 1.47 + uint64_t aOffset, uint32_t aLen); 1.48 + nsresult SendOnStopRequest(nsISupports* aContext, nsresult aStatus); 1.49 + /* SetContentDisposition expects the full value of the Content-Disposition 1.50 + * header */ 1.51 + void SetContentDisposition(const nsACString& aContentDispositionHeader); 1.52 + 1.53 + NS_DECL_ISUPPORTS 1.54 + NS_DECL_NSIREQUEST 1.55 + NS_DECL_NSICHANNEL 1.56 + NS_DECL_NSIBYTERANGEREQUEST 1.57 + NS_DECL_NSIMULTIPARTCHANNEL 1.58 + 1.59 +protected: 1.60 + ~nsPartChannel(); 1.61 + 1.62 +protected: 1.63 + nsCOMPtr<nsIChannel> mMultipartChannel; 1.64 + nsCOMPtr<nsIStreamListener> mListener; 1.65 + 1.66 + nsresult mStatus; 1.67 + nsLoadFlags mLoadFlags; 1.68 + 1.69 + nsCOMPtr<nsILoadGroup> mLoadGroup; 1.70 + 1.71 + nsCString mContentType; 1.72 + nsCString mContentCharset; 1.73 + uint32_t mContentDisposition; 1.74 + nsString mContentDispositionFilename; 1.75 + nsCString mContentDispositionHeader; 1.76 + uint64_t mContentLength; 1.77 + 1.78 + bool mIsByteRangeRequest; 1.79 + int64_t mByteRangeStart; 1.80 + int64_t mByteRangeEnd; 1.81 + 1.82 + uint32_t mPartID; // unique ID that can be used to identify 1.83 + // this part of the multipart document 1.84 + bool mIsLastPart; 1.85 +}; 1.86 + 1.87 +// The nsMultiMixedConv stream converter converts a stream of type "multipart/x-mixed-replace" 1.88 +// to it's subparts. There was some debate as to whether or not the functionality desired 1.89 +// when HTTP confronted this type required a stream converter. After all, this type really 1.90 +// prompts various viewer related actions rather than stream conversion. There simply needs 1.91 +// to be a piece in place that can strip out the multiple parts of a stream of this type, and 1.92 +// "display" them accordingly. 1.93 +// 1.94 +// With that said, this "stream converter" spends more time packaging up the sub parts of the 1.95 +// main stream and sending them off the destination stream listener, than doing any real 1.96 +// stream parsing/converting. 1.97 +// 1.98 +// WARNING: This converter requires that it's destination stream listener be able to handle 1.99 +// multiple OnStartRequest(), OnDataAvailable(), and OnStopRequest() call combinations. 1.100 +// Each series represents the beginning, data production, and ending phase of each sub- 1.101 +// part of the original stream. 1.102 +// 1.103 +// NOTE: this MIME-type is used by HTTP, *not* SMTP, or IMAP. 1.104 +// 1.105 +// NOTE: For reference, a general description of how this MIME type should be handled via 1.106 +// HTTP, see http://home.netscape.com/assist/net_sites/pushpull.html . Note that 1.107 +// real world server content deviates considerably from this overview. 1.108 +// 1.109 +// Implementation assumptions: 1.110 +// Assumed structue: 1.111 +// --BoundaryToken[\r]\n 1.112 +// content-type: foo/bar[\r]\n 1.113 +// ... (other headers if any) 1.114 +// [\r]\n (second line feed to delimit end of headers) 1.115 +// data 1.116 +// --BoundaryToken-- (end delimited by final "--") 1.117 +// 1.118 +// linebreaks can be either CRLF or LFLF. linebreaks preceding 1.119 +// boundary tokens are considered part of the data. BoundaryToken 1.120 +// is any opaque string. 1.121 +// 1.122 +// 1.123 + 1.124 +class nsMultiMixedConv : public nsIStreamConverter { 1.125 +public: 1.126 + NS_DECL_ISUPPORTS 1.127 + NS_DECL_NSISTREAMCONVERTER 1.128 + NS_DECL_NSISTREAMLISTENER 1.129 + NS_DECL_NSIREQUESTOBSERVER 1.130 + 1.131 + nsMultiMixedConv(); 1.132 + virtual ~nsMultiMixedConv(); 1.133 + 1.134 +protected: 1.135 + nsresult SendStart(nsIChannel *aChannel); 1.136 + nsresult SendStop(nsresult aStatus); 1.137 + nsresult SendData(char *aBuffer, uint32_t aLen); 1.138 + nsresult ParseHeaders(nsIChannel *aChannel, char *&aPtr, 1.139 + uint32_t &aLen, bool *_retval); 1.140 + int32_t PushOverLine(char *&aPtr, uint32_t &aLen); 1.141 + char *FindToken(char *aCursor, uint32_t aLen); 1.142 + nsresult BufferData(char *aData, uint32_t aLen); 1.143 + 1.144 + // member data 1.145 + bool mNewPart; // Are we processing the beginning of a part? 1.146 + bool mProcessingHeaders; 1.147 + nsCOMPtr<nsIStreamListener> mFinalListener; // this guy gets the converted data via his OnDataAvailable() 1.148 + 1.149 + nsCString mToken; 1.150 + uint32_t mTokenLen; 1.151 + 1.152 + nsRefPtr<nsPartChannel> mPartChannel; // the channel for the given part we're processing. 1.153 + // one channel per part. 1.154 + nsCOMPtr<nsISupports> mContext; 1.155 + nsCString mContentType; 1.156 + nsCString mContentDisposition; 1.157 + uint64_t mContentLength; 1.158 + 1.159 + char *mBuffer; 1.160 + uint32_t mBufLen; 1.161 + uint64_t mTotalSent; 1.162 + bool mFirstOnData; // used to determine if we're in our first OnData callback. 1.163 + 1.164 + // The following members are for tracking the byte ranges in 1.165 + // multipart/mixed content which specified the 'Content-Range:' 1.166 + // header... 1.167 + int64_t mByteRangeStart; 1.168 + int64_t mByteRangeEnd; 1.169 + bool mIsByteRangeRequest; 1.170 + 1.171 + uint32_t mCurrentPartID; 1.172 +}; 1.173 + 1.174 +#endif /* __nsmultimixedconv__h__ */