1 package main 2 3 import ( 4 "errors" 5 "io" 6 "net/http" 7 "os" 8 9 "golang.org/x/net/websocket" 10 "vimagination.zapto.org/byteio" 11 "vimagination.zapto.org/minewebgen/internal/data" 12 ) 13 14 var transferFuncs = [...]func(Transfer, string, *byteio.StickyLittleEndianReader, *byteio.StickyLittleEndianWriter, *os.File, int64) error{ 15 Transfer.server, 16 Transfer.maps, 17 Transfer.generate, 18 Transfer.generator, 19 } 20 21 type downloadProgress struct { 22 io.Reader 23 *byteio.StickyLittleEndianWriter 24 } 25 26 func (d downloadProgress) Read(b []byte) (int, error) { 27 n, err := d.Reader.Read(b) 28 d.WriteUint8(1) 29 d.WriteInt32(int32(n)) 30 return n, err 31 } 32 33 type Transfer struct { 34 c *Config 35 } 36 37 func (t Transfer) Websocket(conn *websocket.Conn) { 38 conn.PayloadType = websocket.BinaryFrame 39 r := byteio.StickyLittleEndianReader{Reader: conn} 40 w := byteio.StickyLittleEndianWriter{Writer: conn} 41 42 err := t.handle(&r, &w) 43 if err != nil { 44 writeError(&w, err) 45 } 46 } 47 48 func (t Transfer) handle(r *byteio.StickyLittleEndianReader, w *byteio.StickyLittleEndianWriter) error { 49 transferType := r.ReadUint8() 50 51 if transferType>>1 > uint8(len(transferFuncs)) { 52 return errors.New("invalid transfer type") 53 } 54 55 f, err := os.CreateTemp("", "mineWebGen") 56 if err != nil { 57 return err 58 } 59 var size int64 60 if transferType&1 == 0 { 61 url := data.ReadString(r) 62 if r.Err != nil { 63 return err 64 } 65 resp, err := http.Get(url) 66 if err != nil { 67 return err 68 } 69 w.WriteInt32(int32(resp.ContentLength)) 70 size, err = io.Copy(f, downloadProgress{resp.Body, w}) 71 resp.Body.Close() 72 if err != nil { 73 return err 74 } 75 } else { 76 length := r.ReadInt32() 77 _, err := io.Copy(f, io.LimitReader(r, int64(length))) 78 if err != nil { 79 return err 80 } 81 size = int64(length) 82 } 83 f.Seek(0, 0) 84 name := data.ReadString(r) 85 if r.Err != nil { 86 return r.Err 87 } 88 err = transferFuncs[transferType>>1](t, name, r, w, f, size) 89 if err != nil { 90 return err 91 } 92 w.WriteUint8(255) 93 return nil 94 } 95