netwerk/streamconv/converters/nsMultiMixedConv.h

changeset 0
6474c204b198
     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__ */

mercurial