aboutsummaryrefslogtreecommitdiff
path: root/Plugins.Essentials/src/FileProcessArgs.cs
blob: dae695be326ddd805518b8a2aa02591c9306d344 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/*
* Copyright (c) 2022 Vaughn Nugent
* 
* Library: VNLib
* Package: VNLib.Plugins.Essentials
* File: FileProcessArgs.cs 
*
* FileProcessArgs.cs is part of VNLib.Plugins.Essentials which is part of the larger 
* VNLib collection of libraries and utilities.
*
* VNLib.Plugins.Essentials is free software: you can redistribute it and/or modify 
* it under the terms of the GNU Affero General Public License as 
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* VNLib.Plugins.Essentials is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program.  If not, see https://www.gnu.org/licenses/.
*/

using System;
using System.Net;

namespace VNLib.Plugins.Essentials
{
    /// <summary>
    /// Server routine to follow after processing selector 
    /// </summary>
    public enum FpRoutine
    {
        /// <summary>
        /// There was an error during processing and the server should immediatly respond with a <see cref="HttpStatusCode.InternalServerError"/> error code
        /// </summary>
        Error,
        /// <summary>
        /// The server should continue the file read operation with the current information
        /// </summary>
        Continue,
        /// <summary>
        /// The server should redirect the conneciton to an alternate location
        /// </summary>
        Redirect,
        /// <summary>
        /// The server should immediatly respond with a <see cref="HttpStatusCode.Forbidden"/> error code
        /// </summary>
        Deny,
        /// <summary>
        /// The server should fulfill the reqeest by sending the contents of an alternate file location (if it exists) with the existing connection
        /// </summary>
        ServeOther,
        /// <summary>
        /// The server should immediatly respond with a <see cref="HttpStatusCode.NotFound"/> error code
        /// </summary>
        NotFound,
        /// <summary>
        /// Serves another file location that must be a trusted fully qualified location
        /// </summary>
        ServeOtherFQ,
        /// <summary>
        /// The connection does not require a file to be processed
        /// </summary>
        VirtualSkip,
    }

    /// <summary>
    /// Specifies operations the file processor will follow during request handling
    /// </summary>
    public readonly struct FileProcessArgs : IEquatable<FileProcessArgs>
    {
        /// <summary>
        /// Signals the file processor should complete with a <see cref="FpRoutine.Deny"/> routine
        /// </summary>
        public static readonly FileProcessArgs Deny = new (FpRoutine.Deny);
        /// <summary>
        /// Signals the file processor should continue with intended/normal processing of the request
        /// </summary>
        public static readonly FileProcessArgs Continue = new (FpRoutine.Continue);
        /// <summary>
        /// Signals the file processor should complete with a <see cref="FpRoutine.Error"/> routine
        /// </summary>
        public static readonly FileProcessArgs Error = new (FpRoutine.Error);
        /// <summary>
        /// Signals the file processor should complete with a <see cref="FpRoutine.NotFound"/> routine
        /// </summary>
        public static readonly FileProcessArgs NotFound = new (FpRoutine.NotFound);
        /// <summary>
        /// Signals the file processor should not process the connection
        /// </summary>
        public static readonly FileProcessArgs VirtualSkip = new (FpRoutine.VirtualSkip);
        /// <summary>
        /// The routine the file processor should execute
        /// </summary>
        public readonly FpRoutine Routine { get; init; }
        /// <summary>
        /// An optional alternate path for the given routine
        /// </summary>
        public readonly string Alternate { get; init; }

        /// <summary>
        /// Initializes a new <see cref="FileProcessArgs"/> with the specified routine
        /// and empty <see cref="Alternate"/> path
        /// </summary>
        /// <param name="routine">The file processing routine to execute</param>
        public FileProcessArgs(FpRoutine routine)
        {
            this.Routine = routine;
            this.Alternate = string.Empty;
        }
        /// <summary>
        /// Initializes a new <see cref="FileProcessArgs"/> with the specified routine
        /// and alternate path
        /// </summary>
        /// <param name="routine"></param>
        /// <param name="alternatePath"></param>
        public FileProcessArgs(FpRoutine routine, string alternatePath)
        {
            this.Routine = routine;
            this.Alternate = alternatePath;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        /// <returns></returns>
        public static bool operator == (FileProcessArgs arg1, FileProcessArgs arg2)
        {
            return arg1.Equals(arg2);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        /// <returns></returns>
        public static bool operator != (FileProcessArgs arg1, FileProcessArgs arg2)
        {
            return !arg1.Equals(arg2);
        }
        ///<inheritdoc/>
        public bool Equals(FileProcessArgs other)
        {
            //make sure the routine types match
            if (Routine != other.Routine)
            {
                return false;
            }
            //Next make sure the hashcodes of the alternate paths match
            return (Alternate?.GetHashCode(StringComparison.OrdinalIgnoreCase)) == (other.Alternate?.GetHashCode(StringComparison.OrdinalIgnoreCase));
        }
        ///<inheritdoc/>
        public override bool Equals(object obj)
        {
            return obj is FileProcessArgs args && Equals(args);
        }
        /// <summary>
        /// <inheritdoc/>
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
    }
}