Source file src/net/http/clone.go
1 // Copyright 2019 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package http 6 7 import ( 8 "mime/multipart" 9 "net/textproto" 10 "net/url" 11 _ "unsafe" // for linkname 12 ) 13 14 // cloneURLValues should be an internal detail, 15 // but widely used packages access it using linkname. 16 // Notable members of the hall of shame include: 17 // - github.com/searKing/golang 18 // 19 // Do not remove or change the type signature. 20 // See go.dev/issue/67401. 21 // 22 //go:linkname cloneURLValues 23 func cloneURLValues(v url.Values) url.Values { 24 if v == nil { 25 return nil 26 } 27 // http.Header and url.Values have the same representation, so temporarily 28 // treat it like http.Header, which does have a clone: 29 return url.Values(Header(v).Clone()) 30 } 31 32 // cloneURL should be an internal detail, 33 // but widely used packages access it using linkname. 34 // Notable members of the hall of shame include: 35 // - github.com/searKing/golang 36 // 37 // Do not remove or change the type signature. 38 // See go.dev/issue/67401. 39 // 40 //go:linkname cloneURL 41 func cloneURL(u *url.URL) *url.URL { 42 if u == nil { 43 return nil 44 } 45 u2 := new(url.URL) 46 *u2 = *u 47 if u.User != nil { 48 u2.User = new(url.Userinfo) 49 *u2.User = *u.User 50 } 51 return u2 52 } 53 54 // cloneMultipartForm should be an internal detail, 55 // but widely used packages access it using linkname. 56 // Notable members of the hall of shame include: 57 // - github.com/searKing/golang 58 // 59 // Do not remove or change the type signature. 60 // See go.dev/issue/67401. 61 // 62 //go:linkname cloneMultipartForm 63 func cloneMultipartForm(f *multipart.Form) *multipart.Form { 64 if f == nil { 65 return nil 66 } 67 f2 := &multipart.Form{ 68 Value: (map[string][]string)(Header(f.Value).Clone()), 69 } 70 if f.File != nil { 71 m := make(map[string][]*multipart.FileHeader) 72 for k, vv := range f.File { 73 vv2 := make([]*multipart.FileHeader, len(vv)) 74 for i, v := range vv { 75 vv2[i] = cloneMultipartFileHeader(v) 76 } 77 m[k] = vv2 78 } 79 f2.File = m 80 } 81 return f2 82 } 83 84 // cloneMultipartFileHeader should be an internal detail, 85 // but widely used packages access it using linkname. 86 // Notable members of the hall of shame include: 87 // - github.com/searKing/golang 88 // 89 // Do not remove or change the type signature. 90 // See go.dev/issue/67401. 91 // 92 //go:linkname cloneMultipartFileHeader 93 func cloneMultipartFileHeader(fh *multipart.FileHeader) *multipart.FileHeader { 94 if fh == nil { 95 return nil 96 } 97 fh2 := new(multipart.FileHeader) 98 *fh2 = *fh 99 fh2.Header = textproto.MIMEHeader(Header(fh.Header).Clone()) 100 return fh2 101 } 102 103 // cloneOrMakeHeader invokes Header.Clone but if the 104 // result is nil, it'll instead make and return a non-nil Header. 105 // 106 // cloneOrMakeHeader should be an internal detail, 107 // but widely used packages access it using linkname. 108 // Notable members of the hall of shame include: 109 // - github.com/searKing/golang 110 // 111 // Do not remove or change the type signature. 112 // See go.dev/issue/67401. 113 // 114 //go:linkname cloneOrMakeHeader 115 func cloneOrMakeHeader(hdr Header) Header { 116 clone := hdr.Clone() 117 if clone == nil { 118 clone = make(Header) 119 } 120 return clone 121 } 122