@@ -16,13 +16,15 @@ import (
16
16
"path"
17
17
"path/filepath"
18
18
"reflect"
19
+ "runtime"
19
20
"strconv"
20
21
"strings"
21
22
22
23
"github.com/jmorganca/ollama/api"
23
24
"github.com/jmorganca/ollama/llm"
24
25
"github.com/jmorganca/ollama/parser"
25
26
"github.com/jmorganca/ollama/vector"
27
+ "github.com/jmorganca/ollama/version"
26
28
)
27
29
28
30
const MaxRetries = 3
@@ -1005,15 +1007,14 @@ func PushModel(ctx context.Context, name string, regOpts *RegistryOptions, fn fu
1005
1007
1006
1008
fn (api.ProgressResponse {Status : "pushing manifest" })
1007
1009
url := fmt .Sprintf ("%s/v2/%s/manifests/%s" , mp .Registry , mp .GetNamespaceRepository (), mp .Tag )
1008
- headers := map [string ]string {
1009
- "Content-Type" : "application/vnd.docker.distribution.manifest.v2+json" ,
1010
- }
1011
1010
1012
1011
manifestJSON , err := json .Marshal (manifest )
1013
1012
if err != nil {
1014
1013
return err
1015
1014
}
1016
1015
1016
+ headers := make (http.Header )
1017
+ headers .Set ("Content-Type" , "application/vnd.docker.distribution.manifest.v2+json" )
1017
1018
resp , err := makeRequestWithRetry (ctx , "PUT" , url , headers , bytes .NewReader (manifestJSON ), regOpts )
1018
1019
if err != nil {
1019
1020
return err
@@ -1098,10 +1099,9 @@ func PullModel(ctx context.Context, name string, regOpts *RegistryOptions, fn fu
1098
1099
1099
1100
func pullModelManifest (ctx context.Context , mp ModelPath , regOpts * RegistryOptions ) (* ManifestV2 , error ) {
1100
1101
url := fmt .Sprintf ("%s/v2/%s/manifests/%s" , mp .Registry , mp .GetNamespaceRepository (), mp .Tag )
1101
- headers := map [string ]string {
1102
- "Accept" : "application/vnd.docker.distribution.manifest.v2+json" ,
1103
- }
1104
1102
1103
+ headers := make (http.Header )
1104
+ headers .Set ("Accept" , "application/vnd.docker.distribution.manifest.v2+json" )
1105
1105
resp , err := makeRequest (ctx , "GET" , url , headers , nil , regOpts )
1106
1106
if err != nil {
1107
1107
log .Printf ("couldn't get manifest: %v" , err )
@@ -1226,11 +1226,10 @@ func uploadBlobChunked(ctx context.Context, mp ModelPath, url string, layer *Lay
1226
1226
1227
1227
sectionReader := io .NewSectionReader (f , int64 (completed ), chunk )
1228
1228
1229
- headers := make (map [string ]string )
1230
- headers ["Content-Type" ] = "application/octet-stream"
1231
- headers ["Content-Length" ] = strconv .Itoa (int (chunk ))
1232
- headers ["Content-Range" ] = fmt .Sprintf ("%d-%d" , completed , completed + sectionReader .Size ()- 1 )
1233
-
1229
+ headers := make (http.Header )
1230
+ headers .Set ("Content-Type" , "application/octet-stream" )
1231
+ headers .Set ("Content-Length" , strconv .Itoa (int (chunk )))
1232
+ headers .Set ("Content-Range" , fmt .Sprintf ("%d-%d" , completed , completed + sectionReader .Size ()- 1 ))
1234
1233
resp , err := makeRequestWithRetry (ctx , "PATCH" , url , headers , sectionReader , regOpts )
1235
1234
if err != nil && ! errors .Is (err , io .EOF ) {
1236
1235
fn (api.ProgressResponse {
@@ -1260,9 +1259,9 @@ func uploadBlobChunked(ctx context.Context, mp ModelPath, url string, layer *Lay
1260
1259
1261
1260
url = fmt .Sprintf ("%s&digest=%s" , url , layer .Digest )
1262
1261
1263
- headers := make (map [ string ] string )
1264
- headers [ "Content-Type" ] = "application/octet-stream"
1265
- headers [ "Content-Length" ] = "0"
1262
+ headers := make (http. Header )
1263
+ headers . Set ( "Content-Type" , "application/octet-stream" )
1264
+ headers . Set ( "Content-Length" , "0" )
1266
1265
1267
1266
// finish the upload
1268
1267
resp , err := makeRequest (ctx , "PUT" , url , headers , nil , regOpts )
@@ -1279,7 +1278,7 @@ func uploadBlobChunked(ctx context.Context, mp ModelPath, url string, layer *Lay
1279
1278
return nil
1280
1279
}
1281
1280
1282
- func makeRequestWithRetry (ctx context.Context , method , url string , headers map [ string ] string , body io.ReadSeeker , regOpts * RegistryOptions ) (* http.Response , error ) {
1281
+ func makeRequestWithRetry (ctx context.Context , method , url string , headers http. Header , body io.ReadSeeker , regOpts * RegistryOptions ) (* http.Response , error ) {
1283
1282
var status string
1284
1283
for try := 0 ; try < MaxRetries ; try ++ {
1285
1284
resp , err := makeRequest (ctx , method , url , headers , body , regOpts )
@@ -1318,7 +1317,7 @@ func makeRequestWithRetry(ctx context.Context, method, url string, headers map[s
1318
1317
return nil , fmt .Errorf ("max retry exceeded: %v" , status )
1319
1318
}
1320
1319
1321
- func makeRequest (ctx context.Context , method , url string , headers map [ string ] string , body io.Reader , regOpts * RegistryOptions ) (* http.Response , error ) {
1320
+ func makeRequest (ctx context.Context , method , url string , headers http. Header , body io.Reader , regOpts * RegistryOptions ) (* http.Response , error ) {
1322
1321
if ! strings .HasPrefix (url , "http" ) {
1323
1322
if regOpts .Insecure {
1324
1323
url = "http://" + url
@@ -1332,15 +1331,17 @@ func makeRequest(ctx context.Context, method, url string, headers map[string]str
1332
1331
return nil , err
1333
1332
}
1334
1333
1334
+ if headers != nil {
1335
+ req .Header = headers
1336
+ }
1337
+
1335
1338
if regOpts .Token != "" {
1336
1339
req .Header .Set ("Authorization" , "Bearer " + regOpts .Token )
1337
1340
} else if regOpts .Username != "" && regOpts .Password != "" {
1338
1341
req .SetBasicAuth (regOpts .Username , regOpts .Password )
1339
1342
}
1340
1343
1341
- for k , v := range headers {
1342
- req .Header .Set (k , v )
1343
- }
1344
+ req .Header .Set ("User-Agent" , fmt .Sprintf ("ollama/%s (%s %s) Go/%s" , version .Version , runtime .GOARCH , runtime .GOOS , runtime .Version ()))
1344
1345
1345
1346
client := & http.Client {
1346
1347
CheckRedirect : func (req * http.Request , via []* http.Request ) error {
0 commit comments