// nsIRequestObserver implementation NS_IMETHODIMP nsMultiMixedConv::OnStartRequest(nsIRequest *request, nsISupports *ctxt) { // we're assuming the content-type is available at this stage NS_ASSERTION(mToken.IsEmpty(), "a second on start???"); const char *bndry = nullptr; nsAutoCString delimiter; nsresult rv = NS_OK; mContext = ctxt; mFirstOnData = true; mTotalSent = 0; nsCOMPtr<nsIChannel> channel = do_QueryInterface(request, &rv); if (NS_FAILED(rv)) return rv; // 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)) return rv; } else { // try asking the channel directly rv = channel->GetContentType(delimiter); if (NS_FAILED(rv)) return NS_ERROR_FAILURE; } bndry = strstr(delimiter.BeginWriting(), "boundary"); if (!bndry) return NS_ERROR_FAILURE; bndry = strchr(bndry, '='); if (!bndry) return NS_ERROR_FAILURE; bndry++; // move past the equals sign char *attrib = (char *) strchr(bndry, ';'); if (attrib) *attrib = '\0'; nsAutoCString boundaryString(bndry); if (attrib) *attrib = ';'; boundaryString.Trim(" \""); mToken = boundaryString; mTokenLen = boundaryString.Length(); if (mTokenLen == 0) return NS_ERROR_FAILURE; return NS_OK; }
// nsIRequestObserver implementation NS_IMETHODIMP nsMultiMixedConv::OnStartRequest(nsIRequest *request, nsISupports *ctxt) { // we're assuming the content-type is available at this stage NS_ASSERTION(mToken.IsEmpty(), "a second on start???"); const char *bndry = nullptr; nsAutoCString delimiter; nsresult rv = NS_OK; mContext = ctxt; mFirstOnData = true; mTotalSent = 0; nsCOMPtr<nsIChannel> channel = do_QueryInterface(request, &rv); if (NS_FAILED(rv)) return rv; // 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)) return rv; } else { // try asking the channel directly rv = channel->GetContentType(delimiter); 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("application/package") != kNotFound) { mPackagedApp = true; mToken.Truncate(); mTokenLen = 0; } bndry = strstr(delimiter.BeginWriting(), "boundary"); if (!bndry && mPackagedApp) { return NS_OK; } if (!bndry) { return NS_ERROR_FAILURE; } bndry = strchr(bndry, '='); if (!bndry) return NS_ERROR_FAILURE; bndry++; // move past the equals sign char *attrib = (char *) strchr(bndry, ';'); if (attrib) *attrib = '\0'; nsAutoCString boundaryString(bndry); if (attrib) *attrib = ';'; boundaryString.Trim(" \""); mToken = boundaryString; mTokenLen = boundaryString.Length(); if (mTokenLen == 0 && !mPackagedApp) { return NS_ERROR_FAILURE; } return NS_OK; }