Changeset 2698


Ignore:
Timestamp:
5/25/2012 3:59:10 AM (2 years ago)
Author:
lowjoel
Message:

Factor out the HTTP Protocol handling stuff to a separate QueryServer? function which will handle the wet work.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/eraser/Eraser.BlackBox/BlackBoxReportUploader.cs

    r2696 r2698  
    9090 
    9191        /// <summary> 
    92         /// Gets from the server based on the stack trace whether this report is 
    93         /// new. 
     92        /// Gets from the server based on the stack trace whether this report has been 
     93        /// submitted before. 
    9494        /// </summary> 
    9595        public bool IsNew 
     
    9797            get 
    9898            { 
     99                //Get the status from the server. 
     100                XmlDocument result = QueryServer("status", true); 
     101                 
     102                //Parse the result document 
     103                XmlNode node = result.SelectSingleNode("/crashReport"); 
     104                string reportStatus = node.Attributes.GetNamedItem("status").Value; 
     105                switch (reportStatus) 
     106                { 
     107                    case "exists": 
     108                        return false; 
     109 
     110                    case "new": 
     111                        return true; 
     112 
     113                    default: 
     114                        throw new InvalidDataException( 
     115                            "Unknown crash report server response."); 
     116                } 
     117            } 
     118        } 
     119 
     120        /// <summary> 
     121        /// Compresses the report for uploading. 
     122        /// </summary> 
     123        /// <param name="progress">The <see cref="ProgressManager"/> instance that the 
     124        /// Upload function is using.</param> 
     125        /// <param name="progressChanged">The progress changed event handler that should 
     126        /// be called for upload progress updates.</param> 
     127        private void Compress(SteppedProgressManager progress, 
     128            ProgressChangedEventHandler progressChanged) 
     129        { 
     130            using (FileStream archiveStream = new FileStream(ReportBaseName + ".tar", 
     131                    FileMode.Create, FileAccess.Write)) 
     132            { 
     133                //Add the report into a tar file 
     134                TarArchive archive = TarArchive.CreateOutputTarArchive(archiveStream); 
     135                foreach (FileInfo file in Report.Files) 
     136                { 
     137                    TarEntry entry = TarEntry.CreateEntryFromFile(file.FullName); 
     138                    entry.Name = Path.GetFileName(entry.Name); 
     139                    archive.WriteEntry(entry, false); 
     140                } 
     141                archive.Close(); 
     142            } 
     143 
     144            ProgressManager step = new ProgressManager(); 
     145            progress.Steps.Add(new SteppedProgressManagerStep(step, 0.5f, "Compressing")); 
     146            CoderPropID[] propIDs =  
     147                { 
     148                    CoderPropID.DictionarySize, 
     149                    CoderPropID.PosStateBits, 
     150                    CoderPropID.LitContextBits, 
     151                    CoderPropID.LitPosBits, 
     152                    CoderPropID.Algorithm, 
     153                    CoderPropID.NumFastBytes, 
     154                    CoderPropID.MatchFinder, 
     155                    CoderPropID.EndMarker 
     156                }; 
     157            object[] properties =  
     158                { 
     159                    (Int32)(1 << 24),           //Dictionary Size 
     160                    (Int32)2,                   //PosState Bits 
     161                    (Int32)0,                   //LitContext Bits 
     162                    (Int32)2,                   //LitPos Bits 
     163                    (Int32)2,                   //Algorithm 
     164                    (Int32)128,                 //Fast Bytes 
     165                    "bt4",                      //Match Finger 
     166                    true                        //Write end-of-stream 
     167                }; 
     168 
     169            SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compression.LZMA.Encoder(); 
     170            encoder.SetCoderProperties(propIDs, properties); 
     171 
     172            using (FileStream sevenZipFile = new FileStream(ReportBaseName + ".tar.7z", 
     173                FileMode.Create)) 
     174            using (FileStream tarStream = new FileStream(ReportBaseName + ".tar", 
     175                FileMode.Open, FileAccess.Read, FileShare.Read, 262144, FileOptions.DeleteOnClose)) 
     176            { 
     177                encoder.WriteCoderProperties(sevenZipFile); 
     178                Int64 fileSize = -1; 
     179                for (int i = 0; i < 8; i++) 
     180                    sevenZipFile.WriteByte((Byte)(fileSize >> (8 * i))); 
     181 
     182                step.Total = tarStream.Length; 
     183                ICodeProgress callback = progressChanged == null ? null : 
     184                    new SevenZipProgressCallback(this, progress, step, progressChanged); 
     185                encoder.Code(tarStream, sevenZipFile, -1, -1, callback); 
     186            } 
     187        } 
     188 
     189        /// <summary> 
     190        /// Compresses the report, then uploads it to the server. 
     191        /// </summary> 
     192        /// <param name="progressChanged">The progress changed event handler that should 
     193        /// be called for upload progress updates.</param> 
     194        public void Submit(ProgressChangedEventHandler progressChanged) 
     195        { 
     196            SteppedProgressManager overallProgress = new SteppedProgressManager(); 
     197            Compress(overallProgress, progressChanged); 
     198 
     199            using (FileStream bzipFile = new FileStream(ReportBaseName + ".tar.7z", 
     200                FileMode.Open, FileAccess.Read, FileShare.Read, 131072, FileOptions.DeleteOnClose)) 
     201            using (Stream logFile = Report.DebugLog) 
     202            { 
     203                //Build the POST request 
    99204                PostDataBuilder builder = new PostDataBuilder(); 
    100                 builder.AddPart(new PostDataField("action", "status")); 
     205                builder.AddPart(new PostDataField("action", "upload")); 
     206                builder.AddPart(new PostDataFileField("crashReport", "Report.tar.7z", bzipFile)); 
    101207                AddStackTraceToRequest(Report.StackTrace, builder); 
    102208 
     209                //Upload the POST request 
    103210                WebRequest reportRequest = HttpWebRequest.Create(BlackBoxServer); 
    104211                reportRequest.ContentType = builder.ContentType; 
    105212                reportRequest.Method = "POST"; 
     213                reportRequest.Timeout = int.MaxValue; 
    106214                using (Stream formStream = builder.Stream) 
    107215                { 
     216                    ProgressManager progress = new ProgressManager(); 
     217                    overallProgress.Steps.Add(new SteppedProgressManagerStep( 
     218                        progress, 0.5f, "Uploading")); 
    108219                    reportRequest.ContentLength = formStream.Length; 
     220 
    109221                    using (Stream requestStream = reportRequest.GetRequestStream()) 
    110222                    { 
     
    112224                        byte[] buffer = new byte[32768]; 
    113225                        while ((lastRead = formStream.Read(buffer, 0, buffer.Length)) != 0) 
     226                        { 
    114227                            requestStream.Write(buffer, 0, lastRead); 
     228 
     229                            progress.Total = formStream.Length; 
     230                            progress.Completed = formStream.Position; 
     231                            progressChanged(this, new ProgressChangedEventArgs(overallProgress, null)); 
     232                        } 
    115233                    } 
    116234                } 
     
    124242                        reader.ReadToFollowing("crashReport"); 
    125243                        string reportStatus = reader.GetAttribute("status"); 
    126                         switch (reportStatus) 
    127                         { 
    128                             case "exists": 
    129                                 Report.Submitted = true; 
    130                                 return false; 
    131  
    132                             case "new": 
    133                                 return true; 
    134  
    135                             default: 
    136                                 throw new InvalidDataException( 
    137                                     "Unknown crash report server response."); 
    138                         } 
    139                     } 
     244                        string reportId = reader.GetAttribute("id"); 
     245                    } 
     246 
     247                    Report.Submitted = true; 
    140248                } 
    141249                catch (WebException e) 
     
    165273 
    166274        /// <summary> 
    167         /// Compresses the report for uploading. 
    168         /// </summary> 
    169         /// <param name="progress">The <see cref="ProgressManager"/> instance that the 
    170         /// Upload function is using.</param> 
    171         /// <param name="progressChanged">The progress changed event handler that should 
    172         /// be called for upload progress updates.</param> 
    173         private void Compress(SteppedProgressManager progress, 
    174             ProgressChangedEventHandler progressChanged) 
    175         { 
    176             using (FileStream archiveStream = new FileStream(ReportBaseName + ".tar", 
    177                     FileMode.Create, FileAccess.Write)) 
    178             { 
    179                 //Add the report into a tar file 
    180                 TarArchive archive = TarArchive.CreateOutputTarArchive(archiveStream); 
    181                 foreach (FileInfo file in Report.Files) 
    182                 { 
    183                     TarEntry entry = TarEntry.CreateEntryFromFile(file.FullName); 
    184                     entry.Name = Path.GetFileName(entry.Name); 
    185                     archive.WriteEntry(entry, false); 
    186                 } 
    187                 archive.Close(); 
    188             } 
    189  
    190             ProgressManager step = new ProgressManager(); 
    191             progress.Steps.Add(new SteppedProgressManagerStep(step, 0.5f, "Compressing")); 
    192             CoderPropID[] propIDs =  
    193                 { 
    194                     CoderPropID.DictionarySize, 
    195                     CoderPropID.PosStateBits, 
    196                     CoderPropID.LitContextBits, 
    197                     CoderPropID.LitPosBits, 
    198                     CoderPropID.Algorithm, 
    199                     CoderPropID.NumFastBytes, 
    200                     CoderPropID.MatchFinder, 
    201                     CoderPropID.EndMarker 
    202                 }; 
    203             object[] properties =  
    204                 { 
    205                     (Int32)(1 << 24),           //Dictionary Size 
    206                     (Int32)2,                   //PosState Bits 
    207                     (Int32)0,                   //LitContext Bits 
    208                     (Int32)2,                   //LitPos Bits 
    209                     (Int32)2,                   //Algorithm 
    210                     (Int32)128,                 //Fast Bytes 
    211                     "bt4",                      //Match Finger 
    212                     true                        //Write end-of-stream 
    213                 }; 
    214  
    215             SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compression.LZMA.Encoder(); 
    216             encoder.SetCoderProperties(propIDs, properties); 
    217  
    218             using (FileStream sevenZipFile = new FileStream(ReportBaseName + ".tar.7z", 
    219                 FileMode.Create)) 
    220             using (FileStream tarStream = new FileStream(ReportBaseName + ".tar", 
    221                 FileMode.Open, FileAccess.Read, FileShare.Read, 262144, FileOptions.DeleteOnClose)) 
    222             { 
    223                 encoder.WriteCoderProperties(sevenZipFile); 
    224                 Int64 fileSize = -1; 
    225                 for (int i = 0; i < 8; i++) 
    226                     sevenZipFile.WriteByte((Byte)(fileSize >> (8 * i))); 
    227  
    228                 step.Total = tarStream.Length; 
    229                 ICodeProgress callback = progressChanged == null ? null : 
    230                     new SevenZipProgressCallback(this, progress, step, progressChanged); 
    231                 encoder.Code(tarStream, sevenZipFile, -1, -1, callback); 
    232             } 
    233         } 
    234  
    235         /// <summary> 
    236         /// Compresses the report, then uploads it to the server. 
    237         /// </summary> 
    238         /// <param name="progressChanged">The progress changed event handler that should 
    239         /// be called for upload progress updates.</param> 
    240         public void Submit(ProgressChangedEventHandler progressChanged) 
    241         { 
    242             SteppedProgressManager overallProgress = new SteppedProgressManager(); 
    243             Compress(overallProgress, progressChanged); 
    244  
    245             using (FileStream bzipFile = new FileStream(ReportBaseName + ".tar.7z", 
    246                 FileMode.Open, FileAccess.Read, FileShare.Read, 131072, FileOptions.DeleteOnClose)) 
    247             using (Stream logFile = Report.DebugLog) 
    248             { 
    249                 //Build the POST request 
    250                 PostDataBuilder builder = new PostDataBuilder(); 
    251                 builder.AddPart(new PostDataField("action", "upload")); 
    252                 builder.AddPart(new PostDataFileField("crashReport", "Report.tar.7z", bzipFile)); 
    253                 AddStackTraceToRequest(Report.StackTrace, builder); 
    254  
    255                 //Upload the POST request 
    256                 WebRequest reportRequest = HttpWebRequest.Create(BlackBoxServer); 
    257                 reportRequest.ContentType = builder.ContentType; 
    258                 reportRequest.Method = "POST"; 
    259                 reportRequest.Timeout = int.MaxValue; 
    260                 using (Stream formStream = builder.Stream) 
    261                 { 
    262                     ProgressManager progress = new ProgressManager(); 
    263                     overallProgress.Steps.Add(new SteppedProgressManagerStep( 
    264                         progress, 0.5f, "Uploading")); 
    265                     reportRequest.ContentLength = formStream.Length; 
    266  
    267                     using (Stream requestStream = reportRequest.GetRequestStream()) 
    268                     { 
    269                         int lastRead = 0; 
    270                         byte[] buffer = new byte[32768]; 
    271                         while ((lastRead = formStream.Read(buffer, 0, buffer.Length)) != 0) 
    272                         { 
    273                             requestStream.Write(buffer, 0, lastRead); 
    274  
    275                             progress.Total = formStream.Length; 
    276                             progress.Completed = formStream.Position; 
    277                             progressChanged(this, new ProgressChangedEventArgs(overallProgress, null)); 
    278                         } 
    279                     } 
    280                 } 
    281  
    282                 try 
    283                 { 
    284                     HttpWebResponse response = reportRequest.GetResponse() as HttpWebResponse; 
    285                     using (Stream responseStream = response.GetResponseStream()) 
    286                     { 
    287                         XmlReader reader = XmlReader.Create(responseStream); 
    288                         reader.ReadToFollowing("crashReport"); 
    289                         string reportStatus = reader.GetAttribute("status"); 
    290                         string reportId = reader.GetAttribute("id"); 
    291                     } 
    292  
    293                     Report.Submitted = true; 
    294                 } 
    295                 catch (WebException e) 
    296                 { 
    297                     if (e.Response == null) 
    298                         throw; 
    299  
    300                     using (Stream responseStream = e.Response.GetResponseStream()) 
    301                     { 
    302                         try 
    303                         { 
    304                             XmlReader reader = XmlReader.Create(responseStream); 
    305                             reader.ReadToFollowing("error"); 
    306                             throw new InvalidDataException(string.Format(CultureInfo.CurrentCulture, 
    307                                 "The server encountered a problem while processing the request: {0}", 
    308                                 reader.ReadString())); 
    309                         } 
    310                         catch (XmlException) 
    311                         { 
    312                         } 
    313                     } 
    314  
    315                     throw new InvalidDataException(((HttpWebResponse)e.Response).StatusDescription); 
    316                 } 
    317             } 
    318         } 
    319  
    320         /// <summary> 
    321275        /// Adds the stack trace to the given form request. 
    322276        /// </summary> 
     
    339293 
    340294        /// <summary> 
     295        /// Builds a WebRequest object and queries the server for a response. 
     296        /// </summary> 
     297        /// <param name="action">The action to perform.</param> 
     298        /// <param name="includeStackTrace">Whether to include a stack trace.</param> 
     299        /// <returns>An XmlReader containing the response.</returns> 
     300        private XmlDocument QueryServer(string action, bool includeStackTrace) 
     301        { 
     302            PostDataBuilder builder = new PostDataBuilder(); 
     303            builder.AddPart(new PostDataField("action", action)); 
     304            if (includeStackTrace) 
     305                AddStackTraceToRequest(Report.StackTrace, builder); 
     306 
     307            WebRequest reportRequest = HttpWebRequest.Create(BlackBoxServer); 
     308            reportRequest.ContentType = builder.ContentType; 
     309            reportRequest.Method = "POST"; 
     310            using (Stream formStream = builder.Stream) 
     311            { 
     312                reportRequest.ContentLength = formStream.Length; 
     313                using (Stream requestStream = reportRequest.GetRequestStream()) 
     314                { 
     315                    int lastRead = 0; 
     316                    byte[] buffer = new byte[32768]; 
     317                    while ((lastRead = formStream.Read(buffer, 0, buffer.Length)) != 0) 
     318                        requestStream.Write(buffer, 0, lastRead); 
     319                } 
     320            } 
     321 
     322            try 
     323            { 
     324                HttpWebResponse response = reportRequest.GetResponse() as HttpWebResponse; 
     325                using (Stream responseStream = response.GetResponseStream()) 
     326                { 
     327                    XmlReader reader = XmlReader.Create(responseStream); 
     328                    XmlDocument result = new XmlDocument(); 
     329                    result.Load(reader); 
     330                    return result; 
     331                } 
     332            } 
     333            catch (WebException e) 
     334            { 
     335                if (e.Response == null) 
     336                    throw; 
     337 
     338                using (Stream responseStream = e.Response.GetResponseStream()) 
     339                { 
     340                    try 
     341                    { 
     342                        XmlReader reader = XmlReader.Create(responseStream); 
     343                        reader.ReadToFollowing("error"); 
     344                        throw new InvalidDataException(string.Format(CultureInfo.CurrentCulture, 
     345                            "The server encountered a problem while processing the request: {0}", 
     346                            reader.ReadString())); 
     347                    } 
     348                    catch (XmlException) 
     349                    { 
     350                    } 
     351                } 
     352 
     353                throw new InvalidDataException(((HttpWebResponse)e.Response).StatusDescription); 
     354            } 
     355        } 
     356 
     357        /// <summary> 
    341358        /// The path to where the temporary files are stored before uploading. 
    342359        /// </summary> 
Note: See TracChangeset for help on using the changeset viewer.