1 module hunt.http.codec.websocket.model.extension.AbstractExtension;
2 
3 import hunt.http.codec.websocket.model.Extension;
4 import hunt.http.codec.websocket.model.ExtensionConfig;
5 
6 import hunt.http.WebSocketConnection;
7 import hunt.http.WebSocketFrame;
8 import hunt.http.WebSocketPolicy;
9 
10 import hunt.logging;
11 import hunt.Exceptions;
12 import hunt.util.Appendable;
13 import hunt.util.Common;
14 import hunt.util.AbstractLifecycle;
15 
16 import std.format;
17 
18 /**
19  * 
20  */
21 abstract class AbstractExtension : AbstractLifecycle , Extension {
22     
23     private WebSocketPolicy policy;
24     private ExtensionConfig config;
25     private OutgoingFrames nextOutgoing;
26     private IncomingFrames nextIncoming;
27 
28     this() {
29     }
30 
31     void dump(Appendable ot, string indent) {
32         // incoming
33         dumpWithHeading(ot, indent, "incoming", cast(Object)this.nextIncoming);
34         dumpWithHeading(ot, indent, "outgoing", cast(Object)this.nextOutgoing);
35     }
36 
37     protected void dumpWithHeading(Appendable ot, string indent, string heading, Object bean) {
38         ot.append(indent).append(" ~- ");
39         ot.append(heading).append(" : ");
40         ot.append(bean.toString());
41     }
42 
43     override
44     ExtensionConfig getConfig() {
45         return config;
46     }
47 
48     override
49     string getName() {
50         return config.getName();
51     }
52 
53     IncomingFrames getNextIncoming() {
54         return nextIncoming;
55     }
56 
57     OutgoingFrames getNextOutgoing() {
58         return nextOutgoing;
59     }
60 
61     WebSocketPolicy getPolicy() {
62         return policy;
63     }
64 
65     void incomingError(Exception e) {
66         nextIncomingError(e);
67     }
68 
69     /**
70      * Used to indicate that the extension makes use of the RSV1 bit of the base websocket framing.
71      * <p>
72      * This is used to adjust validation during parsing, as well as a checkpoint against 2 or more extensions all simultaneously claiming ownership of RSV1.
73      *
74      * @return true if extension uses RSV1 for its own purposes.
75      */
76     override
77     bool isRsv1User() {
78         return false;
79     }
80 
81     /**
82      * Used to indicate that the extension makes use of the RSV2 bit of the base websocket framing.
83      * <p>
84      * This is used to adjust validation during parsing, as well as a checkpoint against 2 or more extensions all simultaneously claiming ownership of RSV2.
85      *
86      * @return true if extension uses RSV2 for its own purposes.
87      */
88     override
89     bool isRsv2User() {
90         return false;
91     }
92 
93     /**
94      * Used to indicate that the extension makes use of the RSV3 bit of the base websocket framing.
95      * <p>
96      * This is used to adjust validation during parsing, as well as a checkpoint against 2 or more extensions all simultaneously claiming ownership of RSV3.
97      *
98      * @return true if extension uses RSV3 for its own purposes.
99      */
100     override
101     bool isRsv3User() {
102         return false;
103     }
104 
105     protected void nextIncomingError(Exception e) {
106         this.nextIncoming.incomingError(e);
107     }
108 
109     protected void nextIncomingFrame(WebSocketFrame frame) {
110         tracef("nextIncomingFrame(%s)", frame);
111         this.nextIncoming.incomingFrame(frame);
112     }
113 
114     protected void nextOutgoingFrame(WebSocketFrame frame, Callback callback) {
115         tracef("nextOutgoingFrame(%s)", frame);
116         this.nextOutgoing.outgoingFrame(frame, callback);
117     }
118 
119     void setConfig(ExtensionConfig config) {
120         this.config = config;
121     }
122 
123     override
124     void setNextIncomingFrames(IncomingFrames nextIncoming) {
125         this.nextIncoming = nextIncoming;
126     }
127 
128     override
129     void setNextOutgoingFrames(OutgoingFrames nextOutgoing) {
130         this.nextOutgoing = nextOutgoing;
131     }
132 
133     void setPolicy(WebSocketPolicy policy) {
134         this.policy = policy;
135     }
136 
137     override
138     string toString() {
139         return format("%s[%s]", typeid(this).name, config.getParameterizedName());
140     }
141 }