fork(1) download
  1. public class HttpServer
  2. {
  3. private readonly IPEndPoint _ipEndPoint;
  4. private readonly int _serverTasksCount;
  5.  
  6. public HttpServer(IPEndPoint ipEndPoint, int serverTaksCount = 1)
  7. {
  8. if (serverTaksCount < 1)
  9. {
  10. throw new ArgumentException("Invalid task count");
  11. }
  12. _ipEndPoint = ipEndPoint;
  13. _serverTasksCount = serverTaksCount;
  14. }
  15.  
  16. public async Task RunAsync()
  17. {
  18. using Socket serverSocket = new(_ipEndPoint.AddressFamily,
  19. SocketType.Stream,
  20. ProtocolType.Tcp);
  21. serverSocket.Bind(_ipEndPoint);
  22. serverSocket.Listen(_serverTasksCount);
  23. var serverTasks = Enumerable
  24. .Range(0, _serverTasksCount)
  25. .Select(x => AcceptLoop(serverSocket));
  26. await Task.WhenAll(serverTasks);
  27. }
  28.  
  29. private async Task AcceptLoop(Socket serverSocket)
  30. {
  31. while (true)
  32. {
  33. var client = await serverSocket.AcceptAsync();
  34. try
  35. {
  36. await ProcessClient(client);
  37. }
  38. catch (SocketException ex) { }
  39. catch (ObjectDisposedException) { }
  40. catch (IOException) { }
  41. }
  42. }
  43.  
  44. private async Task ProcessClient(Socket client)
  45. {
  46. using NetworkStream clientStream = new(client);
  47. using StreamReader streamReader = new(clientStream);
  48. StringBuilder requestBuffer = new();
  49. do
  50. {
  51. var requestString = await streamReader.ReadLineAsync();
  52. if (requestString.Length == 0) { break; }
  53. requestBuffer.AppendLine(requestString);
  54. } while (true);
  55.  
  56. var isValidRequest = TryParseRequest(requestBuffer, out var request);
  57. if (!isValidRequest)
  58. {
  59. var response1 = "HTTP/1.1 500 Internal";
  60. await client.SendAsync(Encoding.UTF8.GetBytes(response1), SocketFlags.None);
  61. client.Dispose();
  62. return;
  63. }
  64.  
  65. var response = "HTTP/1.1 200 OK\r\n\r\nHello";
  66. await client.SendAsync(Encoding.UTF8.GetBytes(response), SocketFlags.None);
  67. client.Dispose();
  68. }
  69.  
  70. private bool TryParseRequest(StringBuilder requestString, out HttpRequest request)
  71. {
  72. request = default;
  73. using StringReader stringReader = new StringReader(requestString.ToString());
  74. var startString = stringReader.ReadLine().Split(' ');
  75. request = new HttpRequest
  76. {
  77. Method = startString[0],
  78. Path = startString[1],
  79. Protocol = startString[2],
  80. Headers = ParseHeaders(stringReader)
  81. };
  82. return true;
  83. }
  84.  
  85. private Dictionary<string,string> ParseHeaders(StringReader stringReader)
  86. {
  87. Dictionary<string, string> headers = new();
  88. while(true)
  89. {
  90. var str = stringReader.ReadLine();
  91. if (str is null || str.StartsWith("\r\n"))
  92. {
  93. break;
  94. }
  95. var keyValue = str.Split(":", 2, StringSplitOptions.RemoveEmptyEntries);
  96. headers[keyValue[0]] = keyValue[1].Trim();
  97. }
  98. return headers;
  99. }
  100. }
  101. public class HttpRequest
  102. {
  103. public string Method { get; set; }
  104. public string Protocol { get; set; }
  105. public string Path { get; set; }
  106. public string Query { get; set; }
  107. public Dictionary<string, string> Headers { get; set; } = new();
  108. public string Body { get; set; }
  109. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cs(18,18): error CS1525: Unexpected symbol `Socket', expecting `('
prog.cs(20,33): error CS1525: Unexpected symbol `;', expecting `(', `[', or `{'
prog.cs(46,18): error CS1525: Unexpected symbol `NetworkStream', expecting `('
prog.cs(46,51): error CS8124: Tuple must contain at least two elements
prog.cs(46,58): error CS1525: Unexpected symbol `;', expecting `(', `[', or `{'
prog.cs(47,18): error CS1525: Unexpected symbol `StreamReader', expecting `(', `[', or `{'
prog.cs(47,50): error CS8124: Tuple must contain at least two elements
prog.cs(47,63): error CS1525: Unexpected symbol `;', expecting `(', `[', or `{'
prog.cs(48,46): error CS1525: Unexpected symbol `)', expecting `(' or `type'
prog.cs(72,23): error CS1644: Feature `default literal' cannot be used because it is not part of the C# 7.0 language specification
prog.cs(73,18): error CS1525: Unexpected symbol `StringReader', expecting `('
prog.cs(87,53): error CS1525: Unexpected symbol `)', expecting `(' or `type'
prog.cs(91,25): error CS1644: Feature `pattern matching' cannot be used because it is not part of the C# 7.0 language specification
prog.cs(107,70): error CS1014: A get or set accessor expected
Compilation failed: 14 error(s), 0 warnings
stdout
Standard output is empty