11import * as _ from 'lodash' ;
2- import { observable , action } from 'mobx' ;
2+ import { observable , action , computed } from 'mobx' ;
33
44import {
55 InputRequest ,
66 InputResponse ,
77 InputWebSocketMessage ,
88 InputWebSocketClose ,
9- InputFailedRequest
9+ InputFailedRequest ,
10+ InputRuleEventDataMap
1011} from '../../types' ;
1112
1213import { ApiStore } from '../api/api-store' ;
1314import { StreamMessage } from '../events/stream-message' ;
1415import { HttpExchange } from '../http/http-exchange' ;
1516
17+ import { WebSocketOriginalView , WebSocketTransformedView , WebSocketView } from './websocket-views' ;
18+ import { UpstreamWebSocket } from './upstream-websocket' ;
19+
1620// A websocket stream is an HTTP exchange (the initial setup, or even rejection), but
1721// may include a series of many ongoing messages and a final websocket close event,
1822// if the initial websocket connection is successful.
19- export class WebSocketStream extends HttpExchange {
23+ export class WebSocketStream extends HttpExchange implements WebSocketView {
24+
2025 constructor ( request : InputRequest , apiStore : ApiStore ) {
2126 super ( request , apiStore ) ;
2227 this . searchIndex += '\nwebsocket' ;
@@ -26,11 +31,43 @@ export class WebSocketStream extends HttpExchange {
2631 return true ;
2732 }
2833
34+ declare public upstream : UpstreamWebSocket | undefined ;
35+
36+ // These are the same as HttpExchangeViewBase, but need to be copied here (because we're not a _view_,
37+ // we're original, and TS has no proper mixin support).
38+ @computed
39+ get original ( ) : WebSocketView {
40+ if ( ! this . upstream ) return this ;
41+
42+ // If the request is original, then upstream data matches original data
43+ // I.e. only possible transform was after all upstream data
44+ if ( ! this . upstream . wasRequestTransformed ) {
45+ return this . upstream ;
46+ } else {
47+ return new WebSocketOriginalView ( this . downstream , this . apiStore ) ;
48+ }
49+ }
50+
51+ @computed
52+ get transformed ( ) : WebSocketView {
53+ if ( ! this . upstream ) return this ;
54+
55+ // If the response is original, then upstream data matches transformed data
56+ // I.e. all transforms happened before any upstream data
57+ if ( ! this . upstream ?. wasResponseTransformed ) {
58+ return this . upstream ;
59+ } else {
60+ return new WebSocketTransformedView ( this . downstream , this . apiStore ) ;
61+ }
62+ }
63+
2964 @observable
3065 private accepted = false ;
66+ get wasAccepted ( ) { return this . accepted ; }
3167
3268 @observable
3369 private subprotocol : string | undefined ;
70+ get selectedSubprotocol ( ) { return this . subprotocol ; }
3471
3572 @action
3673 setAccepted ( response : InputResponse ) {
@@ -41,14 +78,6 @@ export class WebSocketStream extends HttpExchange {
4178 Object . assign ( this . timingEvents , response . timingEvents ) ;
4279 }
4380
44- wasAccepted ( ) {
45- return this . accepted ;
46- }
47-
48- get selectedSubprotocol ( ) {
49- return this . subprotocol ;
50- }
51-
5281 @observable
5382 readonly messages : Array < StreamMessage > = [ ] ;
5483
@@ -73,7 +102,7 @@ export class WebSocketStream extends HttpExchange {
73102 }
74103
75104 markAborted ( request : InputFailedRequest ) {
76- if ( ! this . wasAccepted ( ) ) {
105+ if ( ! this . wasAccepted ) {
77106 // An abort before accept acts exactly as in normal HTTP
78107 return super . markAborted ( request ) ;
79108 } else {
@@ -88,6 +117,16 @@ export class WebSocketStream extends HttpExchange {
88117 }
89118 }
90119
120+ // The assorted normal upstreamFromUpstream... methods will never be called, as the server side
121+ // is completely different, so UpstreamHttpExchange will never be populated by the base class.
122+
123+ updateWithUpstreamConnect ( params : InputRuleEventDataMap [ 'passthrough-websocket-connect' ] ) {
124+ if ( ! this . upstream ) {
125+ this . upstream = new UpstreamWebSocket ( this , this . apiStore ) ;
126+ }
127+ this . upstream . updateWithRequestHead ( params ) ;
128+ }
129+
91130 cleanup ( ) {
92131 super . cleanup ( ) ;
93132
0 commit comments