Curl JSON codificado em UTF-8

4

Nota importante : estou usando o Cygwin

Recupero JSON de um arquivo que altero antes de enviá-lo para um servidor usando curl . Até agora está tudo bem, exceto uma coisa, quando o servidor recebe o JSON, todos os caracteres especiais (com acentos, etc) não são bem codificados. Suponho que isso se deva ao fato de meu JSON não ter sido codificado em UTF-8 antes de ser enviado, mas não consigo convertê-lo.

Aqui está o código:

sed -i 's/\r//g' $file
fileContent='cat $file'

result=$(jq -c -j ".docs[$docIndex] + { \"_rev\": \"$rev\" }"<<<"$fileContent")            result="{\"docs\":[$result]}"

result=$result | sed 's/\r//g'
result=$result | iconv -t "UTF-8"
s=$(curl -H "Content-Type: application/json; charset=UTF-8" -H "Cache-Control: no-cache" -d "$result" $2/$3/_bulk_docs --silent)

Meu script bash e meus arquivos JSON são codificados em UTF-8. Minha variável LANG parece ser UTF-8. Eu verifiquei com isso: [[ $LANG =~ UTF-8$ ]] && echo "Uses UTF-8 encoding.."

Alguma ideia?

Atualizar

Aqui está o script completo:

#!/bin/bash

# $1 = directory containing JSON files
# $2 = server url (+ port)
# $3 = database name

#Loop on every file of the given directory
for file in "$1"/*; do

    #Try to insert every document of a specific JSON file and retrieve their status (200 = OK; 409 = conflict)
    allStatus=$(curl -H "Content-Type: application/json" -H "Cache-Control: no-cache" --data-binary "@$file" $2/$3/_bulk_docs --silent | jq '.[] |.status' | tr -d '\r')
    docIndex=0

    #Loop on every status (one status = one document)
    while IFS=' ' read -ra statusArray; do
      for status in "${statusArray[@]}"; do

        #Remove unwanted windows characters of the file
        sed -i 's/\r//g' $file
        fileContent='cat $file'

        #Retrieve the id of the current document
        id='jq -r -j ".docs[$docIndex]._id"<<<"$fileContent" | tr -d '\r''

        if [ "$status" = "409" ]
        then 
            #Retrieve the revision of the current document and add it to the document 
            rev=$(curl -X GET --header 'Accept: application/json' $2/$3/$id?revs=true --silent | jq -r -j '._rev' | tr -d '\r')
            result=$(jq -c -j ".docs[$docIndex] + { \"_rev\": \"$rev\" }"<<<"$fileContent")

            #Wrap the document inside {"docs":[]}
            result="{\"docs\":[$result]}"

            #Remove unwanted windows characters before sending the document (again)
            result=$result | sed 's/\r//g'
            result=$result | iconv -t "UTF-8"
            s=$(curl -H "Content-Type: application/json; charset=UTF-8" -H "Cache-Control: no-cache" -d "$result" $2/$3/_bulk_docs --silent)

            #Echo result
            echo $s
        else
          #Status should be 200.
          echo 'status: '$status ' - ' $id
        fi

        docIndex=$((docIndex+1))

      done
    done <<< "$allStatus"
done

Este script tem como objetivo extrair documentos dentro de um banco de dados NoSQL. Se primeiro tentar inserir e se, se falhar, ele recuperar uma propriedade (a revisão) do documento, anexe-a e tente novamente uma vez.

Eu sei que este script pode ser melhorado, mas este é meu primeiro script bash e não será usado em produção (apenas para testes, etc.).

    
por MHogge 20.06.2017 / 15:48

2 respostas

1

Você pode usar isso no Bash on Cygwin, desde que você tenha pelo menos o Python 2.7 instalado:

utf8_result="$(echo "$result" | python -c "import sys;[sys.stdout.write((i).decode('utf-8')) for i in sys.stdin]")"
    
por 24.06.2017 / 06:12
1

Resposta parcial:

De acordo com man curl , -d ou --data faz um POST usando o tipo de conteúdo application/x-www-form-urlencoded e é equivalente a --data-ascii . Eu não acho que as tentativas de substituir o cabeçalho vão mudar isso. Como o padrão diz, o conjunto de caracteres para urlencoding depende dos elementos de formulário, que estão faltando completamente aqui.

Se eu entendi o script corretamente, $result é UTF-8 e não é codificado por url. Portanto, você provavelmente deve usar --data-urlencode (consulte man curl para obter detalhes) e esperar que ele codifique corretamente UTF-8 ou use --form , que é mais flexível, e onde você pode incluir um campo charset .

Assim, o principal problema parece estar em como o padrão prescreve a codificação, o que é suficientemente difícil de entender (pelo menos para mim). Talvez você possa obter uma resposta melhor no stackoverflow.

    
por 27.06.2017 / 22:37