@@ -50,7 +50,8 @@ import {
5050 WebSocketPassThroughHandler ,
5151 EchoWebSocketHandlerDefinition ,
5252 RejectWebSocketHandlerDefinition ,
53- ListenWebSocketHandlerDefinition
53+ ListenWebSocketHandlerDefinition ,
54+ WebSocketForwardToHostHandler
5455} from '../../model/rules/definitions/websocket-rule-definitions' ;
5556import {
5657 EthereumCallResultHandler ,
@@ -151,7 +152,11 @@ export function HandlerConfiguration(props: {
151152 case 'file' :
152153 return < FromFileResponseHandlerConfig { ...configProps } /> ;
153154 case 'forward-to-host' :
154- return < ForwardToHostHandlerConfig { ...configProps } /> ;
155+ case 'ws-forward-to-host' :
156+ return < ForwardToHostHandlerConfig
157+ { ...configProps }
158+ handlerKey = { handlerKey }
159+ /> ;
155160 case 'passthrough' :
156161 case 'ws-passthrough' :
157162 return < PassThroughHandlerConfig { ...configProps } /> ;
@@ -657,9 +662,14 @@ const UrlInput = styled(TextInput)`
657662
658663@inject ( 'rulesStore' )
659664@observer
660- class ForwardToHostHandlerConfig extends HandlerConfig < ForwardToHostHandler , {
661- rulesStore ?: RulesStore
662- } > {
665+ class ForwardToHostHandlerConfig extends HandlerConfig <
666+ | ForwardToHostHandler
667+ | WebSocketForwardToHostHandler ,
668+ {
669+ rulesStore ?: RulesStore ,
670+ handlerKey : 'forward-to-host' | 'ws-forward-to-host'
671+ }
672+ > {
663673
664674 @observable
665675 private error : Error | undefined ;
@@ -682,9 +692,19 @@ class ForwardToHostHandlerConfig extends HandlerConfig<ForwardToHostHandler, {
682692 }
683693
684694 render ( ) {
685- const { targetHost, updateHostHeader, error, onTargetChange, onUpdateHeaderChange } = this ;
695+ const {
696+ targetHost,
697+ updateHostHeader,
698+ error,
699+ onTargetChange,
700+ onUpdateHeaderChange
701+ } = this ;
686702 const { targetHost : savedTargetHost } = this . props . handler . forwarding ! ;
687703
704+ const messageType = this . props . handlerKey === 'ws-forward-to-host'
705+ ? 'WebSocket'
706+ : 'request' ;
707+
688708 return < ConfigContainer >
689709 < SectionLabel > Replacement host</ SectionLabel >
690710 < UrlInput
@@ -699,7 +719,7 @@ class ForwardToHostHandlerConfig extends HandlerConfig<ForwardToHostHandler, {
699719 value = { updateHostHeader . toString ( ) }
700720 onChange = { onUpdateHeaderChange }
701721 title = { dedent `
702- Most servers will not accept requests that arrive
722+ Most servers will not accept ${ messageType } s that arrive
703723 with the wrong host header, so it's typically useful
704724 to automatically change it to match the new host
705725 ` }
@@ -709,7 +729,7 @@ class ForwardToHostHandlerConfig extends HandlerConfig<ForwardToHostHandler, {
709729 </ ConfigSelect >
710730 { savedTargetHost &&
711731 < ConfigExplanation >
712- All matching requests will be forwarded to { savedTargetHost } ,
732+ All matching { messageType } s will be forwarded to { savedTargetHost } ,
713733 keeping their existing path{
714734 ! savedTargetHost . includes ( '://' ) ? ', protocol,' : ''
715735 } and query string.{
@@ -726,26 +746,47 @@ class ForwardToHostHandlerConfig extends HandlerConfig<ForwardToHostHandler, {
726746 try {
727747 if ( ! this . targetHost ) throw new Error ( 'A target host is required' ) ;
728748
729- const protocolMatch = this . targetHost . match ( / ^ \w + : \/ \/ / ) ;
730- if ( protocolMatch ) {
731- const pathWithoutProtocol = this . targetHost . slice ( protocolMatch [ 0 ] . length ) ;
749+ let urlWithoutProtocol : string ;
732750
733- if ( pathWithoutProtocol . includes ( '/' ) ) {
734- throw new Error ( 'The replacement host shouldn\'t include a path, since it won\'t be used' ) ;
735- }
736- if ( pathWithoutProtocol . includes ( '?' ) ) {
737- throw new Error ( 'The replacement host shouldn\'t include a query string, since it won\'t be used' ) ;
751+ const protocolMatch = this . targetHost . match ( / ^ ( \w + ) : \/ \/ / ) ;
752+ if ( protocolMatch ) {
753+ const validProtocols = this . props . handlerKey === 'ws-forward-to-host'
754+ ? [ 'ws' , 'wss' ]
755+ : [ 'http' , 'https' ] ;
756+
757+ if ( ! validProtocols . includes ( protocolMatch [ 1 ] . toLowerCase ( ) ) ) {
758+ throw new Error (
759+ `The protocol must be either ${ validProtocols [ 0 ] } or ${ validProtocols [ 1 ] } `
760+ ) ;
738761 }
762+
763+ urlWithoutProtocol = this . targetHost . slice ( protocolMatch [ 0 ] . length ) ;
739764 } else {
740- if ( this . targetHost . includes ( '/' ) ) {
741- throw new Error ( 'The replacement host shouldn\'t include a path, since it won\'t be used' ) ;
742- }
743- if ( this . targetHost . includes ( '?' ) ) {
744- throw new Error ( 'The replacement host shouldn\'t include a query string, since it won\'t be used' ) ;
745- }
765+ urlWithoutProtocol = this . targetHost ;
766+ }
767+
768+ if ( urlWithoutProtocol . includes ( '/' ) ) {
769+ throw new Error (
770+ 'The replacement host shouldn\'t include a path, since it won\'t be used'
771+ ) ;
772+ }
773+ if ( urlWithoutProtocol . includes ( '?' ) ) {
774+ throw new Error (
775+ 'The replacement host shouldn\'t include a query string, since it won\'t be used'
776+ ) ;
746777 }
747778
748- this . props . onChange ( new ForwardToHostHandler ( this . targetHost , this . updateHostHeader , this . props . rulesStore ! ) ) ;
779+ const HandlerClass = this . props . handlerKey === 'ws-forward-to-host'
780+ ? WebSocketForwardToHostHandler
781+ : ForwardToHostHandler ;
782+
783+ this . props . onChange (
784+ new HandlerClass (
785+ this . targetHost ,
786+ this . updateHostHeader ,
787+ this . props . rulesStore !
788+ )
789+ ) ;
749790 this . error = undefined ;
750791 } catch ( e ) {
751792 console . log ( e ) ;
0 commit comments