How to upload a blob using curl?

I’m trying to upload a blob using curl; but I receive an authorization error.

Im following the example at using blob tables - upload

The example code don’t use any kind of authentication

sh$ curl -isSX PUT '127.0.0.1:4200/_blobs/myblobs/4a756ca07e9487f482465a99e8286abc86ba4dc7' -d 'contents'
HTTP/1.1 201 Created
content-length: 0

I’m using host based authentication. I created CrateDB with crate-operator using this configuration file

apiVersion: cloud.crate.io/v1
kind: CrateDB
metadata:
  name: my-cluster
  namespace: for-crate
spec:
  cluster:
    imageRegistry: crate
    name: my-crate
    version: 5.8.1
    allowedCIDRs:
    - 192.168.151.0/24
    - 10.0.0.0/8
  nodes:
    data:
    - name: hot
      replicas: 3
      resources:
        limits:
          cpu: 4
          memory: 4Gi
        disk:
          count: 1
          size: 16GiB
          storageClass: longhorn
        heapRatio: 0.25

CrateDB answer on these addresses of the “192.168.151.0/24” network

service/crate-my-cluster             LoadBalancer   10.43.2.208   192.168.151.21,192.168.151.22,192.168.151.23   4200:31111/TCP,5432:32328/TCP   8m42s

The machine issuing the command is on the same network

ip -c a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute 
       valid_lft forever preferred_lft forever
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 52:54:00:bd:99:96 brd ff:ff:ff:ff:ff:ff
    inet 192.168.152.40/24 brd 192.168.152.255 scope global noprefixroute enp1s0
       valid_lft forever preferred_lft forever
3: enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 52:54:00:f4:fe:e5 brd ff:ff:ff:ff:ff:ff
    inet 192.168.151.40/24 brd 192.168.151.255 scope global noprefixroute enp2s0
       valid_lft forever preferred_lft forever
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:b0:6b:a0:3f brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever

From this machine using crate I see the attachments blob table

crash --verbose --hosts "192.168.151.21" -U system
+----------------------------+------------+---------+-----------+---------+
| server_url                 | node_name  | version | connected | message |
+----------------------------+------------+---------+-----------+---------+
| http://192.168.151.21:4200 | data-hot-1 | 5.8.1   | TRUE      | OK      |
+----------------------------+------------+---------+-----------+---------+
CONNECT OK
CLUSTER CHECK OK
TYPES OF NODE CHECK OK
cr> select * from blob.attachments;
+--------+---------------+
| digest | last_modified |
+--------+---------------+
+--------+---------------+
SELECT 0 rows in set (0.023 sec)

(remembering to set the “system” user password in the environment variable “CRATEPW”)

Then I created a simple script to upload a file

sysop@h5a-dev:~/h5a/software/pcams/storehouse/cratedb/attachments$ cat upload 
#!/bin/bash

HASH=`sha1sum $1 |sed 's/ /|/' | awk -F '|' '{print $1}'`

echo ===== HASH ========
echo $HASH
echo =
echo ===== UPLOAD ======

curl -isSX PUT '192.168.151.21:4200/_blobs/attachments/$HASH' -d $1

sysop@h5a-dev:~/h5a/software/pcams/storehouse/cratedb/attachments$

But when using this script I receive the authorization error

sysop@h5a-dev:~/h5a/software/pcams/storehouse/cratedb/attachments$ ./upload ROG_CROSSHAIR_X670E_HERO_h732.png 
===== HASH ========
9a3993e2ecbbb3b1ea1435650cedd7fec2454e73
=
===== UPLOAD ======
HTTP/1.1 401 Unauthorized
content-length: 137
www-authenticate: Basic realm="CrateDB Authenticator"

No valid auth.host_based.config entry found for host "192.168.151.40", user "crate", protocol "http". Did you enable TLS in your client?
sysop@h5a-dev:~/h5a/software/pcams/storehouse/cratedb/attachments$ 

What I’m doing wrong?

UPDATE

Tried to add authorization in curl: same error but strange characters in the error message

New script


HASH=`sha1sum $1 |sed 's/ /|/' | awk -F '|' '{print $1}'`

echo ===== HASH ========
echo $HASH
echo =
echo ===== UPLOAD ======
echo =

curl -vvv -isSX PUT '192.168.151.21:4200/_blobs/attachments/$HASH' -H "Authorization: Basic S9xsloAiGVvZ7iqaDQjtAzasmiFedEYlc1ajapZWDikhPbZTkj" --data-binary @$1

echo ' '

The execution

sysop@h5a-dev:~/h5a/software/pcams/storehouse/cratedb/attachments$ ./upload ROG_CROSSHAIR_X670E_HERO_h732.png 
===== HASH ========
9a3993e2ecbbb3b1ea1435650cedd7fec2454e73
=
===== UPLOAD ======
=
*   Trying 192.168.151.21:4200...
* Connected to 192.168.151.21 (192.168.151.21) port 4200 (#0)
> PUT /_blobs/attachments/$HASH HTTP/1.1
> Host: 192.168.151.21:4200
> User-Agent: curl/7.88.1
> Accept: */*
> Authorization: Basic S9xsloAiGVvZ7iqaDQjtAzasmiFedEYlc1ajapZWDikhPbZTkj
> Content-Length: 818987
> Content-Type: application/x-www-form-urlencoded
> 
< HTTP/1.1 401 Unauthorized
HTTP/1.1 401 Unauthorized
< content-length: 169
content-length: 169
< www-authenticate: Basic realm="CrateDB Authenticator"
www-authenticate: Basic realm="CrateDB Authenticator"

* HTTP error before end of send, stop sending
< 
* Excess found in a read: excess = 26, size = 169, maxdownload = 169, bytecount = 0
* Closing connection 0
�6��!^tF%sV�j�V)!=�S�", protocol "http". Did you e t "192.168.151.40", user "K�l��"[��*�
sysop@h5a-dev:~/h5a/software/pcams/storehouse/cratedb/attachments$ 

UPDATE - SOME SUCCESS

I gave up with the examples and tried with the curl manual.
I was able to upload a file using the “–user username:password” and the “–data-binary @[path to file]” parameters

New script

#!/bin/bash

HASH=`sha1sum $1 |sed 's/ /|/' | awk -F '|' '{print $1}'`

echo ===== HASH ========
echo $HASH
echo =

echo ===== URL =========
URL=192.168.151.21:4200/_blobs/attachments/$HASH
echo $URL
echo =

echo ===== UPLOAD ======
echo =

curl -vvvv -isSX PUT $URL --user system:S9xsloAiGVvZ7iqaDQjtAzasmiFedEYlc1ajapZWDikhPbZTkj --data-binary @$1

echo ' '

The execution says it worked

sysop@h5a-dev:~/h5a/software/pcams/storehouse/cratedb/attachments$ ./upload ROG_CROSSHAIR_X670E_HERO_h732.png 
===== HASH ========
9a3993e2ecbbb3b1ea1435650cedd7fec2454e73
=
===== URL =========
192.168.151.21:4200/_blobs/attachments/9a3993e2ecbbb3b1ea1435650cedd7fec2454e73
=
===== UPLOAD ======
=
*   Trying 192.168.151.21:4200...
* Connected to 192.168.151.21 (192.168.151.21) port 4200 (#0)
* Server auth using Basic with user 'system'
> PUT /_blobs/attachments/9a3993e2ecbbb3b1ea1435650cedd7fec2454e73 HTTP/1.1
> Host: 192.168.151.21:4200
> Authorization: Basic c3lzdGVtOlM5eHNsb0FpR1Z2WjdpcWFEUWp0QXphc21pRmVkRVlsYzFhamFwWldEaWtoUGJaVGtq
> User-Agent: curl/7.88.1
> Accept: */*
> Content-Length: 818987
> Content-Type: application/x-www-form-urlencoded
> 
* We are completely uploaded and fine
< HTTP/1.1 201 Created
HTTP/1.1 201 Created
< content-length: 0
content-length: 0

< 
* Connection #0 to host 192.168.151.21 left intact
 
sysop@h5a-dev:~/h5a/software/pcams/storehouse/cratedb/attachments$

Now I have to verify if the file was not corrupted during the upload

Any hint?

I think that to confirm your approach worked correctly we could just download the file, calculate its hash, and then check if it matches the value you had before uploading.

Yes, the downloaded file is identical to the uploaded one.

Problem solved… but I panicked (see my next post)