|
|
@@ -1,6 +1,8 @@
|
|
|
package mux
|
|
|
|
|
|
import (
|
|
|
+ "runtime"
|
|
|
+
|
|
|
"v2ray.com/core/common/buf"
|
|
|
"v2ray.com/core/common/net"
|
|
|
"v2ray.com/core/common/serial"
|
|
|
@@ -30,7 +32,7 @@ func NewResponseWriter(id uint16, writer buf.Writer) *Writer {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-func (w *Writer) writeInternal(mb buf.MultiBuffer) error {
|
|
|
+func (w *Writer) getNextFrameMeta() FrameMetadata {
|
|
|
meta := FrameMetadata{
|
|
|
SessionID: w.id,
|
|
|
Target: w.dest,
|
|
|
@@ -42,35 +44,51 @@ func (w *Writer) writeInternal(mb buf.MultiBuffer) error {
|
|
|
meta.SessionStatus = SessionStatusNew
|
|
|
}
|
|
|
|
|
|
- hasData := !mb.IsEmpty()
|
|
|
+ return meta
|
|
|
+}
|
|
|
|
|
|
- if hasData {
|
|
|
- meta.Option.Add(OptionData)
|
|
|
+func (w *Writer) writeMetaOnly() error {
|
|
|
+ meta := w.getNextFrameMeta()
|
|
|
+ b := buf.New()
|
|
|
+ if err := b.AppendSupplier(meta.AsSupplier()); err != nil {
|
|
|
+ return err
|
|
|
}
|
|
|
+ runtime.KeepAlive(meta)
|
|
|
+ return w.writer.Write(buf.NewMultiBufferValue(b))
|
|
|
+}
|
|
|
+
|
|
|
+func (w *Writer) writeData(mb buf.MultiBuffer) error {
|
|
|
+ meta := w.getNextFrameMeta()
|
|
|
+ meta.Option.Add(OptionData)
|
|
|
|
|
|
frame := buf.New()
|
|
|
- frame.AppendSupplier(meta.AsSupplier())
|
|
|
+ if err := frame.AppendSupplier(meta.AsSupplier()); err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ runtime.KeepAlive(meta)
|
|
|
|
|
|
mb2 := buf.NewMultiBuffer()
|
|
|
mb2.Append(frame)
|
|
|
|
|
|
- if hasData {
|
|
|
- frame.AppendSupplier(serial.WriteUint16(uint16(mb.Len())))
|
|
|
- mb2.AppendMulti(mb)
|
|
|
+ if err := frame.AppendSupplier(serial.WriteUint16(uint16(mb.Len()))); err != nil {
|
|
|
+ return err
|
|
|
}
|
|
|
+
|
|
|
+ mb2.AppendMulti(mb)
|
|
|
return w.writer.Write(mb2)
|
|
|
}
|
|
|
|
|
|
func (w *Writer) Write(mb buf.MultiBuffer) error {
|
|
|
+ if mb.IsEmpty() {
|
|
|
+ return w.writeMetaOnly()
|
|
|
+ }
|
|
|
+
|
|
|
const chunkSize = 8 * 1024
|
|
|
- for {
|
|
|
+ for !mb.IsEmpty() {
|
|
|
slice := mb.SliceBySize(chunkSize)
|
|
|
- if err := w.writeInternal(slice); err != nil {
|
|
|
+ if err := w.writeData(slice); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
- if mb.IsEmpty() {
|
|
|
- break
|
|
|
- }
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
|
@@ -83,6 +101,7 @@ func (w *Writer) Close() {
|
|
|
|
|
|
frame := buf.New()
|
|
|
frame.AppendSupplier(meta.AsSupplier())
|
|
|
+ runtime.KeepAlive(meta)
|
|
|
|
|
|
w.writer.Write(buf.NewMultiBufferValue(frame))
|
|
|
}
|