Skip to content

Instantly share code, notes, and snippets.

@AxelUser
Last active November 2, 2016 21:38
Show Gist options
  • Save AxelUser/323d6dccaa518621870d1dc6f4f132a3 to your computer and use it in GitHub Desktop.
Save AxelUser/323d6dccaa518621870d1dc6f4f132a3 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using AngleSharp;
using System.Text.RegularExpressions;
using AngleSharp.Dom;
using AngleSharp.Extensions;
namespace HabrProxy.Controllers
{
public class ProxyController : Controller
{
// GET: Proxy
public async Task<ActionResult> Index()
{
const string habrHost = "https://habrahabr.ru";
string url = Request.Url.PathAndQuery; //url для проксирования.
if (url.Contains(".")) //условие для файлов.
{
return new RedirectResult(habrHost + url);
}
else
{
var config = Configuration.Default.WithDefaultLoader(); //настройка парсера.
var address = @"https://habrahabr.ru" + url; //конкатенируем путь с хостом хабра.
var document = await BrowsingContext.New(config).OpenAsync(address); //асинхронно загружаем страницу.
//выносим все скрипты из body
var scriptsInBody = document.QuerySelectorAll("body script").ToList();
var scriptsInBodyHtml = string.Join("\n", scriptsInBody
.Select(s => s.OuterHtml));
var docBody = document.Body;
docBody.Insert(AdjacentPosition.AfterEnd, scriptsInBodyHtml);
scriptsInBody.ForEach(scr => scr.Remove());
string formattedText = $" {docBody.TextContent} "; //костыль для работы регулярки с первым словом (и последним)
//ищем все слова из 6 символов
MatchCollection matches = Regex.Matches(formattedText, "[^A-zА-я]{1}[A-zА-я]{6}[^A-zА-я]{1}");
List<string> words = new List<string>();
string newPageHtml = docBody.OuterHtml;
//собираем уникальные значения
foreach (Match m in matches)
{
if (!words.Contains(m.Value))
{
string wordInText = Regex.Match(m.Value, "[A-zА-я]{6}").Value; //слово в тексте.
string wordInHtml = Regex.Match(newPageHtml, "[^A-zА-я]{1}" + wordInText + "[^A-zА-я\u2122]{1}").Value; //слово в HTML.
if (!wordInHtml.Contains("\u2122") && !string.IsNullOrEmpty(wordInHtml)) //дополнительное условие для устранения ошибок.
{
//добавляем к каждому слову трейдмарк
newPageHtml = newPageHtml.Replace(wordInHtml, wordInHtml.Replace(wordInText, $"{wordInText}\u2122"));
bool has = newPageHtml.Contains(wordInHtml);
words.Add(wordInHtml);
}
}
}
docBody.OuterHtml = newPageHtml;
//собираем текущий хост с портом
string domain = Request.Url.Scheme + System.Uri.SchemeDelimiter + Request.Url.Host
+ (Request.Url.IsDefaultPort ? "" : ":" + Request.Url.Port);
//пытаемся починить шрифты, но из-за CORS всё равно ничего не выйдет
document.QuerySelectorAll("style").ToList().ForEach(s =>
{
string temp = s.InnerHtml;
temp = Regex.Replace(temp, @"url\(", m => m.Value + habrHost);
s.InnerHtml = temp;
});
//ищем на странице все ссылки на Хабр.
var links = document.QuerySelectorAll(@"[href^=""/""]").ToList();
var allHabrLinks = document.QuerySelectorAll(string.Format(@"a[href^=""{0}""]", habrHost))
.ToList();
//меняем хост хабра на хост прокси
allHabrLinks.ForEach(l => l.Attributes["href"]
.Value = l.Attributes["href"].Value.Replace(habrHost, domain));
return Content(document.DocumentElement.OuterHtml); //готово =)
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment