You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

72 lines
2.4 KiB

  1. #if !NET20
  2. using System.Text;
  3. using System.Text.RegularExpressions;
  4. namespace Apewer.WebSocket
  5. {
  6. internal class RequestParser
  7. {
  8. const string pattern = @"^(?<method>[^\s]+)\s(?<path>[^\s]+)\sHTTP\/1\.1\r\n" + // request line
  9. @"((?<field_name>[^:\r\n]+):(?([^\r\n])\s)*(?<field_value>[^\r\n]*)\r\n)+" + //headers
  10. @"\r\n" + //newline
  11. @"(?<body>.+)?";
  12. const string FlashSocketPolicyRequestPattern = @"^[<]policy-file-request\s*[/][>]";
  13. private static readonly Regex _regex = new Regex(pattern, RegexOptions.IgnoreCase | RegexOptions.Compiled);
  14. private static readonly Regex _FlashSocketPolicyRequestRegex = new Regex(FlashSocketPolicyRequestPattern, RegexOptions.IgnoreCase | RegexOptions.Compiled);
  15. public static HttpRequest Parse(byte[] bytes)
  16. {
  17. return Parse(bytes, "ws");
  18. }
  19. public static HttpRequest Parse(byte[] bytes, string scheme)
  20. {
  21. // Check for websocket request header
  22. var body = Encoding.UTF8.GetString(bytes);
  23. Match match = _regex.Match(body);
  24. if (!match.Success)
  25. {
  26. // No websocket request header found, check for a flash socket policy request
  27. match = _FlashSocketPolicyRequestRegex.Match(body);
  28. if (match.Success)
  29. {
  30. // It's a flash socket policy request, so return
  31. return new HttpRequest
  32. {
  33. Body = body,
  34. Bytes = bytes
  35. };
  36. }
  37. else
  38. {
  39. return null;
  40. }
  41. }
  42. var request = new HttpRequest
  43. {
  44. Method = match.Groups["method"].Value,
  45. Path = match.Groups["path"].Value,
  46. Body = match.Groups["body"].Value,
  47. Bytes = bytes,
  48. Scheme = scheme
  49. };
  50. var fields = match.Groups["field_name"].Captures;
  51. var values = match.Groups["field_value"].Captures;
  52. for (var i = 0; i < fields.Count; i++)
  53. {
  54. var name = fields[i].ToString();
  55. var value = values[i].ToString();
  56. request.Headers[name] = value;
  57. }
  58. return request;
  59. }
  60. }
  61. }
  62. #endif