Skip to content

Commit

Permalink
support Symfony profiler using gzip files and provide mailer collecto…
Browse files Browse the repository at this point in the history
…r inside statusbar
  • Loading branch information
Haehnchen committed Aug 23, 2023
1 parent eacb705 commit ab6967f
Show file tree
Hide file tree
Showing 12 changed files with 199 additions and 97 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
Expand Down Expand Up @@ -74,7 +72,7 @@ public String getUrlForRequest(@NotNull ProfilerRequestInterface request) {
return this.baseUrl + "/" + StringUtils.stripStart(request.getProfilerUrl(), "/");
}

return ProfilerUtil.getBaseProfilerUrlFromRequest(request.getProfilerUrl());
return ProfilerUtil.getBaseProfilerUrlFromRequest(request) + "/" + StringUtils.stripStart(request.getProfilerUrl(), "/");
}

@NotNull
Expand Down Expand Up @@ -102,19 +100,7 @@ private String getContentForHash(@NotNull String hash) {
return null;
}

StringBuilder content = new StringBuilder();

try {
BufferedReader in = new BufferedReader(new FileReader(file));
String str;
while ((str = in.readLine()) != null) {
content.append(str);
}
in.close();
} catch (IOException ignored) {
}

return content.toString();
return ProfilerUtil.getContentForFile(file);
}

private class MyProfilerRequestBuilderCallable implements Callable<ProfilerRequestInterface> {
Expand All @@ -125,7 +111,7 @@ private class MyProfilerRequestBuilderCallable implements Callable<ProfilerReque
}

@Override
public ProfilerRequestInterface call() throws Exception {
public ProfilerRequestInterface call() {
String content = getContentForHash(split[0]);
if(content == null) {
return new LocalProfilerRequest(split);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import fr.adrienbrault.idea.symfony2plugin.profiler.dict.ProfilerRequestInterface;
import fr.adrienbrault.idea.symfony2plugin.profiler.factory.ProfilerFactoryUtil;
import icons.TwigIcons;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
Expand Down Expand Up @@ -138,13 +139,13 @@ public void selected(@NotNull ProfilerRequestInterface profilerRequest) {
if(collector != null) {
Collection<MailMessage> messages = collector.getMessages();
if(messages.size() > 0) {
this.editorPane1.setText(messages.iterator().next().getMessage());
this.editorPane1.setText(messages.iterator().next().message());
}
}
}

public void selected(MailMessage mailMessage) {
this.editorPane1.setText(mailMessage.getMessage());
this.editorPane1.setText(mailMessage.message());
}

private void start() {
Expand Down Expand Up @@ -177,8 +178,8 @@ public Component getListCellRendererComponent(JList list, Object value, int inde
renderer.setText(((LocalProfilerRequest) value).getUrl());
}

if(value instanceof MailMessage) {
renderer.setText(((MailMessage) value).getTitle());
if (value instanceof MailMessage) {
renderer.setText(StringUtils.abbreviate(((MailMessage) value).title(), 40));
}

return renderer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

Expand All @@ -25,29 +23,47 @@ public LocalMailCollector(@NotNull String contents) {

@NotNull
public Collection<MailMessage> getMessages() {
Collection<MailMessage> mails = new ArrayList<>();

String messages = this.findTwice(this.contents, "MessageDataCollector\":(\\d+):");
if(messages == null) {
return Collections.emptyList();
}
if(messages != null) {
Matcher matcher = Pattern.compile("\"\\x00Swift_Mime_SimpleMimeEntity\\x00_body\";s:(\\d+):\"", Pattern.MULTILINE).matcher(messages);

Matcher matcher = Pattern.compile("\"\\x00Swift_Mime_SimpleMimeEntity\\x00_body\";s:(\\d+):\"", Pattern.MULTILINE).matcher(messages);
while(matcher.find()){
String domain = matcher.group(1);

Collection<MailMessage> mails = new ArrayList<>();
while(matcher.find()){
String domain = matcher.group(1);
//String array_strings = matcher.group(2);
int start = matcher.end();
int end = start + Integer.parseInt(domain);

int start = matcher.end();
int end = start + Integer.parseInt(domain);
mails.add(new MailMessage(messages.substring(start, end), "", "", "swiftmailer"));
}
}

//System.out.println(content.substring(start, end));
mails.add(new MailMessage(messages.substring(start, end), "aa", "aa"));
// try to find any serialized object inside the mailer class
Matcher matcher = Pattern.compile("AbstractHeader\\x00name\"[\\w;:]+\"Subject\"").matcher(this.contents);
Set<String> titles = new HashSet<>();

//Matcher match_strings = Pattern.compile("'(.*?)'\\s=>\\s'.*?'", Pattern.MULTILINE).matcher(array_strings);
//while(match_strings.find()){
// string_map.addString(domain, match_strings.group(1));
//}
while(matcher.find()){
int end = matcher.end();

// find ending scope
int endingHeaderScope = contents.indexOf("}", end);
if (endingHeaderScope > 0) {
String subjectHeaderScope = contents.substring(matcher.start(), endingHeaderScope);

// find the email "Subject" header value
Matcher matcher2 = Pattern.compile("UnstructuredHeader.*value\"[\\w;:]+\"(.*)\"").matcher(subjectHeaderScope);
if (matcher2.find()) {
String subject = matcher2.group(1);
if (!subject.isBlank()) {
titles.add(subject);
}
}
}
}

for (String title : titles) {
mails.add(new MailMessage("", title, "", "mailer"));
}

return mails;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,5 @@
/**
* @author Daniel Espendiller <[email protected]>
*/
public class MailMessage {

@NotNull
private final String message;

@NotNull
private final String title;

@NotNull
private final String format;

public MailMessage(@NotNull String message, @NotNull String title, @NotNull String format) {
this.message = message;
this.title = title;
this.format = format;
}

@NotNull
public String getMessage() {
return message;
}

@NotNull
public String getTitle() {
return title;
}

@NotNull
public String getFormat() {
return format;
}

public record MailMessage(@NotNull String message, @NotNull String title, @NotNull String format, @NotNull String panel) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
Expand All @@ -31,6 +29,7 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.zip.GZIPInputStream;

/**
* @author Daniel Espendiller <[email protected]>
Expand Down Expand Up @@ -424,11 +423,18 @@ public static List<ProfilerRequestInterface> getProfilerRequestCollectorDecorate
* https://127.0.0.1:8000/app_dev.php
*/
@Nullable
public static String getBaseProfilerUrlFromRequest(@NotNull String requestUrl) {
URL url;
public static String getBaseProfilerUrlFromRequest(@NotNull ProfilerRequestInterface request) {
URL url = null;
try {
url = new URL(requestUrl);
url = new URL(request.getProfilerUrl());
} catch (MalformedURLException e) {
try {
url = new URL(request.getUrl());
} catch (MalformedURLException ignored) {
}
}

if (url == null) {
return null;
}

Expand Down Expand Up @@ -468,5 +474,70 @@ public static String formatProfilerRow(@NotNull ProfilerRequestInterface profile

return String.format("(%s) %s", statusCode == 0 ? "n/a" : statusCode, StringUtils.abbreviate(path, 35));
}

public static String getContentForFile(@NotNull File file) {
boolean isGzipFile;

try {
byte[] buffer = new byte[3];

InputStream is = new FileInputStream(file);
int __ = is.read(buffer);

// check gzip header
isGzipFile = buffer[0] == 31
&& buffer[1] == -117
&& buffer[2] == 8;

is.close();
} catch (IOException e) {
return null;
}

if (isGzipFile) {
return getProfilerContentGzdecode(file);
}

return getContentForRaw(file);
}

@Nullable
private static String getContentForRaw(@NotNull File file) {
StringBuilder content = new StringBuilder();

try {
BufferedReader in = new BufferedReader(new FileReader(file));
String str;
while ((str = in.readLine()) != null) {
content.append(str);
}
in.close();
} catch (IOException ignored) {
return null;
}

return content.toString();
}

@Nullable
private static String getProfilerContentGzdecode(File file) {
try {
InputStream in = new FileInputStream(file.getPath());

GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(in.readAllBytes()));
BufferedReader bf = new BufferedReader(new InputStreamReader(gis));
StringBuilder outStr = new StringBuilder();

String line;
while ((line=bf.readLine())!=null) {
outStr.append(line);
}

return outStr.toString();
} catch (IOException ignored) {
}

return null;
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@
import com.intellij.openapi.wm.StatusBarWidget;
import com.intellij.openapi.wm.impl.status.EditorBasedWidget;
import com.intellij.ui.popup.PopupFactoryImpl;
import fr.adrienbrault.idea.symfony2plugin.Symfony2Icons;
import fr.adrienbrault.idea.symfony2plugin.profiler.ProfilerIndexInterface;
import fr.adrienbrault.idea.symfony2plugin.profiler.collector.DefaultDataCollectorInterface;
import fr.adrienbrault.idea.symfony2plugin.profiler.collector.MailCollectorInterface;
import fr.adrienbrault.idea.symfony2plugin.profiler.dict.MailMessage;
import fr.adrienbrault.idea.symfony2plugin.profiler.dict.ProfilerRequestInterface;
import fr.adrienbrault.idea.symfony2plugin.profiler.factory.ProfilerFactoryUtil;
import fr.adrienbrault.idea.symfony2plugin.profiler.widget.action.SymfonyProfilerWidgetActions;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

Expand Down Expand Up @@ -75,39 +79,45 @@ public DefaultActionGroup getActions(){
attachProfileItem(controllerActions, controllerActionsMap, collector.getController(), ProfilerTarget.CONTROLLER);
}

// @TODO: use collector
//String content = profilerRequest.getContent();
//if(content != null && content.contains("Swift_Mime_Headers_MailboxHeader")) {
// mailActions.add(new SymfonyProfilerWidgetActions.UrlAction(getProject(), profilerRequest, statusCode).withPanel("swiftmailer").withIcon(Symfony2Icons.MAIL));
//}
MailCollectorInterface collectorMail = profilerRequest.getCollector(MailCollectorInterface.class);
if(collectorMail != null) {
for (MailMessage message : collectorMail.getMessages()) {
String title = message.title();
if (title.isBlank()) {
mailActions.add(new SymfonyProfilerWidgetActions.UrlAction(index, profilerRequest, message.panel())
.withIcon(Symfony2Icons.MAIL)
.withText(String.format("(%s) %s", profilerRequest.getHash(), StringUtils.abbreviate(title, 40))));
}
}
}
}

// routes
if(urlActions.size() > 0) {
if(!urlActions.isEmpty()) {
actionGroup.addSeparator("Debug-Url");
actionGroup.addAll(urlActions);
}

// mails send by request
if(mailActions.size() > 0) {
if(!mailActions.isEmpty()) {
actionGroup.addSeparator("E-Mail");
actionGroup.addAll(mailActions);
}

// routes
if(routeActions.size() > 0) {
if(!routeActions.isEmpty()) {
actionGroup.addSeparator("Routes");
actionGroup.addAll(routeActions);
}

// controller methods
if(controllerActions.size() > 0) {
if(!controllerActions.isEmpty()) {
actionGroup.addSeparator("Controller");
actionGroup.addAll(controllerActions);
}

// template should be most use case; so keep it in cursor range
if(templateActions.size() > 0) {
if(!templateActions.isEmpty()) {
actionGroup.addSeparator("Template");
actionGroup.addAll(templateActions);
}
Expand Down
Loading

0 comments on commit ab6967f

Please sign in to comment.