@@ -104,47 +104,77 @@ func (up *URLPrefixer) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
104104
105105 // setup a buffer which is the max length of our target attrs
106106 b := make ([]byte , up .maxlen (up .Attrs ... ))
107- io .ReadFull (nextRead , b ) // prime the buffer with the start of the input
108- buf := bytes .NewBuffer (b )
107+ n , _ := io .ReadFull (nextRead , b ) // prime the buffer with the start of the input
108+ buf := bytes .NewBuffer (b [: n ] )
109109
110110 // Read next handler's response byte by byte
111111 src := bufio .NewScanner (nextRead )
112112 src .Split (bufio .ScanBytes )
113113 for {
114114 window := buf .Bytes ()
115115
116+ if len (window ) == 0 {
117+ flusher .Flush ()
118+ break
119+ }
120+
116121 // advance a byte if window is not a src attr
117- if matchlen , match := up .match (window , up .Attrs ... ); matchlen == 0 {
122+ matchlen , match := up .match (window , up .Attrs ... )
123+ if matchlen == 0 {
124+ rw .Write (buf .Next (1 ))
125+ writtenCount ++
126+
118127 if src .Scan () {
119- // shift the next byte into buf
120- rw .Write (buf .Next (1 ))
121- writtenCount ++
122128 buf .Write (src .Bytes ())
129+ } else if err := src .Err (); err != nil {
130+ up .Logger .
131+ WithField ("component" , "prefixer" ).
132+ Error ("Error encountered while scanning: err:" , err )
133+ }
123134
124- if writtenCount >= ChunkSize {
125- flusher .Flush ()
126- writtenCount = 0
127- }
128- } else {
129- if err := src .Err (); err != nil {
130- up .Logger .
131- WithField ("component" , "prefixer" ).
132- Error ("Error encountered while scanning: err:" , err )
133- }
134- rw .Write (window )
135+ if writtenCount >= ChunkSize {
135136 flusher .Flush ()
136- break
137+ writtenCount = 0
137138 }
139+
138140 continue
139- } else {
140- buf .Next (matchlen ) // advance to the relative URL
141- for i := 0 ; i < matchlen ; i ++ {
142- src .Scan ()
143- buf .Write (src .Bytes ())
141+ }
142+
143+ buf .Next (matchlen ) // advance to the relative URL
144+ for i := 0 ; i < matchlen ; i ++ {
145+ src .Scan ()
146+ buf .Write (src .Bytes ())
147+ }
148+ if bytes .Equal (match , []byte (`src=/` )) {
149+ if bytes .HasPrefix (buf .Bytes (), []byte (`/` )) {
150+ rw .Write (match )
151+ continue
152+ }
153+ rw .Write ([]byte (`src=` ))
154+ io .WriteString (rw , up .Prefix )
155+ continue
156+ }
157+ if bytes .Equal (match , []byte (`href=/` )) {
158+ if bytes .HasPrefix (buf .Bytes (), []byte (`/` )) {
159+ rw .Write (match )
160+ continue
144161 }
145- rw .Write (match ) // add the src attr to the output
146- io .WriteString (rw , up .Prefix ) // write the prefix
162+ rw .Write ([]byte (`href=` ))
163+ io .WriteString (rw , up .Prefix )
164+ continue
165+ }
166+ if bytes .Equal (match , []byte (`data-basepath` )) {
167+ if len (buf .Bytes ()) > 0 && bytes .ContainsAny (buf .Bytes ()[:1 ], "> \t \r \n " ) {
168+ rw .Write ([]byte (`data-basepath="` ))
169+ io .WriteString (rw , up .Prefix )
170+ rw .Write ([]byte (`"` ))
171+ continue
172+ }
173+ rw .Write (match )
174+ continue
147175 }
176+ rw .Write (match ) // add the src attr to the output
177+ io .WriteString (rw , up .Prefix ) // write the prefix
148178 }
149179}
150180
@@ -154,7 +184,7 @@ func (up *URLPrefixer) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
154184// targets. The matching []byte is also returned as the second return parameter
155185func (up * URLPrefixer ) match (subject []byte , targets ... []byte ) (int , []byte ) {
156186 for _ , target := range targets {
157- if bytes .Equal (subject [:len (target )], target ) {
187+ if len ( subject ) >= len ( target ) && bytes .Equal (subject [:len (target )], target ) {
158188 return len (target ), target
159189 }
160190 }
@@ -186,7 +216,10 @@ func NewDefaultURLPrefixer(prefix string, next http.Handler, lg chronograf.Logge
186216 []byte (`src="` ),
187217 []byte (`href="` ),
188218 []byte (`url(` ),
219+ []byte (`src=/` ),
220+ []byte (`href=/` ),
189221 []byte (`data-basepath="` ), // for forwarding basepath to frontend
222+ []byte (`data-basepath` ),
190223 },
191224 }
192225}
0 commit comments