Ошибка обработки файла: multipart: NextPart: EOF - PullRequest
0 голосов
/ 08 марта 2020

Я пытаюсь создать маленькое приложение, которое позволяет загружать большие файлы кусками. Я также добавлю возможность сделать паузу позже.

Я застрял на этой ошибке внутри моего l oop: файл обработки ошибок: multipart: NextPart: EOF

func main() {
    router := gin.Default()

    rg := router.Group("api/v1")
    {
        rg.POST("/photo", uploadFile)
    }

    router.Use(CORSMiddleware())
    router.Run()
}

func uploadFile(c *gin.Context) {
    mr, e := c.Request.MultipartReader()
    if e != nil {
        panic("Error reading request:" + e.Error())
    }

    client, e := storage.NewClient(c, option.WithAPIKey(uploadApiKey))
    bucket := client.Bucket(uploadBucket)

    for {
        p, e := mr.NextPart()

        if e == io.EOF {
            break
        } else if e != nil {
            panic("Error processing file:" + e.Error())
        }

        w := bucket.Object(p.FileName()).NewWriter(c)

        if _, e := io.Copy(w, p); e != nil {
            panic("Error during chunk upload:" + e.Error())
        } else if e := w.Close(); e != nil {
            panic("Could not finalize chunk writing:" + e.Error())
        }

    }
}

Код на стороне клиента выглядит следующим образом:

class FileToUpload {
    static chunkSize = 512000;
    static uploadUrl = 'http://localhost:8080/api/v1/photo';
    readonly request: XMLHttpRequest;
    readonly file: File;
    readonly name: string;
    currentChunkStartByte: number;
    currentChunkFinalByte: number;

    constructor(file: File, name: string) {
        this.request = new XMLHttpRequest();
        this.file = file;
        this.name = name;

        this.currentChunkStartByte = 0;
        this.currentChunkFinalByte = FileToUpload.chunkSize > this.file.size ? this.file.size : FileToUpload.chunkSize;
    }

    uploadFile() {
        let chunk: Blob = this.file.slice(this.currentChunkStartByte, this.currentChunkFinalByte);
        this.request.overrideMimeType('application/octet-stream');
        this.request.open('POST', FileToUpload.uploadUrl, true);

        const randomNum = Math.random().toString().substr(2);
        this.request.setRequestHeader('Content-Type', 'multipart/form-data; boundary=--'+randomNum);
        this.request.setRequestHeader('Content-Range', `bytes ${this.currentChunkStartByte}-${this.currentChunkFinalByte}/${this.file.size}`);

        this.request.onload = () => {
            if(this.currentChunkFinalByte === this.file.size) {
                // Do something once done with file
                return;
            }

            this.currentChunkStartByte = this.currentChunkFinalByte;
            this.currentChunkFinalByte = this.currentChunkStartByte + FileToUpload.chunkSize;

            this.uploadFile();
        }
        this.request.send(chunk);
    }
}

У меня уже есть проверка на EOF, я не понимаю, почему я все еще получаю эту ошибку. Есть идеи?

1 Ответ

1 голос
/ 10 марта 2020

Согласно исходному коду, такая ошибка, которая будет состоять из io.EOF, может быть возвращена только в том случае, если в теле потока не найдена закрывающая граница, однако клиент пометил тело как отправленное. В вашем случае либо отсутствует граница в теле запроса, которая помечает конец содержимого файла, либо вы не анализируете его на стороне сервера.

Исходный код: https://golang.org/src/mime/multipart/multipart.go#L339

В указанном вами c случае, http.Request MultipartReader() предварительно проанализирует вашу границу, поэтому вам не нужно делать там ничего дополнительного (https://golang.org/src/net/http/request.go#L486). В то же время Я не вижу кода, который добавлял бы границу файла к потоку на стороне клиента. .

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

Пожалуйста, прочитайте больше информации о работе многочастных форм, в частности, в этом ответе: { ссылка }

...