private static UriInfo StringToLink(Uri referer, String s) { UriInfo ret = null; try { if (s.IndexOf("//") == 0) { s = referer.Scheme + ":" + s; } Uri tmp = new Uri(s); ret = new UriInfo(tmp, referer); } catch { try { Uri tmp = new Uri(referer.Scheme + "://" + referer.Host + (s.IndexOf("/") == 0 ? s : "/" + s)); ret = new UriInfo(tmp, referer); } catch { } } return(ret); }
public Boolean Equal(UriInfo comparer) { return(Target.Equals(comparer.Target)); }
private void Check(LoadTestDatabase db, CheckType type, UriInfo info, ResultData request) { switch (type) { case CheckType.Css: case CheckType.JS: String value = request.ContentEncoding2.GetString(request.Data); String min = minify(value); String expanded = expand(value); double percentMin = 100F - (((double)min.Length / (double)value.Length) * 100F); double percentExp = 100F - (((double)value.Length / (double)expanded.Length) * 100F); if (percentMin > 10) { db.insertMessages(this.TestName, "5. Otimização de arquivos (minify *.js, *.css)", "URL: <a href=\"" + info.Target.AbsoluteUri + "\" target=\"_blank\">" + info.Target.AbsoluteUri + "</a>" + Environment.NewLine + (info.Referer != null ? "Referer: <a href=\"" + info.Referer.AbsoluteUri + "\" target=\"_blank\">" + info.Referer.AbsoluteUri + "</a>" + Environment.NewLine : "") + Environment.NewLine + "Redução estimada de: " + FileResources.formatData(percentMin, ChartDataType.Percent) + Environment.NewLine + "Tamanho original: " + FileResources.formatData(value.Length, ChartDataType.Bytes) + Environment.NewLine + "Tamanho reduzido: " + FileResources.formatData(min.Length, ChartDataType.Bytes)); db.insertOptimization(this.TestName, request.RequestUri, value.Length, min.Length); } if (percentExp > 3) { db.insertNonOptimization(this.TestName, request.RequestUri, value.Length, expanded.Length); } break; case CheckType.Image: String text = ""; String imageInfo = ""; imageInfo = "Tamanho: " + FileResources.formatData(request.DataLength, ChartDataType.Bytes) + Environment.NewLine; if (request.DataLength > (100 * 1024)) //100 Kb { text += "* Tamanho da imagem acima de 100Kb" + Environment.NewLine; } using (MemoryStream stm = new MemoryStream(request.Data)) using (Image bmp = Image.FromStream(stm)) { Boolean resolution = false; PixelFormat pxFormat = PixelFormat.Format24bppRgb; float saveRes = bmp.HorizontalResolution; try { imageInfo += "Resolução: " + bmp.Width + " x " + bmp.Height + "px" + Environment.NewLine; } catch { } try { if ((((Int32)bmp.HorizontalResolution) > 72) || (((Int32)bmp.VerticalResolution) > 72)) { text += "* Qualidade (DPI) da imagem acima de 72" + Environment.NewLine; } imageInfo += "DPI: " + bmp.HorizontalResolution + Environment.NewLine; resolution = true; saveRes = 72; } catch { } try { switch (bmp.PixelFormat) { case System.Drawing.Imaging.PixelFormat.Format32bppArgb: case System.Drawing.Imaging.PixelFormat.Format32bppPArgb: case System.Drawing.Imaging.PixelFormat.Format32bppRgb: case System.Drawing.Imaging.PixelFormat.Format48bppRgb: case System.Drawing.Imaging.PixelFormat.Format64bppArgb: case System.Drawing.Imaging.PixelFormat.Format64bppPArgb: text += "* Qualidade (Bit depth) da imagem acima de 24 bits" + Environment.NewLine; resolution = true; pxFormat = PixelFormat.Format24bppRgb; break; } switch (bmp.PixelFormat) { case System.Drawing.Imaging.PixelFormat.Format8bppIndexed: imageInfo += "Bit depth: 16 bits" + Environment.NewLine; pxFormat = bmp.PixelFormat; break; case System.Drawing.Imaging.PixelFormat.Format16bppArgb1555: case System.Drawing.Imaging.PixelFormat.Format16bppGrayScale: case System.Drawing.Imaging.PixelFormat.Format16bppRgb555: case System.Drawing.Imaging.PixelFormat.Format16bppRgb565: imageInfo += "Bit depth: 16 bits" + Environment.NewLine; pxFormat = bmp.PixelFormat; break; case System.Drawing.Imaging.PixelFormat.Format24bppRgb: imageInfo += "Bit depth: 24 bits" + Environment.NewLine; pxFormat = PixelFormat.Format24bppRgb; break; case System.Drawing.Imaging.PixelFormat.Format32bppArgb: case System.Drawing.Imaging.PixelFormat.Format32bppPArgb: case System.Drawing.Imaging.PixelFormat.Format32bppRgb: imageInfo += "Bit depth: 32 bits" + Environment.NewLine; pxFormat = PixelFormat.Format24bppRgb; break; case System.Drawing.Imaging.PixelFormat.Format48bppRgb: imageInfo += "Bit depth: 48 bits" + Environment.NewLine; pxFormat = PixelFormat.Format24bppRgb; break; case System.Drawing.Imaging.PixelFormat.Format64bppArgb: case System.Drawing.Imaging.PixelFormat.Format64bppPArgb: imageInfo += "Bit depth: 64 bits" + Environment.NewLine; pxFormat = PixelFormat.Format24bppRgb; break; default: imageInfo += "Bit depth: " + bmp.PixelFormat.ToString() + Environment.NewLine; break; } } catch { } try { using (ImageInfo imgInfo = new ImageInfo(bmp)) { if (imgInfo.HasExif) { text += "* Imagem com informações EXIF. A remoção desta informação reduz o tamanho da imagem" + Environment.NewLine; resolution = true; } } } catch { } //Realiza a Otimização sugerida e calcula o tamanho estimado a conseguir if (resolution) { try { ImageFormat saveFormat = ImageFormat.Jpeg; if (bmp.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Jpeg)) { saveFormat = System.Drawing.Imaging.ImageFormat.Jpeg; } if (bmp.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Bmp)) { saveFormat = System.Drawing.Imaging.ImageFormat.Bmp; } if (bmp.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Png)) { saveFormat = System.Drawing.Imaging.ImageFormat.Png; } if (bmp.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Emf)) { saveFormat = System.Drawing.Imaging.ImageFormat.Emf; } if (bmp.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Exif)) { saveFormat = System.Drawing.Imaging.ImageFormat.Exif; } if (bmp.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Gif)) { saveFormat = System.Drawing.Imaging.ImageFormat.Gif; } if (bmp.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Icon)) { saveFormat = System.Drawing.Imaging.ImageFormat.Icon; } if (bmp.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.MemoryBmp)) { saveFormat = System.Drawing.Imaging.ImageFormat.MemoryBmp; } if (bmp.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Tiff)) { saveFormat = System.Drawing.Imaging.ImageFormat.Tiff; } if (bmp.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Wmf)) { saveFormat = System.Drawing.Imaging.ImageFormat.Wmf; } Bitmap newImage = new Bitmap(bmp.Width, bmp.Height, pxFormat); newImage.SetResolution(saveRes, saveRes); Graphics g = Graphics.FromImage(newImage); g.SmoothingMode = SmoothingMode.AntiAlias; g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.PixelOffsetMode = PixelOffsetMode.HighQuality; g.DrawImage(bmp, 0, 0); g.Dispose(); MemoryStream newStm = new MemoryStream(); newImage.Save(newStm, saveFormat); if (newStm.Length < request.DataLength) { db.insertOptimization(this.TestName, request.RequestUri, request.DataLength, newStm.Length); double percent2 = 100F - (((double)newStm.Length / (double)request.DataLength) * 100F); text += Environment.NewLine; text += "Tamanho estimado após redução: " + FileResources.formatData(newStm.Length, ChartDataType.Bytes) + Environment.NewLine; text += "Redução estimada de: " + FileResources.formatData(percent2, ChartDataType.Percent) + Environment.NewLine; } else { //Não há redução, a imagem está otimizada text = ""; } newImage.Dispose(); newImage = null; newStm.Dispose(); newStm = null; } catch (Exception ex) { #if DEBUG text += "Erro ao calcular a redução: " + ex.Message; #endif } } } if (text != "") { db.insertMessages(this.TestName, "6. Otimização de imagem", "Img URL: <a href=\"" + info.Target.AbsoluteUri + "\" target=\"_blank\">" + info.Target.AbsoluteUri + "</a>" + Environment.NewLine + (info.Referer != null ? "Referer: <a href=\"" + info.Referer.AbsoluteUri + "\" target=\"_blank\">" + info.Referer.AbsoluteUri + "</a>" + Environment.NewLine : "") + Environment.NewLine + imageInfo + Environment.NewLine + text); } break; } }
private void GetLinks(Uri baseUri, IPEndPoint proxy, Int32 level, Int32 maxLevel) { //Se ja foi processado, ignora if (gets.Contains(baseUri.AbsoluteUri)) { return; } Console.WriteLine(level + " ==> " + baseUri.AbsoluteUri); lock (gets) { gets.Add(baseUri.AbsoluteUri); } List <UriInfo> tags = new List <UriInfo>(); tags.Add(new UriInfo(baseUri)); //HtmlDocument doc = new HtmlDocument(); //doc.LoadHtml(html); HtmlWeb web = new HtmlWeb(); HtmlDocument doc = null; if (proxy == null) { doc = web.Load(baseUri.AbsoluteUri); } else { doc = web.Load(baseUri.AbsoluteUri, "GET", new WebProxy("http://" + proxy.Address + ":" + proxy.Port), null); } HtmlNodeCollection scripts = doc.DocumentNode.SelectNodes("//script[@src]"); if (scripts != null) { foreach (HtmlNode link in scripts) { HtmlAttribute att = link.Attributes["src"]; UriInfo tmp = StringToLink(baseUri, att.Value); if (tmp != null) { tags.Add(tmp); } } } HtmlNodeCollection links = doc.DocumentNode.SelectNodes("//link[@href]"); if (links != null) { foreach (HtmlNode link in links) { HtmlAttribute att = link.Attributes["href"]; HtmlAttribute rel = link.Attributes["rel"]; if ((rel != null) && (!String.IsNullOrEmpty(rel.Value))) { switch (rel.Value.ToLower()) { case "stylesheet": case "icon": case "next": case "canonical": UriInfo tmp = StringToLink(baseUri, att.Value); if (tmp != null) { tags.Add(tmp); } break; } } } } HtmlNodeCollection imgs = doc.DocumentNode.SelectNodes("//img[@src]"); if (imgs != null) { foreach (HtmlNode link in imgs) { HtmlAttribute att = link.Attributes["src"]; UriInfo tmp = StringToLink(baseUri, att.Value); if (tmp != null) { tags.Add(tmp); } } } HtmlNodeCollection aLinks = doc.DocumentNode.SelectNodes("//a[@href]"); if (aLinks != null) { foreach (HtmlNode link in aLinks) { HtmlAttribute att = link.Attributes["href"]; UriInfo tmp = StringToLink(baseUri, att.Value); switch (GetExtension(tmp.Target)) { case ".txt": case ".html": case ".php": case ".asp": case ".aspx": case ".jpg": case ".png": case ".gif": tags.Add(tmp); break; } if (level < maxLevel) { if ((tmp != null) && (tmp.Target.Host.ToLower() == baseUri.Host.ToLower()) && (tmp.Target.AbsoluteUri != baseUri.AbsoluteUri)) { GetLinks(tmp.Target, proxy, level + 1, maxLevel); } } } } foreach (UriInfo l in tags) { if ((l != null) && (l.Target.Host.ToLower() == baseUri.Host.ToLower())) { if (!uriList.Exists(u => (u.Equals(l)))) { uriList.Add(l); } } else { if (!outUriList.Exists(u => (u.Equals(l)))) { outUriList.Add(l); } } } }
private void AnalizeURI(LoadTestDatabase db, UriInfo u) { switch (GetExtension(u.Target)) { case ".txt": //Sai sem analizar return; break; } Console.WriteLine("ContentAnalizer> " + u.Target); Console.Write("\tBaixando: "); ResultData request = Request.GetRequest(u.Target, this.Proxy, false, HTTPHeaders); if (request.Error) { Console.WriteLine("Err " + request.ErrorMessage); db.insertMessages(this.TestName, "3. Erro na chamada de URL", "URL: <a href=\"" + u.Target.AbsoluteUri + "\" target=\"_blank\">" + u.Target.AbsoluteUri + "</a>" + Environment.NewLine + (u.Referer != null ? "Referer: <a href=\"" + u.Referer.AbsoluteUri + "\" target=\"_blank\">" + u.Referer.AbsoluteUri + "</a>" + Environment.NewLine : "") + Environment.NewLine + "Tempo de resposta: " + FileResources.formatData(request.Time.TotalMilliseconds, ChartDataType.Integer) + "ms " + Environment.NewLine + "Código de retorno HTTP: " + request.Code + Environment.NewLine + Environment.NewLine + (!String.IsNullOrEmpty(request.ErrorMessage) ? "Texto do erro: " + request.ErrorMessage : "")); } else { Console.WriteLine("OK " + request.DataLength); Console.Write("\tVerificando: "); //Tempo de resposta if (request.Time.TotalMilliseconds > 1500F) { db.insertMessages(this.TestName, "2. Alto tempo de resposta", "URL: <a href=\"" + u.Target.AbsoluteUri + "\" target=\"_blank\">" + u.Target.AbsoluteUri + "</a>" + Environment.NewLine + (u.Referer != null ? "Referer: <a href=\"" + u.Referer.AbsoluteUri + "\" target=\"_blank\">" + u.Referer.AbsoluteUri + "</a>" + Environment.NewLine : "") + Environment.NewLine + "Tempo de resposta: " + FileResources.formatData(request.Time.TotalMilliseconds, ChartDataType.Integer) + " ms"); } String extension = GetExtension(u.Target); if (!MIMECheck.CheckMime(request.ContentType.ToLower(), extension)) { db.insertMessages(this.TestName, "4. ContentType inválido", "URL: <a href=\"" + u.Target.AbsoluteUri + "\" target=\"_blank\">" + u.Target.AbsoluteUri + "</a>" + Environment.NewLine + (u.Referer != null ? "Referer: <a href=\"" + u.Referer.AbsoluteUri + "\" target=\"_blank\">" + u.Referer.AbsoluteUri + "</a>" + Environment.NewLine : "") + Environment.NewLine + "Extensão: " + extension + Environment.NewLine + "MIME Type: " + request.ContentType); } if ((request.OriginalDataLength > 0) && (request.OriginalDataLength < request.DataLength)) { db.insertGzipOptimization(this.TestName, request.RequestUri, request.OriginalDataLength, request.DataLength); } else if ((request.OriginalDataLength > 0) && (request.OriginalDataLength == request.DataLength)) { //Realiza a compactação Gzip para estimar a otimização Byte[] tmp = GzipCompress(request.Data); double percent = 100F - (((double)tmp.Length / (double)request.DataLength) * 100F); if (percent > 10) { db.insertMessages(this.TestName, "7. Otimização de rede (compactação gzip/deflate)", "URL: <a href=\"" + u.Target.AbsoluteUri + "\" target=\"_blank\">" + u.Target.AbsoluteUri + "</a>" + Environment.NewLine + (u.Referer != null ? "Referer: <a href=\"" + u.Referer.AbsoluteUri + "\" target=\"_blank\">" + u.Referer.AbsoluteUri + "</a>" + Environment.NewLine : "") + Environment.NewLine + "Redução estimada de: " + FileResources.formatData(percent, ChartDataType.Percent) + Environment.NewLine + "Tamanho original: " + FileResources.formatData(request.DataLength, ChartDataType.Bytes) + Environment.NewLine + "Tamanho reduzido: " + FileResources.formatData(tmp.Length, ChartDataType.Bytes)); } } //Consições específicas por conteúdo switch (request.ContentType.ToLower()) { case "application/x-pointplus": case "text/css": Check(db, CheckType.Css, u, request); break; case "application/x-javascript": case "application/javascript": case "application/ecmascript": case "text/javascript": case "text/ecmascript": Check(db, CheckType.JS, u, request); break; case "image/png": Check(db, CheckType.Image, u, request); break; default: //Verifica por extenção switch (extension) { case ".css": Check(db, CheckType.Css, u, request); break; case ".js": Check(db, CheckType.JS, u, request); break; case ".png": case ".jpg": case ".gif": Check(db, CheckType.Image, u, request); break; } break; } Console.WriteLine("OK"); } }