从Qt客户端发送图像后,出现了“Go http: no such file”错误。

huangapple go评论59阅读模式
英文:

Go http: no such file after sending image from Qt client

问题

我有一个Go API,应该保存客户端发送的图像。我知道当POST请求来自HTML表单时,Go代码是有效的。然而,当我从我的Qt C++客户端发送一个多部分的POST请求时,服务器返回一个错误:

> http: no such file

在客户端,我有一个QPixmap,我将其转换为QByteArray,然后发送,但是不知何故我从Go那里得到了这个错误。我知道当我移除

multi_part->append(image_part);

时,客户端发送的数据长度减少,所以应该是QPixmap被发送了。

Go代码:

func apiUploadHandler(w http.ResponseWriter, req *http.Request) {
    if req.Method == "POST" {
        req.ParseMultipartForm(0)
        fmt.Printf("%v %v %v", req.RemoteAddr, req.ContentLength, req.Body)
        file, fileheader, err := req.FormFile("image")
        if err != nil {
            cio.PrintMessage(1, err.Error())
            return
        }
        defer file.Close()
        var id string
        created := false
        for created != true {
            id = generateImageID()
            err = db.CheckIfImageIDInUse(id)
            if err != nil {
                if err.Error() == "Image ID '"+id+"' exists.'" {
                    created = false
                    continue
                } else {
                    created = false
                    cio.PrintMessage(1, err.Error())
                    return
                }
            }
            created = true
        }
        filePath := fsys.ImgStoragePath + id + "." + strings.Split(fileheader.Filename, ".")[1]
        err = db.StoreImage(id, strings.Split(fileheader.Filename, ".")[0] /*image name*/, filePath, strings.Split(fileheader.Filename, ".")[1] /*extension*/)
        if err != nil {
            cio.PrintMessage(1, err.Error())
            return
        }
        bytesCopied, err := fsys.StoreImage(filePath, file)
        if err != nil {
            cio.PrintMessage(1, err.Error())
            return
        }
        cio.PrintMessage(0, "File "+filePath+" has been created.")
        if err != nil {
            cio.PrintMessage(1, err.Error())
            return
        }
        cio.PrintMessage(0, "Content of uploaded image ("+strconv.FormatInt(bytesCopied, 10)+" Bytes) has been copied to "+filePath+".")
        http.Redirect(w, req, "/"+id, http.StatusFound)
    }
}

Qt C++客户端代码:

void Share::upload(const QByteArray &data) {
    QHttpMultiPart *multi_part = new QHttpMultiPart(QHttpMultiPart::FormDataType);
    QHttpPart text_part;
    text_part.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"text\""));
    text_part.setBody("Screenshot.png");
    QHttpPart image_part;
    image_part.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/png"));
    image_part.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"image\""));
    image_part.setBody(data);
    multi_part->append(text_part);
    multi_part->append(image_part);
    QNetworkRequest request(QUrl("http://localhost:8000/api/upload"));
    QNetworkAccessManager *manager = new QNetworkAccessManager();
    connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(reply_finished(QNetworkReply *)));
    manager->post(request, multi_part);
    qDebug() << QString(data);
}
英文:

I have a Go API that should save an image sent by a client. I know that the Go code works when the POST request comes from a HTML form.
When sending a multipart post request from my Qt C++ client though, the server returns an error

> http: no such file

On the client side I have a QPixmap, which I transform to a QByteArray, which I then send, but somehow I get that error from Go. I know that the length of the data sent by the client decreases when I remove

multi_part-&gt;append(image_part);

so the QPixmap should be sent.

Go code:

func apiUploadHandler(w http.ResponseWriter, req *http.Request) {
if req.Method == &quot;POST&quot; {
	req.ParseMultipartForm(0)
	fmt.Printf(&quot;%v %v %v&quot;, req.RemoteAddr, req.ContentLength, req.Body)
	file, fileheader, err := req.FormFile(&quot;image&quot;)
	if err != nil {
		cio.PrintMessage(1, err.Error())
		return
	}
	defer file.Close()
	var id string
	created := false
	for created != true {
		id = generateImageID()
		err = db.CheckIfImageIDInUse(id)
		if err != nil {
			if err.Error() == &quot;Image ID &#39;&quot;+id+&quot;&#39; exists.&#39;&quot; {
				created = false
				continue
			} else {
				created = false
				cio.PrintMessage(1, err.Error())
				return
			}
		}
		created = true
	}
	filePath := fsys.ImgStoragePath + id + &quot;.&quot; + strings.Split(fileheader.Filename, &quot;.&quot;)[1]
	err = db.StoreImage(id, strings.Split(fileheader.Filename, &quot;.&quot;)[0] /*image name*/, filePath, strings.Split(fileheader.Filename, &quot;.&quot;)[1] /*extension*/)
	if err != nil {
		cio.PrintMessage(1, err.Error())
		return
	}
	bytesCopied, err := fsys.StoreImage(filePath, file)
	if err != nil {
		cio.PrintMessage(1, err.Error())
		return
	}
	cio.PrintMessage(0, &quot;File &quot;+filePath+&quot; has been created.&quot;)
	if err != nil {
		cio.PrintMessage(1, err.Error())
		return
	}
	cio.PrintMessage(0, &quot;Content of uploaded image (&quot;+strconv.FormatInt(bytesCopied, 10)+&quot; Bytes) has been copied to &quot;+filePath+&quot;.&quot;)
	http.Redirect(w, req, &quot;/&quot;+id, http.StatusFound)
}

}

Qt C++ client code:

void Share::upload(const QByteArray &amp;data) {
    QHttpMultiPart *multi_part = new          QHttpMultiPart(QHttpMultiPart::FormDataType);
    QHttpPart text_part;
    text_part.setHeader(QNetworkRequest::ContentDispositionHeader,   QVariant(&quot;form-data; name=\&quot;text\&quot;\&quot;&quot;));
    text_part.setBody(&quot;Screenshot.png&quot;);
    QHttpPart image_part;
    image_part.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(&quot;image/png&quot;));
    image_part.setHeader(QNetworkRequest::ContentDispositionHeader,  QVariant(&quot;form-data; name=\&quot;image\&quot;&quot;));
    image_part.setBody(data);
    multi_part-&gt;append(text_part);
    multi_part-&gt;append(image_part);
    QNetworkRequest request(QUrl(&quot;http://localhost:8000/api/upload&quot;));
    QNetworkAccessManager *manager = new QNetworkAccessManager();
    connect(manager, SIGNAL(finished(QNetworkReply *)), this,    SLOT(reply_finished(QNetworkReply *)));
    manager-&gt;post(request, multi_part);
    qDebug() &lt;&lt; QString(data);
}

答案1

得分: 1

我不确定,但你可以尝试将以下代码部分进行更改:

image_part.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"image\""));

更改为以下内容:

image_part.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"image\"; filename=\"Screenshot.png\""));

这样可能会起到你想要的效果。

英文:

I'm not sure but you can try to change

image_part.setHeader(QNetworkRequest::ContentDispositionHeader,  QVariant(&quot;form-data; name=\&quot;image\&quot;&quot;));

to something like

image_part.setHeader(QNetworkRequest::ContentDispositionHeader,  QVariant(&quot;form-data; name=\&quot;image\&quot;; filename=\&quot;Screenshot.png\&quot;&quot;));

huangapple
  • 本文由 发表于 2016年1月29日 19:39:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/35083636.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定