Akka HTTP: ByteString как полезная нагрузка файла в запросе данных формы - PullRequest
0 голосов
/ 08 мая 2018

В одном из моих предыдущих вопросов я спросил, как представить запрос данных формы, используя Akka HTTP?В соответствии с ответами я создал рабочий образец, но столкнулся с проблемой «масштабируемости» - когда число запросов данных формы велико, мне нужно обрабатывать много файлов в файловой системе.

ЯЛюбопытно, можно ли отправить ByteString в качестве полезной нагрузки файла в запросе данных формы?

case class FBSingleChunkUpload(accessToken: String, 
        sessionId: String,
        from: Long, 
        to: Long, 
        file: ByteString) //this property is received from S3 as array of bytes

Я создал следующий пример:

def defaultEntity(content: String) =
  HttpEntity.Default(
    ContentTypes.`text/plain(UTF-8)`,
    content.length, Source(ByteString(content) :: Nil)
  )

def chunkEntity(chunk: ByteString) =
  HttpEntity.Strict(
    ContentType(MediaTypes.`application/octet-stream`),
    chunk
  )

val formData = Multipart.FormData(
  Source(
    Multipart.FormData.BodyPart("access_token", defaultEntity(upload.fbUploadSession.fbId.accessToken)) ::
    Multipart.FormData.BodyPart("upload_phase", defaultEntity("transfer")) ::
    Multipart.FormData.BodyPart("start_offset", defaultEntity(upload.fbUploadSession.from.toString)) ::
    Multipart.FormData.BodyPart("upload_session_id", defaultEntity(upload.fbUploadSession.uploadSessionId)) ::
    Multipart.FormData.BodyPart("video_file_chunk", chunkEntity(upload.chunk)) :: Nil
  )
)
val req = HttpRequest(
  HttpMethods.POST,
  s"/v2.3/${upload.fbUploadSession.fbId.pageId}/videos",
  Nil,
  formData.toEntity()
)

В этом случае Facebook отправляетмне вернуло сообщение:

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

Но если я отправлю тот же ByteString, что и File, он будет работать нормально.

Что может быть причиной этого?Я уже пытался использовать MediaTypes.multipart/form-data в chunkEntity, но он ведет себя так же.

1 Ответ

0 голосов
/ 21 мая 2018

Чтобы отправить ByteString в виде файла данных формы, вам нужно использовать следующее BodyPart:

def fileEntity(chunk: ByteString) = Multipart.FormData.BodyPart.Strict("video_file_chunk",
    HttpEntity(ContentType(MediaTypes.`application/octet-stream`), chunk), Map("fileName" -> "video_chunk"))

Обратите особое внимание на Map("fileName" -> "video_chunk"), этот параметр обязателен для правильного построения HTTP-запроса данных формы.

Таким образом, вместо chunkEntity из вопроса используйте fileEntity из этого ответа:)

...