@@ -103,8 +103,10 @@ impl Config {
103
103
}
104
104
}
105
105
106
- fn to_str ( buf : & [ u8 ] ) -> & str {
107
- std:: str:: from_utf8 ( buf) . unwrap_or ( "[invalid utf-8]" )
106
+ fn to_str ( buf : & [ u8 ] ) -> std:: borrow:: Cow < ' _ , str > {
107
+ //&str {
108
+ //std::str::from_utf8(buf).unwrap_or("[invalid utf-8]")
109
+ String :: from_utf8_lossy ( buf)
108
110
}
109
111
110
112
async fn handle_connection ( mut stream : tokio:: net:: TcpStream , client_addr : SocketAddr , local_addr : SocketAddr , config : CloneableConfig ) -> Result < ( ) > {
@@ -148,7 +150,11 @@ async fn handle_connection(mut stream: tokio::net::TcpStream, client_addr: Socke
148
150
if !direct_tls {
149
151
let mut stream_open = Vec :: new ( ) ;
150
152
151
- while let Ok ( n) = stream. read ( in_filter. current_buf ( ) ) . await {
153
+ let ( in_rd, mut in_wr) = stream. split ( ) ;
154
+ // we naively read 1 byte at a time, which buffering significantly speeds up
155
+ let mut in_rd = tokio:: io:: BufReader :: with_capacity ( IN_BUFFER_SIZE , in_rd) ;
156
+
157
+ while let Ok ( n) = in_rd. read ( in_filter. current_buf ( ) ) . await {
152
158
if n == 0 {
153
159
bail ! ( "stream ended before open" ) ;
154
160
}
@@ -160,32 +166,36 @@ async fn handle_connection(mut stream: tokio::net::TcpStream, client_addr: Socke
160
166
continue ;
161
167
} else if buf. starts_with ( b"<stream:stream " ) {
162
168
debug ! ( "> {} '{}'" , client_addr, to_str( & stream_open) ) ;
163
- stream . write_all ( & stream_open) . await ?;
169
+ in_wr . write_all ( & stream_open) . await ?;
164
170
stream_open. clear ( ) ;
165
171
166
172
// gajim seems to REQUIRE an id here...
167
173
let buf = if buf. contains_seq ( b"id=" ) {
168
- buf. replace ( b" id='" , b" id='xmpp-proxy" )
169
- . replace ( br#" id=""# , br#" id="xmpp-proxy"# )
170
- . replace ( b" to=" , br#" bla toblala="# )
171
- . replace ( b" from=" , b" to=" )
172
- . replace ( br#" bla toblala="# , br#" from="# )
174
+ buf. replace_first ( b" id='" , b" id='xmpp-proxy" )
175
+ . replace_first ( br#" id=""# , br#" id="xmpp-proxy"# )
176
+ . replace_first ( b" to=" , br#" bla toblala="# )
177
+ . replace_first ( b" from=" , b" to=" )
178
+ . replace_first ( br#" bla toblala="# , br#" from="# )
173
179
} else {
174
- buf. replace ( b" to=" , br#" bla toblala="# )
175
- . replace ( b" from=" , b" to=" )
176
- . replace ( br#" bla toblala="# , br#" id='xmpp-proxy' from="# )
180
+ buf. replace_first ( b" to=" , br#" bla toblala="# )
181
+ . replace_first ( b" from=" , b" to=" )
182
+ . replace_first ( br#" bla toblala="# , br#" id='xmpp-proxy' from="# )
177
183
} ;
178
184
179
185
debug ! ( "> {} '{}'" , client_addr, to_str( & buf) ) ;
180
- stream. write_all ( & buf) . await ?;
181
-
182
- stream
183
- . write_all ( br###"<features xmlns="http://etherx.jabber.org/streams"><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"><required/></starttls></features>"### )
184
- . await ?;
185
- stream. flush ( ) . await ?;
186
+ in_wr. write_all ( & buf) . await ?;
187
+
188
+ // ejabberd never sends <starttls/> with the first, only the second?
189
+ //let buf = br###"<features xmlns="http://etherx.jabber.org/streams"><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"><required/></starttls></features>"###;
190
+ let buf = br###"<stream:features><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"><required/></starttls></stream:features>"### ;
191
+ debug ! ( "> {} '{}'" , client_addr, to_str( buf) ) ;
192
+ in_wr. write_all ( buf) . await ?;
193
+ in_wr. flush ( ) . await ?;
186
194
} else if buf. starts_with ( b"<starttls " ) {
187
- stream. write_all ( br###"<proceed xmlns="urn:ietf:params:xml:ns:xmpp-tls" />"### ) . await ?;
188
- stream. flush ( ) . await ?;
195
+ let buf = br###"<proceed xmlns="urn:ietf:params:xml:ns:xmpp-tls" />"### ;
196
+ debug ! ( "> {} '{}'" , client_addr, to_str( buf) ) ;
197
+ in_wr. write_all ( buf) . await ?;
198
+ in_wr. flush ( ) . await ?;
189
199
break ;
190
200
} else {
191
201
bail ! ( "bad pre-tls stanza: {}" , to_str( & buf) ) ;
@@ -197,7 +207,6 @@ async fn handle_connection(mut stream: tokio::net::TcpStream, client_addr: Socke
197
207
let stream = config. acceptor . accept ( stream) . await ?;
198
208
199
209
let ( in_rd, mut in_wr) = tokio:: io:: split ( stream) ;
200
-
201
210
// we naively read 1 byte at a time, which buffering significantly speeds up
202
211
let mut in_rd = tokio:: io:: BufReader :: with_capacity ( IN_BUFFER_SIZE , in_rd) ;
203
212
@@ -396,7 +405,7 @@ impl StanzaFilter {
396
405
//println!("b: '{}', cnt: {}, tag_cnt: {}, self.buf.len(): {}", b as char, self.cnt, self.tag_cnt, self.buf.len());
397
406
self . cnt += 1 ;
398
407
if self . cnt == self . buf_size {
399
- bail ! ( "stanza too big" ) ;
408
+ bail ! ( "stanza too big: {}" , to_str ( & self . buf ) ) ;
400
409
}
401
410
Ok ( None )
402
411
}
0 commit comments