Backout Bug 477578 because it causes us to refcount atoms off the main thread.
authorKyle Huey <khuey@kylehuey.com>
Thu, 22 Sep 2011 10:43:11 -0400
changeset 78367 d300ffff0be707803e580744824c78348f0fcc96
parent 78366 502f2bd2c229164699421ad823d27e8d05b2426f
child 78368 518c3a56a5dadedc242d87aff40c2c243846bf8c
push id340
push userclegnitto@mozilla.com
push dateTue, 08 Nov 2011 22:56:33 +0000
treeherdermozilla-beta@f745dc151615 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs477578
milestone9.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backout Bug 477578 because it causes us to refcount atoms off the main thread.
netwerk/protocol/http/HttpBaseChannel.cpp
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/HttpChannelParent.cpp
netwerk/protocol/http/HttpChannelParent.h
netwerk/protocol/http/PHttpChannel.ipdl
netwerk/protocol/http/nsHttp.cpp
netwerk/protocol/http/nsHttp.h
netwerk/protocol/http/nsHttpAtomList.h
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/http/nsHttpHandler.cpp
netwerk/protocol/http/nsHttpRequestHead.cpp
netwerk/protocol/http/nsHttpRequestHead.h
netwerk/test/unit/test_bug477578.js
netwerk/test/unit/xpcshell.ini
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -771,46 +771,35 @@ HttpBaseChannel::nsContentEncodings::Pre
 
 //-----------------------------------------------------------------------------
 // HttpBaseChannel::nsIHttpChannel
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 HttpBaseChannel::GetRequestMethod(nsACString& aMethod)
 {
-  mRequestHead.Method()->ToUTF8String(aMethod);
+  aMethod = mRequestHead.Method();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HttpBaseChannel::SetRequestMethod(const nsACString& aMethod)
 {
   ENSURE_CALLED_BEFORE_ASYNC_OPEN();
 
-  nsCAutoString upperCaseMethod;
-  ToUpperCase(aMethod, upperCaseMethod);
+  const nsCString& flatMethod = PromiseFlatCString(aMethod);
 
   // Method names are restricted to valid HTTP tokens.
-  if (!nsHttp::IsValidToken(upperCaseMethod))
+  if (!nsHttp::IsValidToken(flatMethod))
     return NS_ERROR_INVALID_ARG;
 
-  nsCOMPtr<nsIAtom> atom = do_GetAtom(upperCaseMethod);
+  nsHttpAtom atom = nsHttp::ResolveAtom(flatMethod.get());
+  if (!atom)
+    return NS_ERROR_FAILURE;
 
-  // We've changed method names to case sensitive in bug 477578. Some
-  // methods are kept case insensitive to keep backward compatibility and
-  // to satisfy XMLHttpRequest specification which demands it.
-#define HTTP_METHOD_ATOM(name_, value_)
-#define HTTP_CASE_INSENSITIVE_METHOD_ATOM(name_, value_) \
-  if (nsHttp::name_ == atom) {} else
-#include "nsHttpAtomList.h"
-#undef HTTP_CASE_INSENSITIVE_METHOD_ATOM
-#undef HTTP_METHOD_ATOM
-  { // upper case atom doesn't match any case insensitive atom
-    atom = do_GetAtom(aMethod);
-  }
   mRequestHead.SetMethod(atom);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HttpBaseChannel::GetReferrer(nsIURI **referrer)
 {
   NS_ENSURE_ARG_POINTER(referrer);
@@ -1549,17 +1538,17 @@ HttpBaseChannel::SetupReplacementChannel
       if (uploadChannel2) {
         const char *ctype = mRequestHead.PeekHeader(nsHttp::Content_Type);
         if (!ctype)
           ctype = "";
         const char *clen  = mRequestHead.PeekHeader(nsHttp::Content_Length);
         PRInt64 len = clen ? nsCRT::atoll(clen) : -1;
         uploadChannel2->ExplicitSetUploadStream(
                                   mUploadStream, nsDependentCString(ctype), len,
-                                  nsAtomCString(mRequestHead.Method()),
+                                  nsDependentCString(mRequestHead.Method()),
                                   mUploadStreamHasHeaders);
       } else {
         if (mUploadStreamHasHeaders) {
           uploadChannel->SetUploadStream(mUploadStream, EmptyCString(),
                            -1);
         } else {
           const char *ctype =
             mRequestHead.PeekHeader(nsHttp::Content_Type);
@@ -1576,17 +1565,17 @@ HttpBaseChannel::SetupReplacementChannel
         }
       }
     }
     // since preserveMethod is true, we need to ensure that the appropriate 
     // request method gets set on the channel, regardless of whether or not 
     // we set the upload stream above. This means SetRequestMethod() will
     // be called twice if ExplicitSetUploadStream() gets called above.
 
-    httpChannel->SetRequestMethod(nsAtomCString(mRequestHead.Method()));
+    httpChannel->SetRequestMethod(nsDependentCString(mRequestHead.Method()));
   }
   // convey the referrer if one was used for this channel to the next one
   if (mReferrer)
     httpChannel->SetReferrer(mReferrer);
   // convey the mAllowPipelining flag
   httpChannel->SetAllowPipelining(mAllowPipelining);
   // convey the new redirection limit
   httpChannel->SetRedirectionLimit(mRedirectionLimit - 1);
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -1067,17 +1067,17 @@ HttpChannelChild::AsyncOpen(nsIStreamLis
   // The socket transport in the chrome process now holds a logical ref to us
   // until OnStopRequest, or we do a redirect, or we hit an IPDL error.
   AddIPDLReference();
 
   gNeckoChild->SendPHttpChannelConstructor(this, tabChild);
 
   SendAsyncOpen(IPC::URI(mURI), IPC::URI(mOriginalURI),
                 IPC::URI(mDocumentURI), IPC::URI(mReferrer), mLoadFlags,
-                mRequestHeaders, nsAtomCString(mRequestHead.Method()),
+                mRequestHeaders, mRequestHead.Method(),
                 IPC::InputStream(mUploadStream), mUploadStreamHasHeaders,
                 mPriority, mRedirectionLimit, mAllowPipelining,
                 mForceAllowThirdPartyCookie, mSendResumeAt,
                 mStartPos, mEntityID, mChooseApplicationCache, 
                 appCacheClientId);
 
   return NS_OK;
 }
--- a/netwerk/protocol/http/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/HttpChannelParent.cpp
@@ -127,17 +127,17 @@ HttpChannelParent::GetInterface(const ns
 
 bool 
 HttpChannelParent::RecvAsyncOpen(const IPC::URI&            aURI,
                                  const IPC::URI&            aOriginalURI,
                                  const IPC::URI&            aDocURI,
                                  const IPC::URI&            aReferrerURI,
                                  const PRUint32&            loadFlags,
                                  const RequestHeaderTuples& requestHeaders,
-                                 const nsCString&           requestMethod,
+                                 const nsHttpAtom&          requestMethod,
                                  const IPC::InputStream&    uploadStream,
                                  const PRBool&              uploadStreamHasHeaders,
                                  const PRUint16&            priority,
                                  const PRUint8&             redirectionLimit,
                                  const PRBool&              allowPipelining,
                                  const PRBool&              forceAllowThirdPartyCookie,
                                  const bool&                doResumeAt,
                                  const PRUint64&            startPos,
@@ -185,17 +185,17 @@ HttpChannelParent::RecvAsyncOpen(const I
                                requestHeaders[i].mMerge);
   }
 
   nsRefPtr<HttpChannelParentListener> channelListener =
       new HttpChannelParentListener(this);
 
   httpChan->SetNotificationCallbacks(channelListener);
 
-  httpChan->SetRequestMethod(requestMethod);
+  httpChan->SetRequestMethod(nsDependentCString(requestMethod.get()));
 
   nsCOMPtr<nsIInputStream> stream(uploadStream);
   if (stream) {
     httpChan->InternalSetUploadStream(stream);
     httpChan->SetUploadStreamHasHeaders(uploadStreamHasHeaders);
   }
 
   if (priority != nsISupportsPriority::PRIORITY_NORMAL)
--- a/netwerk/protocol/http/HttpChannelParent.h
+++ b/netwerk/protocol/http/HttpChannelParent.h
@@ -81,17 +81,17 @@ public:
 
 protected:
   virtual bool RecvAsyncOpen(const IPC::URI&            uri,
                              const IPC::URI&            originalUri,
                              const IPC::URI&            docUri,
                              const IPC::URI&            referrerUri,
                              const PRUint32&            loadFlags,
                              const RequestHeaderTuples& requestHeaders,
-                             const nsCString&           requestMethod,
+                             const nsHttpAtom&          requestMethod,
                              const IPC::InputStream&    uploadStream,
                              const PRBool&              uploadStreamHasHeaders,
                              const PRUint16&            priority,
                              const PRUint8&             redirectionLimit,
                              const PRBool&              allowPipelining,
                              const PRBool&              forceAllowThirdPartyCookie,
                              const bool&                doResumeAt,
                              const PRUint64&            startPos,
--- a/netwerk/protocol/http/PHttpChannel.ipdl
+++ b/netwerk/protocol/http/PHttpChannel.ipdl
@@ -42,16 +42,17 @@
 include protocol PNecko;
 
 include "mozilla/net/PHttpChannelParams.h";
 include "mozilla/net/NeckoMessageUtils.h";
 include "prio.h";
 
 using RequestHeaderTuples;
 using nsHttpResponseHead;
+using nsHttpAtom;
 using IPC::URI;
 using IPC::InputStream;
 using PRNetAddr;
 
 namespace mozilla {
 namespace net {
 
 //-------------------------------------------------------------------
@@ -64,17 +65,17 @@ parent:
             // - TODO: bug 571161: unclear if any HTTP channel clients ever
             // set originalURI != uri (about:credits?); also not clear if
             // chrome channel would ever need to know.  Get rid of next arg?
             URI                 original,
             URI                 doc,
             URI                 referrer,
             PRUint32            loadFlags,
             RequestHeaderTuples requestHeaders,
-            nsCString           requestMethod,
+            nsHttpAtom          requestMethod,
             InputStream         uploadStream,
             PRBool              uploadStreamHasHeaders,
             PRUint16            priority,
             PRUint8             redirectionLimit,
             PRBool              allowPipelining,
             PRBool              forceAllowThirdPartyCookie,
             bool                resumeAt,
             PRUint64            startPos,
--- a/netwerk/protocol/http/nsHttp.cpp
+++ b/netwerk/protocol/http/nsHttp.cpp
@@ -37,17 +37,16 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsHttp.h"
 #include "pldhash.h"
 #include "mozilla/Mutex.h"
 #include "nsCRT.h"
 #include "prbit.h"
-#include "nsStaticAtom.h"
 
 #if defined(PR_LOGGING)
 PRLogModuleInfo *gHttpLog = nsnull;
 #endif
 
 // define storage for all atoms
 #define HTTP_ATOM(_name, _value) nsHttpAtom nsHttp::_name = { _value };
 #include "nsHttpAtomList.h"
@@ -56,33 +55,16 @@ PRLogModuleInfo *gHttpLog = nsnull;
 // find out how many atoms we have
 #define HTTP_ATOM(_name, _value) Unused_ ## _name,
 enum {
 #include "nsHttpAtomList.h"
     NUM_HTTP_ATOMS
 };
 #undef HTTP_ATOM
 
-// define all method atoms
-#define HTTP_METHOD_ATOM(name_, value_) nsIAtom* nsHttp::name_;
-#include "nsHttpAtomList.h"
-#undef HTTP_METHOD_ATOM
-
-#define HTTP_METHOD_ATOM(name_, value_) \
-    NS_STATIC_ATOM_BUFFER(name_##_buffer, value_)
-#include "nsHttpAtomList.h"
-#undef HTTP_METHOD_ATOM
-
-static const nsStaticAtom methodAtomsInfo[] = {
-#define HTTP_METHOD_ATOM(name_, value_) \
-    NS_STATIC_ATOM(name_##_buffer, &nsHttp::name_),
-#include "nsHttpAtomList.h"
-#undef HTTP_METHOD_ATOM
-};
-
 using namespace mozilla;
 
 // we keep a linked list of atoms allocated on the heap for easy clean up when
 // the atom table is destroyed.  The structure and value string are allocated
 // as one contiguous block.
 
 struct HttpHeapAtom {
     struct HttpHeapAtom *next;
@@ -197,22 +179,16 @@ nsHttp::DestroyAtomTable()
     }
 
     if (sLock) {
         delete sLock;
         sLock = nsnull;
     }
 }
 
-void
-nsHttp::CreateMethodAtoms()
-{
-    NS_RegisterStaticAtoms(methodAtomsInfo, NS_ARRAY_LENGTH(methodAtomsInfo));
-}
-
 // this function may be called from multiple threads
 nsHttpAtom
 nsHttp::ResolveAtom(const char *str)
 {
     nsHttpAtom atom = { nsnull };
 
     if (!str || !sAtomTable.ops)
         return atom;
--- a/netwerk/protocol/http/nsHttp.h
+++ b/netwerk/protocol/http/nsHttp.h
@@ -62,17 +62,16 @@
 
 #include "plstr.h"
 #include "prlog.h"
 #include "prtime.h"
 #include "nsISupportsUtils.h"
 #include "nsPromiseFlatString.h"
 #include "nsURLHelper.h"
 #include "netCore.h"
-#include "nsIAtom.h"
 
 #if defined(PR_LOGGING)
 //
 // Log module for HTTP Protocol logging...
 //
 // To enable logging (see prlog.h for full details):
 //
 //    set NSPR_LOG_MODULES=nsHttp:5
@@ -160,18 +159,16 @@ struct nsHttpAtom
     const char *_val;
 };
 
 struct nsHttp
 {
     static nsresult CreateAtomTable();
     static void DestroyAtomTable();
 
-    static void CreateMethodAtoms();
-
     // will dynamically add atoms to the table if they don't already exist
     static nsHttpAtom ResolveAtom(const char *);
     static nsHttpAtom ResolveAtom(const nsACString &s)
     {
         return ResolveAtom(PromiseFlatCString(s).get());
     }
 
     // returns true if the specified token [start,end) is valid per RFC 2616
@@ -213,20 +210,16 @@ struct nsHttp
     // 
     // The atom names and values are stored in nsHttpAtomList.h and are brought
     // to you by the magic of C preprocessing.  Add new atoms to nsHttpAtomList
     // and all support logic will be auto-generated.
     //
 #define HTTP_ATOM(_name, _value) static nsHttpAtom _name;
 #include "nsHttpAtomList.h"
 #undef HTTP_ATOM
-
-#define HTTP_METHOD_ATOM(_name, _value) static nsIAtom* _name;
-#include "nsHttpAtomList.h"
-#undef HTTP_METHOD_ATOM
 };
 
 //-----------------------------------------------------------------------------
 // utilities...
 //-----------------------------------------------------------------------------
 
 static inline PRUint32
 PRTimeToSeconds(PRTime t_usec)
--- a/netwerk/protocol/http/nsHttpAtomList.h
+++ b/netwerk/protocol/http/nsHttpAtomList.h
@@ -45,17 +45,16 @@
 
   All entries must be enclosed in the macro HTTP_ATOM which will have cruel
   and unusual things done to it.
 
   The first argument to HTTP_ATOM is the C++ name of the atom.
   The second argument to HTTP_ATOM is the string value of the atom.
  ******/
 
-#if defined(HTTP_ATOM)
 HTTP_ATOM(Accept,                    "Accept")
 HTTP_ATOM(Accept_Encoding,           "Accept-Encoding")
 HTTP_ATOM(Accept_Language,           "Accept-Language")
 HTTP_ATOM(Accept_Ranges,             "Accept-Ranges")
 HTTP_ATOM(Age,                       "Age")
 HTTP_ATOM(Allow,                     "Allow")
 HTTP_ATOM(Authentication,            "Authentication")
 HTTP_ATOM(Authorization,             "Authorization")
@@ -119,45 +118,31 @@ HTTP_ATOM(Trailer,                   "Tr
 HTTP_ATOM(Transfer_Encoding,         "Transfer-Encoding")
 HTTP_ATOM(URI,                       "URI")
 HTTP_ATOM(Upgrade,                   "Upgrade")
 HTTP_ATOM(User_Agent,                "User-Agent")
 HTTP_ATOM(Vary,                      "Vary")
 HTTP_ATOM(Version,                   "Version")
 HTTP_ATOM(WWW_Authenticate,          "WWW-Authenticate")
 HTTP_ATOM(Warning,                   "Warning")
-#endif
 
 // methods are atoms too.
 //
 // Note: winnt.h defines DELETE macro, so we'll just keep the methods mixedcase
 // even though they're normally written all uppercase. -- darin
 
-#if defined(HTTP_METHOD_ATOM)
-
-#if !defined(HTTP_CASE_INSENSITIVE_METHOD_ATOM)
-#define HTTP_CASE_INSENSITIVE_METHOD_ATOM HTTP_METHOD_ATOM
-#define UNDEF_HTTP_CASE_INSENSITIVE_METHOD_ATOM
-#endif
-HTTP_CASE_INSENSITIVE_METHOD_ATOM(Connect,   "CONNECT")
-HTTP_METHOD_ATOM                 (Copy,      "COPY")
-HTTP_CASE_INSENSITIVE_METHOD_ATOM(Delete,    "DELETE")
-HTTP_CASE_INSENSITIVE_METHOD_ATOM(Get,       "GET")
-HTTP_CASE_INSENSITIVE_METHOD_ATOM(Head,      "HEAD")
-HTTP_METHOD_ATOM                 (Index,     "INDEX")
-HTTP_METHOD_ATOM                 (Lock,      "LOCK")
-HTTP_METHOD_ATOM                 (M_Post,    "M-POST")
-HTTP_METHOD_ATOM                 (Mkcol,     "MKCOL")
-HTTP_METHOD_ATOM                 (Move,      "MOVE")
-HTTP_CASE_INSENSITIVE_METHOD_ATOM(Options,   "OPTIONS")
-HTTP_CASE_INSENSITIVE_METHOD_ATOM(Post,      "POST")
-HTTP_METHOD_ATOM                 (Propfind,  "PROPFIND")
-HTTP_METHOD_ATOM                 (Proppatch, "PROPPATCH")
-HTTP_CASE_INSENSITIVE_METHOD_ATOM(Put,       "PUT")
-HTTP_CASE_INSENSITIVE_METHOD_ATOM(Trace,     "TRACE")
-HTTP_CASE_INSENSITIVE_METHOD_ATOM(Track,     "TRACK")
-HTTP_METHOD_ATOM                 (Unlock,    "UNLOCK")
-#if defined(UNDEF_HTTP_CASE_INSENSITIVE_METHOD_ATOM)
-#undef UNDEF_HTTP_CASE_INSENSITIVE_METHOD_ATOM
-#undef HTTP_CASE_INSENSITIVE_METHOD_ATOM
-#endif
-
-#endif
+HTTP_ATOM(Connect,                   "CONNECT")
+HTTP_ATOM(Copy,                      "COPY")
+HTTP_ATOM(Delete,                    "DELETE")
+HTTP_ATOM(Get,                       "GET")
+HTTP_ATOM(Head,                      "HEAD")
+HTTP_ATOM(Index,                     "INDEX")
+HTTP_ATOM(Lock,                      "LOCK")
+HTTP_ATOM(M_Post,                    "M-POST")
+HTTP_ATOM(Mkcol,                     "MKCOL")
+HTTP_ATOM(Move,                      "MOVE")
+HTTP_ATOM(Options,                   "OPTIONS")
+HTTP_ATOM(Post,                      "POST")
+HTTP_ATOM(Propfind,                  "PROPFIND")
+HTTP_ATOM(Proppatch,                 "PROPPATCH")
+HTTP_ATOM(Put,                       "PUT")
+HTTP_ATOM(Trace,                     "TRACE")
+HTTP_ATOM(Unlock,                    "UNLOCK")
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -2447,19 +2447,17 @@ nsHttpChannel::CheckCache()
         return NS_OK;
 
     nsXPIDLCString buf;
 
     // Get the method that was used to generate the cached response
     rv = mCacheEntry->GetMetaDataElement("request-method", getter_Copies(buf));
     NS_ENSURE_SUCCESS(rv, rv);
 
-    nsCOMPtr<nsIAtom> method = do_GetAtom(buf);
-    NS_ENSURE_TRUE(method, NS_ERROR_OUT_OF_MEMORY);
-
+    nsHttpAtom method = nsHttp::ResolveAtom(buf);
     if (method == nsHttp::Head) {
         // The cached response does not contain an entity.  We can only reuse
         // the response if the current request is also HEAD.
         if (mRequestHead.Method() != nsHttp::Head)
             return NS_OK;
     }
     buf.Adopt(0);
 
@@ -3019,17 +3017,17 @@ nsHttpChannel::AddCacheEntryHeaders(nsIC
     LOG(("nsHttpChannel::AddCacheEntryHeaders [this=%x] begin", this));
     // Store secure data in memory only
     if (mSecurityInfo)
         entry->SetSecurityInfo(mSecurityInfo);
 
     // Store the HTTP request method with the cache entry so we can distinguish
     // for example GET and HEAD responses.
     rv = entry->SetMetaDataElement("request-method",
-                                   nsAtomCString(mRequestHead.Method()).get());
+                                   mRequestHead.Method().get());
     if (NS_FAILED(rv)) return rv;
 
     // Store the HTTP authorization scheme used if any...
     rv = StoreAuthorizationMetaData(entry);
     if (NS_FAILED(rv)) return rv;
 
     // Iterate over the headers listed in the Vary response header, and
     // store the value of the corresponding request header so we can verify
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -233,18 +233,16 @@ nsHttpHandler::Init()
     nsresult rv;
 
     LOG(("nsHttpHandler::Init\n"));
 
     rv = nsHttp::CreateAtomTable();
     if (NS_FAILED(rv))
         return rv;
 
-    nsHttp::CreateMethodAtoms();
-
     mIOService = do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
     if (NS_FAILED(rv)) {
         NS_WARNING("unable to continue without io service");
         return rv;
     }
 
     if (IsNeckoChild())
         NeckoChild::InitNeckoChild();
--- a/netwerk/protocol/http/nsHttpRequestHead.cpp
+++ b/netwerk/protocol/http/nsHttpRequestHead.cpp
@@ -42,17 +42,17 @@
 // nsHttpRequestHead
 //-----------------------------------------------------------------------------
 
 void
 nsHttpRequestHead::Flatten(nsACString &buf, PRBool pruneProxyHeaders)
 {
     // note: the first append is intentional.
  
-    buf.Append(nsAtomCString(mMethod));
+    buf.Append(mMethod.get());
     buf.Append(' ');
     buf.Append(mRequestURI);
     buf.AppendLiteral(" HTTP/");
 
     switch (mVersion) {
     case NS_HTTP_VERSION_1_1:
         buf.AppendLiteral("1.1");
         break;
--- a/netwerk/protocol/http/nsHttpRequestHead.h
+++ b/netwerk/protocol/http/nsHttpRequestHead.h
@@ -50,36 +50,36 @@
 //-----------------------------------------------------------------------------
 
 class nsHttpRequestHead
 {
 public:
     nsHttpRequestHead() : mMethod(nsHttp::Get), mVersion(NS_HTTP_VERSION_1_1) {}
     ~nsHttpRequestHead() {}
 
-    void SetMethod(nsIAtom *method) { mMethod = method; }
+    void SetMethod(nsHttpAtom method) { mMethod = method; }
     void SetVersion(nsHttpVersion version) { mVersion = version; }
     void SetRequestURI(const nsCSubstring &s) { mRequestURI = s; }
 
     nsHttpHeaderArray  &Headers()    { return mHeaders; }
-    nsIAtom            *Method()     { return mMethod; }
+    nsHttpAtom          Method()     { return mMethod; }
     nsHttpVersion       Version()    { return mVersion; }
     const nsCSubstring &RequestURI() { return mRequestURI; }
 
     const char *PeekHeader(nsHttpAtom h)                                     { return mHeaders.PeekHeader(h); }
     nsresult SetHeader(nsHttpAtom h, const nsACString &v, PRBool m=PR_FALSE) { return mHeaders.SetHeader(h, v, m); }
     nsresult GetHeader(nsHttpAtom h, nsACString &v)                          { return mHeaders.GetHeader(h, v); }
     void ClearHeader(nsHttpAtom h)                                           { mHeaders.ClearHeader(h); }
     void ClearHeaders()                                                      { mHeaders.Clear(); }
 
     const char *FindHeaderValue(nsHttpAtom h, const char *v) { return mHeaders.FindHeaderValue(h, v); }
     PRBool      HasHeaderValue(nsHttpAtom h, const char *v) { return mHeaders.HasHeaderValue(h, v); }
 
     void Flatten(nsACString &, PRBool pruneProxyHeaders = PR_FALSE);
 
 private:
     nsHttpHeaderArray mHeaders;
-    nsCOMPtr<nsIAtom> mMethod;
+    nsHttpAtom        mMethod;
     nsHttpVersion     mVersion;
     nsCString         mRequestURI;
 };
 
 #endif // nsHttpRequestHead_h__
deleted file mode 100644
--- a/netwerk/test/unit/test_bug477578.js
+++ /dev/null
@@ -1,42 +0,0 @@
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-
-const testMethods = [
-  ["get", "GET"],
-  ["post", "POST"],
-  ["head", "HEAD"],
-  ["put", "PUT"],
-  ["delete", "DELETE"],
-  ["connect", "CONNECT"],
-  ["options", "OPTIONS"],
-  ["trace", "TRACE"],
-  ["track", "TRACK"],
-  ["copy", "copy"],
-  ["index", "index"],
-  ["lock", "lock"],
-  ["m-post", "m-post"],
-  ["mkcol", "mkcol"],
-  ["move", "move"],
-  ["propfind", "propfind"],
-  ["proppatch", "proppatch"],
-  ["unlock", "unlock"],
-  ["link", "link"],
-  ["foo", "foo"],
-  ["foO", "foO"],
-  ["fOo", "fOo"],
-  ["Foo", "Foo"]
-]
-
-function run_test() {
-  var ios =
-    Cc["@mozilla.org/network/io-service;1"].
-    getService(Ci.nsIIOService);
-
-  var chan = ios.newChannel("http://localhost/", null, null)
-                  .QueryInterface(Components.interfaces.nsIHttpChannel);
-
-  for (var i = 0; i < testMethods.length; i++) {
-    chan.requestMethod = testMethods[i][0];
-    do_check_eq(chan.requestMethod, testMethods[i][1]);
-  }
-}
--- a/netwerk/test/unit/xpcshell.ini
+++ b/netwerk/test/unit/xpcshell.ini
@@ -40,17 +40,16 @@ skip-if = os == "android"
 [test_bug429347.js]
 [test_bug455311.js]
 [test_bug455598.js]
 [test_bug468426.js]
 # Bug 675039: test hangs consistently on Android 
 skip-if = os == "android"
 [test_bug468594.js]
 [test_bug470716.js]
-[test_bug477578.js]
 [test_bug479413.js]
 [test_bug479485.js]
 [test_bug482601.js]
 [test_bug484684.js]
 [test_bug490095.js]
 [test_bug504014.js]
 [test_bug510359.js]
 # Bug 675039: test hangs consistently on Android