| | 1 | | namespace Kestrun.Utilities; |
| | 2 | |
|
| | 3 | | /// <summary> |
| | 4 | | /// Common HTTP verbs recognized by the framework. |
| | 5 | | /// </summary> |
| | 6 | | /// <remarks> |
| | 7 | | /// This enum includes standard HTTP methods as well as WebDAV extensions. |
| | 8 | | /// It is designed to be extensible for future HTTP methods. |
| | 9 | | /// The enum values correspond to the HTTP methods as defined in various RFCs: |
| | 10 | | /// RFC 4918 - HTTP Extensions for WebDAV |
| | 11 | | /// RFC 3744 - WebDAV Access Control Protocol |
| | 12 | | /// RFC 3253 - Versioning Extensions to WebDAV |
| | 13 | | /// RFC 5323 - WebDAV SEARCH |
| | 14 | | /// RFC 5842 - WebDAV Ordered Collections |
| | 15 | | /// RFC 5689 - WebDAV Bindings |
| | 16 | | /// RFC 6620 - WebDAV MERGE |
| | 17 | | /// RFC 5689 - WebDAV BIND |
| | 18 | | /// RFC 4918 - WebDAV |
| | 19 | | /// RFC 7231 - HTTP/1.1 Semantics and Content |
| | 20 | | /// RFC 7232 - HTTP/1.1 Conditional Requests |
| | 21 | | /// RFC 7233 - HTTP/1.1 Range Requests |
| | 22 | | /// RFC 7234 - HTTP/1.1 Caching |
| | 23 | | /// RFC 7235 - HTTP/1.1 Authentication |
| | 24 | | /// </remarks> |
| | 25 | | [Flags] |
| | 26 | | public enum HttpVerb |
| | 27 | | { |
| | 28 | | /// <summary> |
| | 29 | | /// Represents the HTTP GET method. |
| | 30 | | /// </summary> |
| | 31 | | Get = 1 << 0, |
| | 32 | | /// <summary> |
| | 33 | | /// Represents the HTTP HEAD method. |
| | 34 | | /// </summary> |
| | 35 | | Head = 1 << 1, |
| | 36 | | /// <summary> |
| | 37 | | /// Represents the HTTP POST method. |
| | 38 | | /// </summary> |
| | 39 | | Post = 1 << 2, |
| | 40 | | /// <summary> |
| | 41 | | /// Represents the HTTP PUT method. |
| | 42 | | /// </summary> |
| | 43 | | Put = 1 << 3, |
| | 44 | | /// <summary> |
| | 45 | | /// Represents the HTTP PATCH method. |
| | 46 | | /// </summary> |
| | 47 | | Patch = 1 << 4, |
| | 48 | | /// <summary> |
| | 49 | | /// Represents the HTTP DELETE method. |
| | 50 | | /// </summary> |
| | 51 | | Delete = 1 << 5, |
| | 52 | | /// <summary> |
| | 53 | | /// Represents the HTTP OPTIONS method. |
| | 54 | | /// </summary> |
| | 55 | | Options = 1 << 6, |
| | 56 | | /// <summary> |
| | 57 | | /// Represents the HTTP TRACE method. |
| | 58 | | /// </summary> |
| | 59 | | Trace = 1 << 7, |
| | 60 | | // WebDAV verbs |
| | 61 | | /// <summary> |
| | 62 | | /// Represents the HTTP PROPFIND method (WebDAV). |
| | 63 | | /// </summary> |
| | 64 | | PropFind = 1 << 8, |
| | 65 | | /// <summary> |
| | 66 | | /// Represents the HTTP PROPPATCH method (WebDAV). |
| | 67 | | /// </summary> |
| | 68 | | PropPatch = 1 << 9, |
| | 69 | | /// <summary> |
| | 70 | | /// Represents the HTTP MKCOL method (WebDAV). |
| | 71 | | /// </summary> |
| | 72 | | MkCol = 1 << 10, |
| | 73 | | /// <summary> |
| | 74 | | /// Represents the HTTP COPY method (WebDAV). |
| | 75 | | /// </summary> |
| | 76 | | Copy = 1 << 11, |
| | 77 | | /// <summary> |
| | 78 | | /// Represents the HTTP MOVE method (WebDAV). |
| | 79 | | /// </summary> |
| | 80 | | Move = 1 << 12, |
| | 81 | | /// <summary> |
| | 82 | | /// Represents the HTTP LOCK method (WebDAV). |
| | 83 | | /// </summary> |
| | 84 | | Lock = 1 << 13, |
| | 85 | | /// <summary> |
| | 86 | | /// Represents the HTTP UNLOCK method (WebDAV). |
| | 87 | | /// </summary> |
| | 88 | | Unlock = 1 << 14, |
| | 89 | | /// <summary> |
| | 90 | | /// Represents the HTTP REPORT method (WebDAV). |
| | 91 | | /// </summary> |
| | 92 | | Report = 1 << 15, |
| | 93 | | /// <summary> |
| | 94 | | /// Represents the HTTP ACL method (WebDAV). |
| | 95 | | /// </summary> |
| | 96 | | Acl = 1 << 16, |
| | 97 | | /// <summary> |
| | 98 | | /// Represents the HTTP SEARCH method (WebDAV). |
| | 99 | | /// </summary> |
| | 100 | | Search = 1 << 17, |
| | 101 | | /// <summary> |
| | 102 | | /// Represents the HTTP MERGE method (WebDAV). |
| | 103 | | /// </summary> |
| | 104 | | Merge = 1 << 18, |
| | 105 | | /// <summary> |
| | 106 | | /// Represents the HTTP BIND method (WebDAV). |
| | 107 | | /// </summary> |
| | 108 | | Bind = 1 << 19, |
| | 109 | | /// <summary> |
| | 110 | | /// Represents the HTTP UNBIND method (WebDAV). |
| | 111 | | /// </summary> |
| | 112 | | Unbind = 1 << 20, |
| | 113 | | /// <summary> |
| | 114 | | /// Represents the HTTP REBIND method (WebDAV). |
| | 115 | | /// </summary> |
| | 116 | | Rebind = 1 << 21, |
| | 117 | | /// <summary> |
| | 118 | | /// Represents the HTTP UPDATE method (WebDAV). |
| | 119 | | /// </summary> |
| | 120 | | Update = 1 << 22, |
| | 121 | | /// <summary> |
| | 122 | | /// Represents the HTTP VERSION-CONTROL method (WebDAV). |
| | 123 | | /// </summary> |
| | 124 | | VersionControl = 1 << 23, |
| | 125 | | /// <summary> |
| | 126 | | /// Represents the HTTP CHECKIN method (WebDAV). |
| | 127 | | /// </summary> |
| | 128 | | Checkin = 1 << 24, |
| | 129 | | /// <summary> |
| | 130 | | /// Represents the HTTP CHECKOUT method (WebDAV). |
| | 131 | | /// </summary> |
| | 132 | | Checkout = 1 << 25, |
| | 133 | | /// <summary> |
| | 134 | | /// Represents the HTTP UNCHECKOUT method (WebDAV). |
| | 135 | | /// </summary> |
| | 136 | | Uncheckout = 1 << 26, |
| | 137 | | /// <summary> |
| | 138 | | /// Represents the HTTP MKWORKSPACE method (WebDAV). |
| | 139 | | /// </summary> |
| | 140 | | MkWorkspace = 1 << 27, |
| | 141 | | /// <summary> |
| | 142 | | /// Represents the HTTP LABEL method (WebDAV). |
| | 143 | | /// </summary> |
| | 144 | | Label = 1 << 28, |
| | 145 | | /// <summary> |
| | 146 | | /// Represents the HTTP ORDERPATCH method (WebDAV). |
| | 147 | | /// </summary> |
| | 148 | | OrderPatch = 1 << 29 |
| | 149 | | } |
| | 150 | |
|
| | 151 | | /// <summary> |
| | 152 | | /// Extension methods for the <see cref="HttpVerb"/> enum. |
| | 153 | | /// </summary> |
| | 154 | | public static class HttpVerbExtensions |
| | 155 | | { |
| | 156 | | /// <summary> |
| | 157 | | /// Convert the verb enum to its uppercase HTTP method string. |
| | 158 | | /// </summary> |
| 58 | 159 | | public static string ToMethodString(this HttpVerb v) => v.ToString().ToUpperInvariant(); |
| | 160 | |
|
| | 161 | | /// <summary> |
| | 162 | | /// Convert a HTTP method string to its corresponding HttpVerb enum value. |
| | 163 | | /// </summary> |
| | 164 | | /// <param name="method">The HTTP method string (case-insensitive).</param> |
| | 165 | | /// <returns>The corresponding HttpVerb enum value.</returns> |
| | 166 | | /// <exception cref="ArgumentException">Thrown when the method string is not recognized.</exception> |
| | 167 | | public static HttpVerb FromMethodString(string method) |
| | 168 | | { |
| 25 | 169 | | if (string.IsNullOrWhiteSpace(method)) |
| | 170 | | { |
| 2 | 171 | | throw new ArgumentException("Method cannot be null or whitespace.", nameof(method)); |
| | 172 | | } |
| | 173 | |
|
| | 174 | | // Handle special cases where enum names don't match HTTP method strings |
| 23 | 175 | | var normalizedMethod = method.Trim().ToUpperInvariant() switch |
| 23 | 176 | | { |
| 3 | 177 | | "PROPFIND" => "PropFind", |
| 2 | 178 | | "PROPPATCH" => "PropPatch", |
| 2 | 179 | | "MKCOL" => "MkCol", |
| 3 | 180 | | "VERSION-CONTROL" => "VersionControl", |
| 3 | 181 | | "MKWORKSPACE" => "MkWorkspace", |
| 2 | 182 | | "ORDERPATCH" => "OrderPatch", |
| 8 | 183 | | _ => method.Trim() |
| 23 | 184 | | }; |
| | 185 | |
|
| 23 | 186 | | return Enum.TryParse<HttpVerb>(normalizedMethod, true, out var result) |
| 23 | 187 | | ? result |
| 23 | 188 | | : throw new ArgumentException($"Unknown HTTP method: {method}", nameof(method)); |
| | 189 | | } |
| | 190 | |
|
| | 191 | | /// <summary> |
| | 192 | | /// Try to convert a HTTP method string to its corresponding HttpVerb enum value. |
| | 193 | | /// </summary> |
| | 194 | | /// <param name="method">The HTTP method string (case-insensitive).</param> |
| | 195 | | /// <param name="verb">When this method returns, contains the HttpVerb value if conversion succeeded, or default val |
| | 196 | | /// <returns>true if the conversion succeeded; otherwise, false.</returns> |
| | 197 | | public static bool TryFromMethodString(string method, out HttpVerb verb) |
| | 198 | | { |
| 10 | 199 | | verb = default; |
| | 200 | |
|
| 10 | 201 | | if (string.IsNullOrWhiteSpace(method)) |
| | 202 | | { |
| 0 | 203 | | return false; |
| | 204 | | } |
| | 205 | |
|
| | 206 | | try |
| | 207 | | { |
| 10 | 208 | | verb = FromMethodString(method); |
| 8 | 209 | | return true; |
| | 210 | | } |
| 2 | 211 | | catch (ArgumentException) |
| | 212 | | { |
| 2 | 213 | | return false; |
| | 214 | | } |
| 10 | 215 | | } |
| | 216 | | } |