Bug 1307456 - Remove packaged app related changes to nsMultiMixedConv r=bagder draft
authorValentin Gosu <valentin.gosu@gmail.com>
Mon, 31 Oct 2016 15:32:15 +0100
changeset 431762 87f5a990638f65ad568619b504db057c9c05871a
parent 431761 25ac286f8b0b69dfb0c80966a78926751f955284
child 535458 ac34248ca0f5856de6863f4a1d296ad47f5147da
push id34102
push uservalentin.gosu@gmail.com
push dateMon, 31 Oct 2016 14:36:30 +0000
reviewersbagder
bugs1307456
milestone52.0a1
Bug 1307456 - Remove packaged app related changes to nsMultiMixedConv r=bagder MozReview-Commit-ID: Vkt8s9xT5E
netwerk/base/moz.build
netwerk/base/nsIMultiPartChannel.idl
netwerk/base/nsIResponseHeadProvider.idl
netwerk/protocol/http/nsHttpTransaction.cpp
netwerk/streamconv/converters/nsMultiMixedConv.cpp
netwerk/streamconv/converters/nsMultiMixedConv.h
netwerk/test/unit/test_multipart_streamconv_application_package.js
netwerk/test/unit/xpcshell.ini
uriloader/exthandler/ExternalHelperAppParent.cpp
--- a/netwerk/base/moz.build
+++ b/netwerk/base/moz.build
@@ -90,17 +90,16 @@ XPIDL_SOURCES += [
     'nsIProxyInfo.idl',
     'nsIRandomGenerator.idl',
     'nsIRedirectChannelRegistrar.idl',
     'nsIRedirectResultListener.idl',
     'nsIRequest.idl',
     'nsIRequestContext.idl',
     'nsIRequestObserver.idl',
     'nsIRequestObserverProxy.idl',
-    'nsIResponseHeadProvider.idl',
     'nsIResumableChannel.idl',
     'nsISecCheckWrapChannel.idl',
     'nsISecureBrowserUI.idl',
     'nsISecurityEventSink.idl',
     'nsISecurityInfoProvider.idl',
     'nsISensitiveInfoHiddenURI.idl',
     'nsISerializationHelper.idl',
     'nsIServerSocket.idl',
--- a/netwerk/base/nsIMultiPartChannel.idl
+++ b/netwerk/base/nsIMultiPartChannel.idl
@@ -27,20 +27,9 @@ interface nsIMultiPartChannel : nsISuppo
     readonly attribute uint32_t partID;
 
     /**
      * Set to true when onStopRequest is received from the base channel.
      * The listener can check this from its onStopRequest to determine
      * whether more data can be expected.
      */
     readonly attribute boolean isLastPart;
-
-    /**
-     * ASCII-encoding content prior to the first resource. Only valid for
-     * content-type=application/package.
-     */
-    readonly attribute ACString preamble;
-
-    /**
-     * The original http response header in each part.
-     */
-    readonly attribute ACString originalResponseHeader;
 };
deleted file mode 100644
--- a/netwerk/base/nsIResponseHeadProvider.idl
+++ /dev/null
@@ -1,35 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsISupports.idl"
-
-interface nsIHttpHeaderVisitor;
-
-%{C++
-namespace mozilla {
-namespace net {
-class nsHttpResponseHead;
-}
-}
-%}
-
-[ptr] native nsHttpResponseHeadPtr(mozilla::net::nsHttpResponseHead);
-
-/**
- * nsIResponseHeadProvider
- */
-[scriptable, builtinclass, uuid(cd0d0804-2e0c-4bff-aa0a-78a3e3159b69)]
-interface nsIResponseHeadProvider : nsISupports
-{
-  /**
-   * Returns a pointer to a nsHttpResponseHead. May return null.
-   */
-  [notxpcom] nsHttpResponseHeadPtr GetResponseHead();
-
-  /**
-   * May be used to iterate through the response headers
-   */
-  void visitResponseHeaders(in nsIHttpHeaderVisitor aVisitor);
-};
--- a/netwerk/protocol/http/nsHttpTransaction.cpp
+++ b/netwerk/protocol/http/nsHttpTransaction.cpp
@@ -33,16 +33,17 @@
 #include "nsICancelable.h"
 #include "nsIEventTarget.h"
 #include "nsIHttpChannelInternal.h"
 #include "nsIInputStream.h"
 #include "nsIThrottledInputChannel.h"
 #include "nsITransport.h"
 #include "nsIOService.h"
 #include "nsIRequestContext.h"
+#include "nsIHttpAuthenticator.h"
 #include <algorithm>
 
 #ifdef MOZ_WIDGET_GONK
 #include "NetStatistics.h"
 #endif
 
 //-----------------------------------------------------------------------------
 
--- a/netwerk/streamconv/converters/nsMultiMixedConv.cpp
+++ b/netwerk/streamconv/converters/nsMultiMixedConv.cpp
@@ -46,18 +46,16 @@ nsPartChannel::nsPartChannel(nsIChannel 
   mStatus(NS_OK),
   mContentLength(UINT64_MAX),
   mIsByteRangeRequest(false),
   mByteRangeStart(0),
   mByteRangeEnd(0),
   mPartID(aPartID),
   mIsLastPart(false)
 {
-    mMultipartChannel = aMultipartChannel;
-
     // Inherit the load flags from the original channel...
     mMultipartChannel->GetLoadFlags(&mLoadFlags);
 
     mMultipartChannel->GetLoadGroup(getter_AddRefs(mLoadGroup));
 }
 
 nsPartChannel::~nsPartChannel()
 {
@@ -110,17 +108,16 @@ NS_IMPL_ADDREF(nsPartChannel)
 NS_IMPL_RELEASE(nsPartChannel)
 
 NS_INTERFACE_MAP_BEGIN(nsPartChannel)
     NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIChannel)
     NS_INTERFACE_MAP_ENTRY(nsIRequest)
     NS_INTERFACE_MAP_ENTRY(nsIChannel)
     NS_INTERFACE_MAP_ENTRY(nsIByteRangeRequest)
     NS_INTERFACE_MAP_ENTRY(nsIMultiPartChannel)
-    NS_INTERFACE_MAP_ENTRY(nsIResponseHeadProvider)
 NS_INTERFACE_MAP_END
 
 //
 // nsIRequest implementation...
 //
 
 NS_IMETHODIMP
 nsPartChannel::GetName(nsACString &aResult)
@@ -402,35 +399,16 @@ nsPartChannel::GetPartID(uint32_t *aPart
 NS_IMETHODIMP
 nsPartChannel::GetIsLastPart(bool *aIsLastPart)
 {
     *aIsLastPart = mIsLastPart;
     return NS_OK;
 }
 
 //
-// nsIResponseHeadProvider
-//
-
-NS_IMETHODIMP_(mozilla::net::nsHttpResponseHead *)
-nsPartChannel::GetResponseHead()
-{
-    return mResponseHead;
-}
-
-NS_IMETHODIMP
-nsPartChannel::VisitResponseHeaders(nsIHttpHeaderVisitor *visitor)
-{
-    if (!mResponseHead)
-        return NS_ERROR_NOT_AVAILABLE;
-    return mResponseHead->VisitHeaders(visitor,
-        mozilla::net::nsHttpHeaderArray::eFilterResponse);
-}
-
-//
 // nsIByteRangeRequest implementation...
 //
 
 NS_IMETHODIMP 
 nsPartChannel::GetIsByteRangeRequest(bool *aIsByteRangeRequest)
 {
     *aIsByteRangeRequest = mIsByteRangeRequest;
 
@@ -458,42 +436,16 @@ nsPartChannel::GetBaseChannel(nsIChannel
 {
     NS_ENSURE_ARG_POINTER(aReturn);
 
     *aReturn = mMultipartChannel;
     NS_IF_ADDREF(*aReturn);
     return NS_OK;
 }
 
-NS_IMETHODIMP
-nsPartChannel::GetPreamble(nsACString & aPreamble)
-{
-    aPreamble = mPreamble;
-    return NS_OK;
-}
-
-void
-nsPartChannel::SetPreamble(const nsACString& aPreamble)
-{
-    mPreamble = aPreamble;
-}
-
-NS_IMETHODIMP
-nsPartChannel::GetOriginalResponseHeader(nsACString & aOriginalResponseHeader)
-{
-    aOriginalResponseHeader = mOriginalResponseHeader;
-    return NS_OK;
-}
-
-void
-nsPartChannel::SetOriginalResponseHeader(const nsACString& aOriginalResponseHeader)
-{
-    mOriginalResponseHeader = aOriginalResponseHeader;
-}
-
 // nsISupports implementation
 NS_IMPL_ISUPPORTS(nsMultiMixedConv,
                   nsIStreamConverter,
                   nsIStreamListener,
                   nsIRequestObserver)
 
 
 // nsIStreamConverter implementation
@@ -516,19 +468,16 @@ nsMultiMixedConv::AsyncConvertData(const
     // hook up our final listener. this guy gets the various On*() calls we want to throw
     // at him.
     //
     // WARNING: this listener must be able to handle multiple OnStartRequest, OnDataAvail()
     //  and OnStopRequest() call combinations. We call of series of these for each sub-part
     //  in the raw stream.
     mFinalListener = aListener;
 
-    if (NS_LITERAL_CSTRING(APPLICATION_PACKAGE).Equals(aFromType)) {
-        mPackagedApp = true;
-    }
     return NS_OK;
 }
 
 // AutoFree implementation to prevent memory leaks
 class AutoFree
 {
 public:
   AutoFree() : mBuffer(nullptr) {}
@@ -546,59 +495,16 @@ public:
 
   operator char*() const {
     return mBuffer;
   }
 private:
   char *mBuffer;
 };
 
-char*
-nsMultiMixedConv::ProbeToken(char* aBuffer, uint32_t& aTokenLen)
-{
-    // To sign a packaged web app in the new security model, we need
-    // to add the signature to the package header. The header is the
-    // data before the first token and the header format is
-    //
-    // [field-name]: [field-value] CR LF
-    //
-    // So the package may look like:
-    //
-    // manifest-signature: MRjdkly...
-    // --gc0pJq0M:08jU534c0p
-    // Content-Location: /someapp.webmanifest
-    // Content-Type: application/manifest
-    //
-    // {
-    // "name": "My App",
-    // "description":"A great app!"
-    // ...
-    //
-    //
-    // We search for the first '\r\n--' and assign the subsquent chars
-    // to the token until another '\r\n'. '--' will be included in the
-    // token we probed. If the second '\r\n' is not found, we still treat
-    // the token is not found and more data will be requested.
-
-    char* posCRLFDashDash = PL_strstr(aBuffer, "\r\n--");
-    if (!posCRLFDashDash) {
-        return nullptr;
-    }
-
-    char* tokenStart = posCRLFDashDash + 2; // Skip "\r\n".
-    char* tokenEnd = PL_strstr(tokenStart, "\r\n");
-    if (!tokenEnd) {
-        return nullptr;
-    }
-
-    aTokenLen = tokenEnd - tokenStart;
-
-    return tokenStart;
-}
-
 // nsIStreamListener implementation
 NS_IMETHODIMP
 nsMultiMixedConv::OnDataAvailable(nsIRequest *request, nsISupports *context,
                                   nsIInputStream *inStr, uint64_t sourceOffset,
                                   uint32_t count) {
     nsresult rv = NS_OK;
     AutoFree buffer(nullptr);
     uint32_t bufLen = 0, read = 0;
@@ -648,53 +554,16 @@ nsMultiMixedConv::OnDataAvailable(nsIReq
         nsAutoCString firstBuffer(buffer, bufLen);
         int32_t posCR = firstBuffer.Find("\r");
 
         if (needMoreChars || (posCR == kNotFound)) {
             // we don't have enough data yet to make this comparison.
             // skip this check, and try again the next time OnData()
             // is called.
             mFirstOnData = true;
-        } else if (mPackagedApp) {
-            // We need to check the line starts with --
-            if (!StringBeginsWith(firstBuffer, NS_LITERAL_CSTRING("--"))) {
-                char* tokenPos = ProbeToken(buffer, mTokenLen);
-                if (!tokenPos) {
-                    // No token is found. We need more data.
-                    mFirstOnData = true;
-                } else {
-                    // Token is probed.
-                    mToken = Substring(tokenPos, mTokenLen);
-                    mPreamble = nsCString(Substring(buffer, tokenPos));
-
-                    // Push the cursor to the token so that the while loop below will
-                    // find token from the right position.
-                    cursor = tokenPos;
-
-                    // Update bufLen to exlude the preamble. Otherwise, the first
-                    // |SendData| would claim longer buffer length.
-                    bufLen -= mPreamble.Length();
-                }
-            } else {
-                // If the boundary was set in the header,
-                // we need to check it matches with the one in the file.
-                if (mTokenLen &&
-                    !StringBeginsWith(Substring(firstBuffer, 2), mToken)) {
-                    return NS_ERROR_FAILURE;
-                }
-
-                // Save the token.
-                if (!mTokenLen) {
-                    mToken = nsCString(Substring(firstBuffer, 2).BeginReading(),
-                                       posCR - 2);
-                    mTokenLen = mToken.Length();
-                }
-
-                cursor = buffer;
-            }
         } else if (!PL_strnstr(cursor, token, mTokenLen + 2)) {
             char *newBuffer = (char *) realloc(buffer, bufLen + mTokenLen + 1);
             if (!newBuffer)
                 return NS_ERROR_OUT_OF_MEMORY;
             buffer = newBuffer;
 
             memmove(buffer + mTokenLen + 1, buffer, bufLen);
             memcpy(buffer, token, mTokenLen);
@@ -704,33 +573,24 @@ nsMultiMixedConv::OnDataAvailable(nsIReq
 
             // need to reset cursor to the buffer again (bug 100595)
             cursor = buffer;
         }
     }
 
     char *token = nullptr;
 
-    // This may get initialized by ParseHeaders and the resulting
-    // HttpResponseHead will be passed to nsPartChannel by SendStart
-
     if (mProcessingHeaders) {
         // we were not able to process all the headers
         // for this "part" given the previous buffer given to 
         // us in the previous OnDataAvailable callback.
         bool done = false;
-        const char* originalCursor = cursor;
         rv = ParseHeaders(channel, cursor, bufLen, &done);
         if (NS_FAILED(rv)) return rv;
 
-        // Append the content to the original header.
-        if (cursor > originalCursor) {
-            mOriginalResponseHeader.Append(originalCursor, cursor - originalCursor);
-        }
-
         if (done) {
             mProcessingHeaders = false;
             rv = SendStart(channel);
             if (NS_FAILED(rv)) return rv;
         }
     }
 
     int32_t tokenLinefeed = 1;
@@ -759,25 +619,19 @@ nsMultiMixedConv::OnDataAvailable(nsIReq
         bufLen -= mTokenLen;
         tokenLinefeed = PushOverLine(token, bufLen);
 
         if (mNewPart) {
             // parse headers
             mNewPart = false;
             cursor = token;
             bool done = false;
-            const char* originalCursor = cursor;
             rv = ParseHeaders(channel, cursor, bufLen, &done);
             if (NS_FAILED(rv)) return rv;
 
-            // Append the content to the original header.
-            if (cursor > originalCursor) {
-                mOriginalResponseHeader.Append(originalCursor, cursor - originalCursor);
-            }
-
             if (done) {
                 rv = SendStart(channel);
                 if (NS_FAILED(rv)) return rv;
             }
             else {
                 // we haven't finished processing header info.
                 // we'll break out and try to process later.
                 mProcessingHeaders = true;
@@ -849,61 +703,33 @@ nsMultiMixedConv::OnStartRequest(nsIRequ
     mContext = ctxt;
 
     mFirstOnData = true;
     mTotalSent   = 0;
 
     nsCOMPtr<nsIChannel> channel = do_QueryInterface(request, &rv);
     if (NS_FAILED(rv)) return rv;
 
-    nsCOMPtr<nsICacheInfoChannel> cacheChan = do_QueryInterface(request);
-    if (cacheChan) {
-        cacheChan->IsFromCache(&mIsFromCache);
-    }
-
     // ask the HTTP channel for the content-type and extract the boundary from it.
     nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel, &rv);
     if (NS_SUCCEEDED(rv)) {
         rv = httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("content-type"), delimiter);
-        if (NS_FAILED(rv) && !mPackagedApp) {
+        if (NS_FAILED(rv)) {
             return rv;
         }
     } else {
         // try asking the channel directly
         rv = channel->GetContentType(delimiter);
-        if (NS_FAILED(rv) && !mPackagedApp) {
+        if (NS_FAILED(rv)) {
             return NS_ERROR_FAILURE;
         }
     }
 
-    // http://www.w3.org/TR/web-packaging/#streamable-package-format
-    // Although it is compatible with multipart/* this format does not require
-    // the boundary to be included in the header, as it can be ascertained from
-    // the content of the file.
-    if (delimiter.Find(NS_LITERAL_CSTRING(APPLICATION_PACKAGE)) != kNotFound) {
-        mPackagedApp = true;
-        mHasAppContentType = true;
-        mToken.Truncate();
-        mTokenLen = 0;
-    }
-
     bndry = strstr(delimiter.BeginWriting(), "boundary");
 
-    bool requestSucceeded = true;
-    if (httpChannel) {
-        httpChannel->GetRequestSucceeded(&requestSucceeded);
-    }
-
-    // If the package has the appropriate content type, or if it is a successful
-    // packaged app request, without the required content type, there's no need
-    // for a boundary to be included in this header.
-    if (!bndry && (mHasAppContentType || (mPackagedApp && requestSucceeded))) {
-        return NS_OK;
-    }
-
     if (!bndry) {
         return NS_ERROR_FAILURE;
     }
 
     bndry = strchr(bndry, '=');
     if (!bndry) return NS_ERROR_FAILURE;
 
     bndry++; // move past the equals sign
@@ -914,41 +740,29 @@ nsMultiMixedConv::OnStartRequest(nsIRequ
     nsAutoCString boundaryString(bndry);
     if (attrib) *attrib = ';';
 
     boundaryString.Trim(" \"");
 
     mToken = boundaryString;
     mTokenLen = boundaryString.Length();
 
-    if (mTokenLen == 0 && !mPackagedApp) {
+    if (mTokenLen == 0) {
         return NS_ERROR_FAILURE;
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsMultiMixedConv::OnStopRequest(nsIRequest *request, nsISupports *ctxt,
-                                nsresult aStatus) {
-
-    nsresult rv = NS_OK;
-
-    // We should definitely have found a token at this point. Not having one
-    // is clearly an error, so we need to pass it to the listener.
-    // However, since packaged apps usually have the boundary token at the
-    // begining of the content, if the package is served from the cache, and
-    // only metadata was saved for said package (meaning no content is available
-    // and `mFirstOnData` is true) then we wouldn't have a boundary even though
-    // no error has occured.
-    if (mToken.IsEmpty() &&
-        NS_SUCCEEDED(rv) && // don't hide channel error results
-        !(mPackagedApp && mIsFromCache && mFirstOnData)) {
-        aStatus = NS_ERROR_FAILURE;
-        rv = NS_ERROR_FAILURE;
+                                nsresult aStatus)
+{
+    if (mToken.IsEmpty()) { // no token, no love.
+        return NS_ERROR_FAILURE;
     }
 
     if (mPartChannel) {
         mPartChannel->SetIsLastPart();
 
         // we've already called SendStart() (which sets up the mPartChannel,
         // and fires an OnStart()) send any data left over, and then fire the stop.
         if (mBufLen > 0 && mBuffer) {
@@ -959,32 +773,26 @@ nsMultiMixedConv::OnStopRequest(nsIReque
             mBuffer = nullptr;
             mBufLen = 0;
         }
         (void) SendStop(aStatus);
     } else if (NS_FAILED(aStatus)) {
         // underlying data production problem. we should not be in
         // the middle of sending data. if we were, mPartChannel,
         // above, would have been true.
-        
+
         // if we send the start, the URI Loader's m_targetStreamListener, may
         // be pointing at us causing a nice stack overflow.  So, don't call 
         // OnStartRequest!  -  This breaks necko's semantecs. 
         //(void) mFinalListener->OnStartRequest(request, ctxt);
-        
-        (void) mFinalListener->OnStopRequest(request, ctxt, aStatus);
-    } else if (mIsFromCache && mFirstOnData) {
-        // `mFirstOnData` is true if the package's cache entry only holds
-        // metadata and no calls to OnDataAvailable are made.
-        // In this case we would not call OnStopRequest for any of the parts,
-        // so we need to call it here.
+
         (void) mFinalListener->OnStopRequest(request, ctxt, aStatus);
     }
 
-    return rv;
+    return NS_OK;
 }
 
 
 // nsMultiMixedConv methods
 nsMultiMixedConv::nsMultiMixedConv() :
   mCurrentPartID(0)
 {
     mTokenLen           = 0;
@@ -992,19 +800,16 @@ nsMultiMixedConv::nsMultiMixedConv() :
     mContentLength      = UINT64_MAX;
     mBuffer             = nullptr;
     mBufLen             = 0;
     mProcessingHeaders  = false;
     mByteRangeStart     = 0;
     mByteRangeEnd       = 0;
     mTotalSent          = 0;
     mIsByteRangeRequest = false;
-    mPackagedApp        = false;
-    mHasAppContentType  = false;
-    mIsFromCache        = false;
 }
 
 nsMultiMixedConv::~nsMultiMixedConv() {
     NS_ASSERTION(!mBuffer, "all buffered data should be gone");
     if (mBuffer) {
         free(mBuffer);
         mBuffer = nullptr;
     }
@@ -1024,19 +829,17 @@ nsMultiMixedConv::BufferData(char *aData
 }
 
 
 nsresult
 nsMultiMixedConv::SendStart(nsIChannel *aChannel) {
     nsresult rv = NS_OK;
 
     nsCOMPtr<nsIStreamListener> partListener(mFinalListener);
-    // For packaged apps that don't have a content type we want to just
-    // go ahead and serve them with an empty content type
-    if (mContentType.IsEmpty() && !mPackagedApp) {
+    if (mContentType.IsEmpty()) {
         mContentType.AssignLiteral(UNKNOWN_CONTENT_TYPE);
         nsCOMPtr<nsIStreamConverterService> serv =
             do_GetService(NS_STREAMCONVERTERSERVICE_CONTRACTID, &rv);
         if (NS_SUCCEEDED(rv)) {
             nsCOMPtr<nsIStreamListener> converter;
             rv = serv->AsyncConvertData(UNKNOWN_CONTENT_TYPE,
                                         "*/*",
                                         mFinalListener,
@@ -1061,26 +864,16 @@ nsMultiMixedConv::SendStart(nsIChannel *
         newChannel->InitializeByteRange(mByteRangeStart, mByteRangeEnd);
     }
 
     mTotalSent = 0;
 
     // Set up the new part channel...
     mPartChannel = newChannel;
 
-    // Pass preamble to the channel.
-    mPartChannel->SetPreamble(mPreamble);
-
-    // Pass original http header.
-    mPartChannel->SetOriginalResponseHeader(mOriginalResponseHeader);
-    mOriginalResponseHeader = EmptyCString();
-
-    // We pass the headers to the nsPartChannel
-    mPartChannel->SetResponseHead(mResponseHead.forget());
-
     rv = mPartChannel->SetContentType(mContentType);
     if (NS_FAILED(rv)) return rv;
 
     rv = mPartChannel->SetContentLength(mContentLength);
     if (NS_FAILED(rv)) return rv;
 
     mPartChannel->SetContentDisposition(mContentDisposition);
 
@@ -1178,23 +971,16 @@ nsMultiMixedConv::ParseHeaders(nsIChanne
     // NOTE: this data must be ascii.
     // NOTE: aPtr is NOT null terminated!
     nsresult rv = NS_OK;
     char *cursor = aPtr, *newLine = nullptr;
     uint32_t cursorLen = aLen;
     bool done = false;
     uint32_t lineFeedIncrement = 1;
 
-    // We only create an nsHttpResponseHead for packaged app channels
-    // It may already be initialized, from a previous call of ParseHeaders
-    // since the headers for a single part may come in more then one chunk
-    if (mPackagedApp && !mResponseHead) {
-        mResponseHead = new mozilla::net::nsHttpResponseHead();
-    }
-
     mContentLength = UINT64_MAX; // XXX what if we were already called?
     while (cursorLen && (newLine = (char *) memchr(cursor, nsCRT::LF, cursorLen))) {
         // adjust for linefeeds
         if ((newLine > cursor) && (newLine[-1] == nsCRT::CR) ) { // CRLF
             lineFeedIncrement = 2;
             newLine--;
         }
         else
@@ -1209,45 +995,29 @@ nsMultiMixedConv::ParseHeaders(nsIChanne
 
             done = true;
             break;
         }
 
         char tmpChar = *newLine;
         *newLine = '\0'; // cursor is now null terminated
 
-        if (mResponseHead) {
-            nsAutoCString tmpHeader(cursor);
-            mResponseHead->ParseHeaderLine(tmpHeader);
-        }
-
         char *colon = (char *) strchr(cursor, ':');
         if (colon) {
             *colon = '\0';
             nsAutoCString headerStr(cursor);
             headerStr.CompressWhitespace();
             *colon = ':';
 
             nsAutoCString headerVal(colon + 1);
             headerVal.CompressWhitespace();
 
             // examine header
             if (headerStr.LowerCaseEqualsLiteral("content-type")) {
                 mContentType = headerVal;
-
-                // If the HTTP channel doesn't have an application/package
-                // content type we still want to serve the resource, but with the
-                // "application/octet-stream" header, so we prevent execution of
-                // unsafe content
-                if (mPackagedApp && !mHasAppContentType) {
-                    mContentType = APPLICATION_OCTET_STREAM;
-                    mResponseHead->SetHeader(mozilla::net::nsHttp::Content_Type,
-                                             mContentType);
-                    mResponseHead->SetContentType(mContentType);
-                }
             } else if (headerStr.LowerCaseEqualsLiteral("content-length")) {
                 mContentLength = nsCRT::atoll(headerVal.get());
             } else if (headerStr.LowerCaseEqualsLiteral("content-disposition")) {
                 mContentDisposition = headerVal;
             } else if (headerStr.LowerCaseEqualsLiteral("set-cookie")) {
                 nsCOMPtr<nsIHttpChannelInternal> httpInternal =
                     do_QueryInterface(aChannel);
                 if (httpInternal) {
--- a/netwerk/streamconv/converters/nsMultiMixedConv.h
+++ b/netwerk/streamconv/converters/nsMultiMixedConv.h
@@ -9,17 +9,16 @@
 #include "nsIChannel.h"
 #include "nsString.h"
 #include "nsCOMPtr.h"
 #include "nsIByteRangeRequest.h"
 #include "nsILoadInfo.h"
 #include "nsIMultiPartChannel.h"
 #include "nsAutoPtr.h"
 #include "mozilla/Attributes.h"
-#include "nsIResponseHeadProvider.h"
 #include "nsHttpResponseHead.h"
 
 #define NS_MULTIMIXEDCONVERTER_CID                         \
 { /* 7584CE90-5B25-11d3-A175-0050041CAF44 */         \
     0x7584ce90,                                      \
     0x5b25,                                          \
     0x11d3,                                          \
     {0xa1, 0x75, 0x0, 0x50, 0x4, 0x1c, 0xaf, 0x44}       \
@@ -29,41 +28,37 @@
 // nsPartChannel is a "dummy" channel which represents an individual part of
 // a multipart/mixed stream...
 //
 // Instances on this channel are passed out to the consumer through the
 // nsIStreamListener interface.
 //
 class nsPartChannel final : public nsIChannel,
                             public nsIByteRangeRequest,
-                            public nsIResponseHeadProvider,
                             public nsIMultiPartChannel
 {
 public:
   nsPartChannel(nsIChannel *aMultipartChannel, uint32_t aPartID,
                 nsIStreamListener* aListener);
 
   void InitializeByteRange(int64_t aStart, int64_t aEnd);
   void SetIsLastPart() { mIsLastPart = true; }
-  void SetPreamble(const nsACString& aPreamble);
-  void SetOriginalResponseHeader(const nsACString& aOriginalResponseHeader);
   nsresult SendOnStartRequest(nsISupports* aContext);
   nsresult SendOnDataAvailable(nsISupports* aContext, nsIInputStream* aStream,
                                uint64_t aOffset, uint32_t aLen);
   nsresult SendOnStopRequest(nsISupports* aContext, nsresult aStatus);
   /* SetContentDisposition expects the full value of the Content-Disposition
    * header */
   void SetContentDisposition(const nsACString& aContentDispositionHeader);
   void SetResponseHead(mozilla::net::nsHttpResponseHead * head) { mResponseHead = head; }
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIREQUEST
   NS_DECL_NSICHANNEL
   NS_DECL_NSIBYTERANGEREQUEST
-  NS_DECL_NSIRESPONSEHEADPROVIDER
   NS_DECL_NSIMULTIPARTCHANNEL
 
 protected:
   ~nsPartChannel();
 
 protected:
   nsCOMPtr<nsIChannel>    mMultipartChannel;
   nsCOMPtr<nsIStreamListener> mListener;
@@ -83,21 +78,16 @@ protected:
 
   bool                    mIsByteRangeRequest;
   int64_t                 mByteRangeStart;
   int64_t                 mByteRangeEnd;
 
   uint32_t                mPartID; // unique ID that can be used to identify
                                    // this part of the multipart document
   bool                    mIsLastPart;
-
-  nsCString               mPreamble;
-
-  // The original http response header.
-  nsCString               mOriginalResponseHeader;
 };
 
 // The nsMultiMixedConv stream converter converts a stream of type "multipart/x-mixed-replace"
 // to it's subparts. There was some debate as to whether or not the functionality desired
 // when HTTP confronted this type required a stream converter. After all, this type really
 // prompts various viewer related actions rather than stream conversion. There simply needs
 // to be a piece in place that can strip out the multiple parts of a stream of this type, and 
 // "display" them accordingly.
@@ -147,17 +137,16 @@ protected:
     nsresult SendStart(nsIChannel *aChannel);
     nsresult SendStop(nsresult aStatus);
     nsresult SendData(char *aBuffer, uint32_t aLen);
     nsresult ParseHeaders(nsIChannel *aChannel, char *&aPtr,
                           uint32_t &aLen, bool *_retval);
     int32_t  PushOverLine(char *&aPtr, uint32_t &aLen);
     char *FindToken(char *aCursor, uint32_t aLen);
     nsresult BufferData(char *aData, uint32_t aLen);
-    char* ProbeToken(char* aBuffer, uint32_t& aTokenLen);
 
     // member data
     bool                mNewPart;        // Are we processing the beginning of a part?
     bool                mProcessingHeaders;
     nsCOMPtr<nsIStreamListener> mFinalListener; // this guy gets the converted data via his OnDataAvailable()
 
     nsCString           mToken;
     uint32_t            mTokenLen;
@@ -177,32 +166,11 @@ protected:
     // The following members are for tracking the byte ranges in
     // multipart/mixed content which specified the 'Content-Range:'
     // header...
     int64_t             mByteRangeStart;
     int64_t             mByteRangeEnd;
     bool                mIsByteRangeRequest;
 
     uint32_t            mCurrentPartID;
-
-    // If true, it means the packaged app had an "application/package" header
-    // Otherwise, we remove "Content-Type" headers from files in the package
-    bool                mHasAppContentType;
-    // This is true if the content-type is application/package
-    // Streamable packages don't require the boundary in the header
-    // as it can be ascertained from the package file.
-    bool                mPackagedApp;
-    nsAutoPtr<mozilla::net::nsHttpResponseHead> mResponseHead;
-    // It is necessary to know if the content is coming from the cache
-    // for packaged apps, in the case that only metadata is saved in the cache
-    // entry and OnDataAvailable never gets called.
-    bool                mIsFromCache;
-
-    // Preamble is defined as the ASCII-encoding string which appears before the
-    // first boundary. It's only supported by 'application/package' content type
-    // and requires the boundary is defined in the HTTP header.
-    nsCString           mPreamble;
-
-    // The original http response header of each subresource.
-    nsCString           mOriginalResponseHeader;
 };
 
 #endif /* __nsmultimixedconv__h__ */
deleted file mode 100644
--- a/netwerk/test/unit/test_multipart_streamconv_application_package.js
+++ /dev/null
@@ -1,304 +0,0 @@
-// Tests:
-//   test_multipart
-//     Loads the multipart file returned by contentHandler()
-//     The boundary is ascertained from the first line in the multipart file
-//   test_multipart_with_boundary
-//     Loads the multipart file returned by contentHandler_with_boundary()
-//     The boundary is given in the Content-Type headers, and is also present
-//     in the first line of the file.
-//   test_multipart_chunked_headers
-//     Tests that the headers are properly passed even when they come in multiple
-//     chunks (several calls to OnDataAvailable). It first passes the first 60
-//     characters, then the rest of the response.
-
-// testData.token - the multipart file's boundary
-// Call testData.getData() to get the file contents as a string
-
-// multipartListener
-//   - a listener that checks that the multipart file is correctly split into multiple parts
-
-// headerListener
-//   - checks that the headers for each part is set correctly
-
-Cu.import("resource://testing-common/httpd.js");
-Cu.import("resource://gre/modules/NetUtil.jsm");
-
-var httpserver = null;
-
-XPCOMUtils.defineLazyGetter(this, "uri", function() {
-  return "http://localhost:" + httpserver.identity.primaryPort;
-});
-
-function make_channel(url) {
-  return NetUtil.newChannel({uri: url, loadUsingSystemPrincipal: true});
-}
-
-function contentHandler(metadata, response)
-{
-  response.setHeader("Content-Type", 'application/package');
-  var body = testData.getData();
-  response.bodyOutputStream.write(body, body.length);
-}
-
-function contentHandler_with_boundary(metadata, response)
-{
-  response.setHeader("Content-Type", 'application/package; boundary="'+testData.token+'"');
-  var body = testData.getData();
-  response.bodyOutputStream.write(body, body.length);
-}
-
-function contentHandler_chunked_headers(metadata, response)
-{
-  response.setHeader("Content-Type", 'application/package');
-  var body = testData.getData();
-
-  response.bodyOutputStream.write(body.substring(0,60), 60);
-  response.processAsync();
-  do_timeout(5, function() {
-    response.bodyOutputStream.write(body.substring(60), body.length-60);
-    response.finish();
-  });
-}
-
-function contentHandler_type_missing(metadata, response)
-{
-  response.setHeader("Content-Type", 'text/plain');
-  var body = testData.getData();
-  response.bodyOutputStream.write(body, body.length);
-}
-
-function contentHandler_with_package_header(chunkSize, metadata, response)
-{
-  response.setHeader("Content-Type", 'application/package');
-  var body = testData.packageHeader + testData.getData();
-
-  response.bodyOutputStream.write(body.substring(0,chunkSize), chunkSize);
-  response.processAsync();
-  do_timeout(5, function() {
-    response.bodyOutputStream.write(body.substring(chunkSize), body.length-chunkSize);
-    response.finish();
-  });
-}
-
-var testData = {
-  packageHeader: 'manifest-signature: dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk\r\n',
-  content: [
-   { headers: ["Content-Location: /index.html", "Content-Type: text/html"], data: "<html>\r\n  <head>\r\n    <script src=\"/scripts/app.js\"></script>\r\n    ...\r\n  </head>\r\n  ...\r\n</html>\r\n", type: "text/html" },
-   { headers: ["Content-Location: /scripts/app.js", "Content-Type: text/javascript"], data: "module Math from '/scripts/helpers/math.js';\r\n...\r\n", type: "text/javascript" },
-   { headers: ["Content-Location: /scripts/helpers/math.js", "Content-Type: text/javascript"], data: "export function sum(nums) { ... }\r\n...\r\n", type: "text/javascript" }
-  ],
-  token : "gc0pJq0M:08jU534c0p",
-  getData: function() {
-    var str = "";
-    for (var i in this.content) {
-      str += "--" + this.token + "\r\n";
-      for (var j in this.content[i].headers) {
-        str += this.content[i].headers[j] + "\r\n";
-      }
-      str += "\r\n";
-      str += this.content[i].data + "\r\n";
-    }
-
-    str += "--" + this.token + "--";
-    return str;
-  }
-}
-
-function multipartListener(test, badContentType, shouldVerifyPackageHeader) {
-  this._buffer = "";
-  this.testNum = 0;
-  this.test = test;
-  this.numTests = this.test.content.length;
-  // If set to true, that means the package is missing the application/package
-  // content type. If so, resources will have their content type set to
-  // application/octet-stream
-  this.badContentType = badContentType == undefined ? false : badContentType;
-  this.shouldVerifyPackageHeader = shouldVerifyPackageHeader;
-}
-
-multipartListener.prototype.responseHandler = function(request, buffer) {
-    equal(buffer, this.test.content[this.testNum].data);
-    equal(request.QueryInterface(Ci.nsIChannel).contentType,
-          this.badContentType ? "application/octet-stream" : this.test.content[this.testNum].type);
-    if (++this.testNum == this.numTests) {
-      run_next_test();
-    }
-}
-
-multipartListener.prototype.QueryInterface = function(iid) {
-  if (iid.equals(Components.interfaces.nsIStreamListener) ||
-      iid.equals(Components.interfaces.nsIRequestObserver) ||
-      iid.equals(Components.interfaces.nsISupports))
-    return this;
-  throw Components.results.NS_ERROR_NO_INTERFACE;
-}
-
-multipartListener.prototype.onStartRequest = function(request, context) {
-  if (this.shouldVerifyPackageHeader) {
-    let partChannel = request.QueryInterface(Ci.nsIMultiPartChannel);
-    ok(!!partChannel, 'Should be multipart channel');
-    equal(partChannel.preamble, this.test.packageHeader);
-  }
-
-  this._buffer = "";
-  this.headerListener = new headerListener(this.test.content[this.testNum].headers, this.badContentType);
-  let headerProvider = request.QueryInterface(Ci.nsIResponseHeadProvider);
-  if (headerProvider) {
-    headerProvider.visitResponseHeaders(this.headerListener);
-  }
-
-  // Verify the original header if the request is a multipart channel.
-  let partChannel = request.QueryInterface(Ci.nsIMultiPartChannel);
-  if (partChannel) {
-    let originalHeader = this.test.content[this.testNum].headers.join("\r\n") + "\r\n\r\n";
-    equal(originalHeader, partChannel.originalResponseHeader, "Oringinal header check.");
-  }
-}
-
-multipartListener.prototype.onDataAvailable = function(request, context, stream, offset, count) {
-  try {
-    this._buffer = this._buffer.concat(read_stream(stream, count));
-  } catch (ex) {
-    do_throw("Error in onDataAvailable: " + ex);
-  }
-}
-
-multipartListener.prototype.onStopRequest = function(request, context, status) {
-  try {
-    equal(this.headerListener.index, this.test.content[this.testNum].headers.length);
-    this.responseHandler(request, this._buffer);
-  } catch (ex) {
-    do_throw("Error in closure function: " + ex);
-  }
-}
-
-function headerListener(headers, badContentType) {
-  this.expectedHeaders = headers;
-  this.badContentType = badContentType;
-  this.index = 0;
-}
-
-headerListener.prototype.QueryInterface = function(iid) {
-  if (iid.equals(Components.interfaces.nsIHttpHeaderVisitor) ||
-      iid.equals(Components.interfaces.nsISupports))
-    return this;
-  throw Components.results.NS_ERROR_NO_INTERFACE;
-}
-
-headerListener.prototype.visitHeader = function(header, value) {
-  ok(this.index <= this.expectedHeaders.length);
-  if (!this.badContentType)
-    equal(header + ": " + value, this.expectedHeaders[this.index]);
-  this.index++;
-}
-
-function test_multipart() {
-  var streamConv = Cc["@mozilla.org/streamConverters;1"]
-                     .getService(Ci.nsIStreamConverterService);
-  var conv = streamConv.asyncConvertData("application/package",
-           "*/*",
-           new multipartListener(testData),
-           null);
-
-  var chan = make_channel(uri + "/multipart");
-  chan.asyncOpen2(conv);
-}
-
-function test_multipart_with_boundary() {
-  var streamConv = Cc["@mozilla.org/streamConverters;1"]
-                     .getService(Ci.nsIStreamConverterService);
-  var conv = streamConv.asyncConvertData("application/package",
-           "*/*",
-           new multipartListener(testData),
-           null);
-
-  var chan = make_channel(uri + "/multipart2");
-  chan.asyncOpen2(conv);
-}
-
-function test_multipart_chunked_headers() {
-  var streamConv = Cc["@mozilla.org/streamConverters;1"]
-                     .getService(Ci.nsIStreamConverterService);
-  var conv = streamConv.asyncConvertData("application/package",
-           "*/*",
-           new multipartListener(testData),
-           null);
-
-  var chan = make_channel(uri + "/multipart3");
-  chan.asyncOpen2(conv);
-}
-
-function test_multipart_content_type_other() {
-  var streamConv = Cc["@mozilla.org/streamConverters;1"]
-                     .getService(Ci.nsIStreamConverterService);
-
-  var conv = streamConv.asyncConvertData("application/package",
-           "*/*",
-           new multipartListener(testData, true),
-           null);
-
-  var chan = make_channel(uri + "/multipart4");
-  chan.asyncOpen2(conv);
-}
-
-function test_multipart_package_header(aChunkSize) {
-  var streamConv = Cc["@mozilla.org/streamConverters;1"]
-                     .getService(Ci.nsIStreamConverterService);
-
-  var conv = streamConv.asyncConvertData("application/package",
-           "*/*",
-           new multipartListener(testData, false, true),
-           null);
-
-  var chan = make_channel(uri + "/multipart5_" + aChunkSize);
-  chan.asyncOpen2(conv);
-}
-
-// Bug 1212223 - Test multipart with package header and different chunk size.
-// Use explict function name to make the test case log more readable.
-
-function test_multipart_package_header_50() {
-  return test_multipart_package_header(50);
-}
-
-function test_multipart_package_header_100() {
-  return test_multipart_package_header(100);
-}
-
-function test_multipart_package_header_150() {
-  return test_multipart_package_header(150);
-}
-
-function test_multipart_package_header_200() {
-  return test_multipart_package_header(200);
-}
-
-function run_test()
-{
-  httpserver = new HttpServer();
-  httpserver.registerPathHandler("/multipart", contentHandler);
-  httpserver.registerPathHandler("/multipart2", contentHandler_with_boundary);
-  httpserver.registerPathHandler("/multipart3", contentHandler_chunked_headers);
-  httpserver.registerPathHandler("/multipart4", contentHandler_type_missing);
-
-  // Bug 1212223 - Test multipart with package header and different chunk size.
-  httpserver.registerPathHandler("/multipart5_50", contentHandler_with_package_header.bind(null, 50));
-  httpserver.registerPathHandler("/multipart5_100", contentHandler_with_package_header.bind(null, 100));
-  httpserver.registerPathHandler("/multipart5_150", contentHandler_with_package_header.bind(null, 150));
-  httpserver.registerPathHandler("/multipart5_200", contentHandler_with_package_header.bind(null, 200));
-
-  httpserver.start(-1);
-
-  run_next_test();
-}
-
-add_test(test_multipart);
-add_test(test_multipart_with_boundary);
-add_test(test_multipart_chunked_headers);
-add_test(test_multipart_content_type_other);
-
-// Bug 1212223 - Test multipart with package header and different chunk size.
-add_test(test_multipart_package_header_50);
-add_test(test_multipart_package_header_100);
-add_test(test_multipart_package_header_150);
-add_test(test_multipart_package_header_200);
--- a/netwerk/test/unit/xpcshell.ini
+++ b/netwerk/test/unit/xpcshell.ini
@@ -338,17 +338,16 @@ skip-if = os != "win"
 # Disabled on XP in bug 1190674 for intermittent failures
 skip-if = os == "android" || (os == "win" && (os_version == "5.1" || os_version == "5.2"))
 reason = bug 1190674
 firefox-appdir = browser
 [test_tls_server_multiple_clients.js]
 # The local cert service used by this test is not currently shipped on Android
 skip-if = os == "android"
 [test_1073747.js]
-[test_multipart_streamconv_application_package.js]
 [test_safeoutputstream_append.js]
 [test_suspend_channel_before_connect.js]
 [test_inhibit_caching.js]
 [test_dns_disable_ipv4.js]
 [test_dns_disable_ipv6.js]
 [test_bug1195415.js]
 [test_cookie_blacklist.js]
 [test_getHost.js]
--- a/uriloader/exthandler/ExternalHelperAppParent.cpp
+++ b/uriloader/exthandler/ExternalHelperAppParent.cpp
@@ -500,22 +500,10 @@ ExternalHelperAppParent::GetPartID(uint3
 }
 
 NS_IMETHODIMP
 ExternalHelperAppParent::GetIsLastPart(bool* aIsLastPart)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-NS_IMETHODIMP
-ExternalHelperAppParent::GetPreamble(nsACString & aPreamble)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-ExternalHelperAppParent::GetOriginalResponseHeader(nsACString & aOriginalResponseHeader)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
 } // namespace dom
 } // namespace mozilla