2016-08-15 2 views
0

Я пытался создать инструмент CLI в Crystal для использования send-anywhere.com из командной строки.Не удалось отправить несколько файлов с curl на send-anywhere.com

Отправка multipart не встроена в Crystal, но, прежде чем писать свои собственные, я подумал, что попытаюсь использовать cURL, чтобы увидеть, как именно я должен это сделать, но я даже не могу заставить его работать с cURL!

Проблема заключается в том, что при отправке более одного файла с cURL их сервер видит только 1 входящий файл, они видят общую длину, но терпят неудачу на 50%, так как они ожидали только одного файла.

Что убивает меня, так это то, что он работает в браузере, у меня открыт сетевой инспектор, и я не вижу разницы с моим запросом cURL. Я попытался настроить заголовок Expect на 100-continue, я их сравнил, но я не вижу, что может заставить его работать с браузером, а не завивать.

Вот команда, которую я пытался с Curl все с тем же результатом, что сервер в конечном итоге видеть только один файл поступающего не 2.

Для тестирования я использовал несколько копий общего файла лицензии.

curl -F [email protected] -F [email protected] https://...their.weblink... 

Я видел в инспекторе, что Chrome называет имя файла = "файл []" в Content-Disposition, так что я пробовал сам (тот же результат):

curl -F file[][email protected] -F file[][email protected] https://...their.weblink... 

Я также попробовал эти 2 команды, используя -H "Expect: 100-continue" с таким же результатом.

На данный момент я рассердился и подумал, что я попробую сам, возможно, CURL не может сделать это правильно (очень маловероятно, и у меня гораздо больше шансов, что я что-то сделаю неправильно).

Так, прежде чем писать с нуля, я попробовал реализацию, которая была использована в Телеграмма бот посмотреть здесь: https://github.com/hangyas/TelegramBot/blob/b3fcbbb621bd669bbafe9f3e91364702d06d1e10/src/TelegramBot/http_client_multipart.cr

Это довольно простой, но я все еще получаю один и тот же вопрос. Только первый файл распознается.

Примечание: при отправке только одного файла все работает нормально и при реализации cURL, и в Crystal.

Я схожу с ума, в чем разница между браузером, который работает, и двумя другими? Что я не вижу?

Я не ищу реализацию, но только для того, чтобы кто-то мог указать, что я пропустил, что бы распознать несколько файлов правильно?

+0

Замечание mutlipart должно войти в стандартную библиотеку довольно скоро, см. Https: // github.com/crystal-lang/crystal/pull/2967 –

+0

@ JonneHaß Да, я знаю, что я некоторое время следил за этой проблемой! Но я даже не уверен, что он исправит эту проблему. – ItsASecret

+0

Я не получаю этот сайт, он просто ничего не делает для меня, когда я добавляю файл (при условии, что я попробовал правильный сайт, и вы просто забыли тире в домене). –

ответ

2

Это только для образовательных целей, фактически это нарушает Условия предоставления услуг. Он имеет документированный API, вместо этого следует использовать , после получения ключа API.

Важно сообщить количество файлов в конечную точку key правильно. Таким образом, весь поток выглядит следующим образом:

#!/bin/bash 

# First we need to get a device key by registering ourselves as a 
# device. For that we need a profile name. We need to store the 
# received cookie and send it with the subsequent request. 
profilename="$(openssl rand -hex 6)" 
curl -c .session -vL https://send-anywhere.com/web/device \ 
    -d "os_type=web" \ 
    -d "profile_name=$profilename" \ 
    -d "manufacturer=Linux" \ 
    -d "model_number=Firefox" \ 
    -d "app_version=48" \ 
    -d "device_language=en-US" 

# We need to know the individual filesizes in bytes as well as 
# the total size we're going to upload 
file0name="foo.txt" 
file0size="$(wc -c "$file0name" | cut -d ' ' -f 1)" 
file1name="bar.txt" 
file1size="$(wc -c "$file1name" | cut -d ' ' -f 1)" 
filesize="$(echo "$file0size + $file1size" | bc)" 

# Using that info and the cookie we got from the device key 
# we can correctly announce our upload 
key="$(curl -b .session -vL https://send-anywhere.com/web/key \ 
    -d "file[0][name]=$file0name" -d "file[0][size]=$file0size" \ 
    -d "file[1][name]=$file1name" -d "file[1][size]=$file1size" \ 
    -d "file_number=2" -d "file_size=$filesize")" 

# We get some JSON back with the URL to send to the receiver 
# and the URL to upload back 
url="$(echo "$key" | ruby -rjson -e 'print JSON.parse($stdin.read)["link"]')" 
upload_url="$(echo "$key" | ruby -rjson -e 'print JSON.parse($stdin.read)["weblink"]')" 

echo 
echo "------------------------------------------------------------" 
echo "Receive 2 files of $filesize bytes at $url" 
echo "------------------------------------------------------------" 
echo 

# And finally do the upload 
curl -vL "$upload_url" \ 
    -F "file[][email protected]$file0name" \ 
    -F "file[][email protected]$file1name" 
+0

AH! Я никогда не думал смотреть на предыдущий запрос, так как они отлично работали (и да, у меня есть свой собственный ключ API). Также я не понял полностью, но разве против их ToS отправлять несколько файлов с помощью API (с допустимым ключом)? Или просто отправлять файлы без использования ключа API? Спасибо в любом случае! – ItsASecret

+0

Также, возможно, они просто забыли добавить это в свой API-документ: https://send-anywhere.com/web/page/api#web-gui. Нет упоминания о том, чтобы указать количество файлов! – ItsASecret

+0

Также, возможно, это было непонятно, но я использовал свой собственный ключ API с самого начала. Но ключ не нужен для последнего шага (загрузка на веб-ссылку). Поэтому об этом не упоминалось. Это нужно только для выполнения шагов register_device и get_6_digits_key. – ItsASecret

Смежные вопросы