Разбор HTTP составного POST с использованием структуры в Rocket

Я хочу проанализировать HTTP POST в Rocket, используя структуру. При отправке формы не работает.

Я прочитал пример тела данных и получил этот код.

#[derive(FromForm)]
struct ConvertFile {
    name: String,
    filename: String
}

#[post("/submit", format = "multipart/form-data", data = "<form>")]
fn submit(form: Form<ConvertFile>) {
    println!("form field: {}", form.get().name);
}

Я отправляю с помощью curl:

curl -H "Content-Type: multipart/form-data" -F "name=Claus" -F "filename=claus.jpg" http://localhost:8000/submit

и консоль Rocket отвечает

multipart/form-data; boundary=------------------------8495649d6ed34d20:
    => Matched: POST /submit multipart/form-data
    => Warning: Form data does not have form content type.
    => Outcome: Forward
    => Error: No matching routes for POST /submit multipart/form-data; boundary=------------------------8495649d6ed34d2.
    => Warning: Responding with 404 Not Found catcher.
    => Response succeeded.

Я хочу отправить файл, поэтому multipart/form-data. Пытаясь найти причину, я использовал String в структуре, чтобы сделать ее проще. Итак, сначала он отвечает Matched:, а затем нет подходящих маршрутов.

Этот более простой POST работает:

#[post("/convert", format = "text/plain", data = "<file>")]
fn convert_file(file: String) {
    println!("file: {}", file);
}

Я использую последнюю ночную версию Rust с rustup.

Что я делаю не так?


person kometen    schedule 25.07.2017    source источник
comment
Я не уверен, но пробовали ли вы использовать соответствующие поля формы в своей команде curl? У вас есть file и filename в этом ConvertFile, а не name и filename.   -  person E_net4 the curator    schedule 26.07.2017
comment
Поля в структуре были из более раннего проекта, автоматически сохраненного в SO. Поэтому я забыл изменить его с помощью текущей команды curl, когда задавал вопрос. Спасибо, что заметили это, я изменил его, чтобы он был правильным.   -  person kometen    schedule 26.07.2017


Ответы (1)


Rocket пока не поддерживает multipart формы.

Вы можете увидеть проблему с отслеживанием здесь: https://github.com/SergioBenitez/Rocket/issues/ 106

В этом ответе приведен возможный обходной путь: >Как парсить составные формы с помощью abonander/multipart с Rocket?

person belst    schedule 26.07.2017
comment
Спасибо. Но тогда пример на rocket.rs/guide/requests/#forms должен быть неточным? - person kometen; 26.07.2017
comment
нет, формы работают, но не составной тип контента. - person belst; 26.07.2017
comment
Хм, у меня проблемы с отправкой сообщения http-формы с использованием curl. curl -X POST -f name=claus filename=claus.jpg. - person kometen; 26.07.2017
comment
это отлично работает для меня: curl -X POST --data "name=clause&filename=claus.jpg" http://localhost:8000: gist.github.com/belst/21a6759f183cd031a2cac5846bd4bfbb - person belst; 26.07.2017
comment
Похоже, что Rocket пытается сопоставить multipart/form-data с multipart/form-data; boundary=...., что явно не удается. Итак, как сказано в ответе, вам нужно использовать FromData, а не FromForm, и самостоятельно анализировать тело. - person belst; 26.07.2017
comment
Я могу загрузить и сохранить файл с помощью Rocket::Data.stream_to_file(). Но если я хочу отправить имя файла как часть сообщения формы, кажется, что поддержка multipart/form-data должна быть добавлена, прежде чем это станет возможным, я думаю. - person kometen; 26.07.2017