Создал http server

parent 19bb446f
.idea/
test.txt
bin/
[Dd]ebug
[Oo]bj
example.txt
t.txt

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyHttpServer", "MyHttpServer\MyHttpServer.csproj", "{41E5602C-8DEE-448C-96D6-6E14BAAD4E7E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{41E5602C-8DEE-448C-96D6-6E14BAAD4E7E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{41E5602C-8DEE-448C-96D6-6E14BAAD4E7E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{41E5602C-8DEE-448C-96D6-6E14BAAD4E7E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{41E5602C-8DEE-448C-96D6-6E14BAAD4E7E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
namespace MyHttpServer
{
public class Cat
{
public string Name { get; set; }
public int Age { get; set; }
public Cat(string name, int age)
{
Name = name;
Age = age;
}
public override string ToString()
{
return $"Имя - {Name} | Возраст {Age}";
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Mime;
using System.Reflection;
using System.Drawing;
using System.Drawing.Imaging;
using System.Threading;
using System.Web;
using RazorEngine;
using RazorEngine.Templating;
using Encoding = System.Text.Encoding;
namespace MyHttpServer
{
public class DumbHttpServer
{
private Thread _thread;
private string _siteDir;
private HttpListener _listener;
private int _port;
private readonly List<Cat> _cats = GetCats();
public DumbHttpServer(string path, int port)
{
Initialize(path, port);
}
private void Initialize(string path, int port)
{
_siteDir = path;
_port = port;
_thread = new Thread(Listen);
_thread.Start();
Console.WriteLine($"Сервер запущен на порту {_port}");
Console.WriteLine($"Файлы сайта лежат в каталоге {_siteDir}");
}
private void Listen()
{
_listener = new HttpListener();
_listener.Prefixes.Add($"http://localhost:{_port}/");
_listener.Start();
while (true)
{
try
{
HttpListenerContext context = _listener.GetContext();
Process(context);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
break;
}
}
Stop();
}
private void Process(HttpListenerContext context)
{
string fileName = context.Request.Url.AbsolutePath;
Console.WriteLine(fileName);
fileName = fileName.Substring(1);
fileName = Path.Combine(_siteDir, fileName);
string content = "";
Stream fileStream;
byte[] htmlBytes;
if (context.Request.HttpMethod == "POST" && context.Request.Url.ToString().Contains("Add"))
{
Stream body = context.Request.InputStream;
StreamReader reader = new StreamReader(body, Encoding.UTF8);
string query = reader.ReadToEnd();
if (query.Contains("%"))
query = HttpUtility.UrlDecode(query, Encoding.UTF8);
string[] subquery = query.Split("&");
string name = subquery[0].Substring(subquery[0].IndexOf("=") + 1);
int age = Convert.ToInt32(subquery[1].Substring(subquery[0].IndexOf("=") + 1));
_cats.Add(new Cat(name, age));
HttpListenerResponse response = context.Response;
reader.Close();
body.Close();
response.Redirect("http://localhost:7777/cats.html");
response.Close();
}
else
{
if (File.Exists(fileName))
{
try
{
if (fileName.Contains(".html"))
{
content = BuildHtml(fileName);
htmlBytes = Encoding.UTF8.GetBytes(content);
}
else
{
htmlBytes = File.ReadAllBytes(fileName);
}
fileStream = new MemoryStream(htmlBytes);
context.Response.ContentType = GetContentType(fileName);
context.Response.ContentLength64 = fileStream.Length;
byte[] buffer = new byte[16 * 1024];
int dataLength;
do
{
dataLength = fileStream.Read(buffer, 0, buffer.Length);
context.Response.OutputStream.Write(buffer, 0, dataLength);
} while (dataLength > 0);
fileStream.Close();
context.Response.StatusCode = (int) HttpStatusCode.OK;
context.Response.OutputStream.Flush();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
context.Response.StatusCode = (int) HttpStatusCode.InternalServerError;
}
}
else
{
context.Response.StatusCode = (int) HttpStatusCode.NotFound;
}
context.Response.OutputStream.Close();
}
}
private static List<Cat> GetCats()
{
List<Cat> cats = new List<Cat>();
cats.Add(new Cat("Tom", 10));
cats.Add(new Cat("Tom", 10));
cats.Add(new Cat("Tom", 10));
cats.Add(new Cat("Tom", 10));
cats.Add(new Cat("Tom", 10));
cats.Add(new Cat("Tom", 10));
cats.Add(new Cat("Jerry", 2));
cats.Add(new Cat("Simon", 2));
return cats;
}
private string BuildHtml(string fileName)
{
string html = "";
string layoutPath = Path.Combine(_siteDir, "layout.html");
string filePath = Path.Combine(_siteDir, fileName);
var razorService = Engine.Razor;
if (!razorService.IsTemplateCached("layout", null))
razorService.AddTemplate("layout", File.ReadAllText(layoutPath));
if (!razorService.IsTemplateCached(fileName, null))
{
razorService.AddTemplate(fileName, File.ReadAllText(filePath));
razorService.Compile(fileName);
}
html = razorService.Run(fileName, null, new
{
indexTitle = "Заголовок главной страницы",
page1 = "Первая страница",
page2 = "Вторая страница",
cats = _cats
});
return html;
}
private string GetContentType(string fileName)
{
var dictionary = new Dictionary<string, string> {
{".css", "text/css"},
{".html", "text/html"},
{".ico", "image/x-icon"},
{".js", "application/x-javascript"},
{".json", "application/json"},
{".png", "image/png"}
};
string contentType = "";
string fileExtension = Path.GetExtension(fileName);
dictionary.TryGetValue(fileExtension, out contentType);
return contentType;
}
public void Stop()
{
_thread.Abort();
_listener.Stop();
}
}
}
\ No newline at end of file
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<LangVersion>9</LangVersion>
</PropertyGroup>
<ItemGroup>
<None Update="site\index.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="site\page1.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="site\page2.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="site\style.css">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="site\layout.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="site\cats.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="site\images\cat.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="site\aboutCat.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Razor" Version="2.2.0" />
<PackageReference Include="RazorEngine.NetCore" Version="2.2.6" />
</ItemGroup>
<ItemGroup>
<Folder Include="site\images" />
</ItemGroup>
</Project>
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Net;
using System.Text;
using System.Text.Json;
namespace MyHttpServer
{
//Зарезервированные символы
//Главные разделители Gen delims
// : / ? # [ ] @
//Вторичные разделдители (подразделители)
// ! $ & ' ( ) * + , ; =
// . _ ~ aA-zZ 0-9
//[схема":"]путь["?"запрос]["#"фрагмент]
//File://D/file.pdf?page=150
//ftp://username@host.com:80/Home/Files/image.png?
class Program
{
static void Main(string[] args)
{
string currentDir = Directory.GetCurrentDirectory();
string site = currentDir + @"\site";
DumbHttpServer server = new DumbHttpServer(site, 7777);
// HttpListener listener = new HttpListener();
// listener.Prefixes.Add("http://localhost:7777/");
// listener.Start();
// while (true)
// {
// Console.WriteLine("Ожидание подключений");
// HttpListenerContext context = listener.GetContext();
// HttpListenerResponse response = context.Response;
//// if (context.Request.Url.ToString().Contains("Add") && context.Request.HttpMethod == "POST")
//// AddUser(GetData(context));
//// string content = File.ReadAllText("users.txt");
// Stream body = context.Request.InputStream;
// Encoding encoding = context.Request.ContentEncoding;
// StreamReader reader = new StreamReader(body, encoding);
// string content = reader.ReadToEnd();
// Dictionary<string, string> queryDictionary =
// JsonSerializer.Deserialize<Dictionary<string, string>>(content);
//
//
// string responseString = BuildPage(queryDictionary["name"]);
// byte[] buffer = Encoding.UTF8.GetBytes(responseString);
// response.ContentLength64 = buffer.Length;
// Stream output = response.OutputStream;
// output.Write(buffer, 0, buffer.Length);
// output.Close();
// }
//
//
//
// listener.Stop();
}
static string GetData(HttpListenerContext context)
{
NameValueCollection collection = context.Request.QueryString;
string result = "-------------\n";
foreach (var key in collection.AllKeys)
{
result += $"<p>{key} : {collection[key]}</p>\n";
}
result += "-------------\n";
return result;
}
static string BuildPage(string content)
{
string responseString = "<html>" +
"<head>" +
"<meta charset='UTF-8'" +
"</head>\n" +
$"{content}" +
"</html>";
return responseString;
}
static void AddUser(string user)
{
if(!File.Exists("users.txt"))
File.WriteAllText("users.txt", user);
else
File.AppendAllText("users.txt", user);
}
}
}
@{
Layout = "layout";
}
<a href="http://localhost:7777/cats.html">На главную</a>
\ No newline at end of file
@{
Layout = "layout";
}
<h1>Список котов</h1>
@foreach(var cat in @Model.cats){
<p>@cat</p>
<a href="http://localhost:7777/aboutCat.html?name=@cat.Name">Подробнее</a>
}
<form action="http://localhost:7777/Add/cats.html" method="post">
<label for="name">Имя кота</label>
<input id="name" name="name" type="text">
<label for="age">Возраст кота</label>
<input id="age" name="age" type="text">
<button type="submit">Создать</button>
</form>
\ No newline at end of file
@{
Layout = "layout";
}
<h1>@Model.indexTitle</h1>
@for(var i = 0; i < 10; i++){
<p>Line @i</p>
}
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="style.css">
<title></title>
</head>
<body>
<div class="topnav">
<div class="container">
<a href="index.html">Index</a>
<a href="page1.html">Page 1</a>
<a href="page2.html">Page 2</a>
<a href="cats.html">Cats</a>
</div>
</div>
<div class="container">
@RenderBody()
</div>
</body>
</html>
\ No newline at end of file
@{
Layout = "layout";
}
<h2>@Model.page1</h2>
\ No newline at end of file
@{
Layout = "layout";
}
<h2>@Model.page2</h2>
\ No newline at end of file
h1 {
color: red;
}
.container{
max-width: 900px;
margin: 0 auto;
}
/* Add a black background color to the top navigation */
.topnav {
position: relative;
background-color: #333;
overflow: hidden;
}
.image{
width: 250px;
}
img{
width: 100%;
height: auto;
}
/* Style the links inside the navigation bar */
.topnav a {
float: left;
color: #f2f2f2;
text-align: center;
padding: 14px 16px;
text-decoration: none;
font-size: 17px;
}
/* Change the color of links on hover */
.topnav a:hover {
background-color: #ddd;
color: black;
}
/* Add a color to the active/current link */
.topnav a.active {
background-color: #4CAF50;
color: white;
}
/* Centered section inside the top navigation */
.topnav-centered a {
float: none;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
/* Right-aligned section inside the top navigation */
.topnav-right {
float: right;
}
/* Responsive navigation menu - display links on top of each other instead of next to each other (for mobile devices) */
@media screen and (max-width: 600px) {
.topnav a, .topnav-right {
float: none;
display: block;
}
.topnav-centered a {
position: relative;
top: 0;
left: 0;
transform: none;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment