2

I'm building an iOS extension in Swift, and want to upload a file from a background uploadTask to a Go server. I have managed to do this successfully with a dataTask, following this example . Due to memory restrictions, I need to use a uploadTask(with:fromFile:) from . On the iOS side, I can see that the file is uploading, and I confirmed with fiddler that the POST request has the file data attached. However, when I now try and parse the request in Go via FormFile, I get the following error message:

"multipart: NextPart: bufio: buffer full"

I have tried different sizes as the argument for ParseMutlipartForm, and also taking it out, since Formfile should call ParseMultipartForm, if it needs to. None of this had any effect. The error persists for calls to FormFile, as well.

Upload request from iOS:

let config = URLSessionConfiguration.background(withIdentifier: "\(fileUrl)")
config.sharedContainerIdentifier = SHARED_CONTAINER_IDENTIFIER
let urlString = CLIENTURL + "/saveFile"
let postURL = URL(string: urlString)

var request = URLRequest(url: postURL!)
request.httpMethod = "POST"
let boundary = "Boundary-\(UUID().uuidString)"
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
request.setValue("Keep-Alive", forHTTPHeaderField: "Connection")

let task = session.uploadTask(with: request, fromFile: fileUrl)
session.getTasksWithCompletionHandler{
  (dataTasks, uploadTasks, downloadTasks) -> Void in
}
task.resume()

Go server:

func handleSaveFile(w http.ResponseWriter, r *http.Request, p hr.Params) {
    log := config.Log(`api:iosfp`)

    const _24K = (1 << 10) * 24
    if err := r.ParseMultipartForm(_24K); nil != err {
        log.WithError(err).Error(`Error at ParseMultipartForm`)
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    file, _, err := r.FormFile("file")
    if nil != err {
        log.WithError(err).Error(`Error at FormFile`)
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    var buff bytes.Buffer
    fSize, err := buff.ReadFrom(file)
    if nil != err {
        log.WithError(err).Error(`Error reading file`)
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    log.Info(`fileSize: `, fSize)
 ...
}
  • not sure why are you calling `r.ParseMultipartForm()` first. this may help you: https://github.com/yanpozka/go-httprouter-upfiles-token/blob/master/handlers.go#L49 + it's not a good idea read the whole file in memory – Yandry Pozo Oct 11 '17 at 00:21

0 Answers0