4

デフォルトの Yesod 足場プロジェクトで作業しています。
ファイルをアップロードするための簡単なフォームを表示するページを作成しました。
(フォームは Javascript を使用してクライアント上で作成される可能性があります。)
簡潔にするために、フォームには単一のファイル入力があります。

<form method="post" action=@{UploadR}>
   <input type="file" name="myfile">
   <button type="submit">

私の目的は、フォーム データを処理し、ファイルを Web サービスにアップロードすることです。
フォームの処理に問題はありません。私の懸念は Web サービスとの対話です。
たとえば、次の Yesod ハンドラがあるとします。

postUploadR :: Handler Html
postUploadR = do
    mgr <- fmap httpManager getYesod
    fi  <- runInputPost $ ireq fileField "myfile"
    let fSource = fileSource fi
        fName   = fileName fi
    req <- parseUrl "http://webservice/upload"
    let areq = req { method = methodPost
                   , requestBody = requestBodySourceChunked fSource
                   }
    res <- httpLbs areq mgr
    defaultLayout $ do
      setTitle "file uploaded"
      [whamlet|
       <h3> Success
       <p> You uploaded #{fName}.
      |]

Web サービスはエラーを返します:fail post content-lengthが、それ以外はすべて期待どおりに機能します。サーバーがチャンク化されたリクエストボディをサポートしていない可能性がありますか?

4

1 に答える 1

2

チャンクされたリクエストボディについてのあなたの推測は正しいと思います。あなたがする必要があるのは:

  • アップロードされたコンテンツを一時ファイルにストリーミングします。
  • そのファイルのサイズを取得します。
  • requestBodySourceファイルの長さとその内容を使用して提供します。

幸いなことに、手順 (1) と (2) は、 sinkCacheLength関数によって非常に簡単に処理できます。次のような結果になります。

(fSize, fSource) <- fileSource fi $$ sinkCacheLength
于 2014-09-30T10:55:44.457 に答える