Solved Error when trying to upload image to BaasBox
-
Hi, I'm trying to upload an image to a BaasBox backend. The endpoint receive data in the following form:
curl -X POST http://localhost:9000/file \ -F file=@test.jpg \ -H X-BB-SESSION:9952384d-8d78-4399-82d0-7039f832a786
I try to upload the image using these three methods:
void Rest::iniciar(QString url) { estatusRespuesta = false; peticion.setUrl(QUrl(url)); peticion.setHeader(peticion.ContentTypeHeader,"application/json"); peticion.setRawHeader(QByteArray("X-BAASBOX-APPCODE"), QByteArray(llave.toStdString().c_str())); } bool Rest::crearCabeceraMultiparte(QString url) { multiparte = new QHttpMultiPart(QHttpMultiPart::FormDataType); QHttpPart parteArchivo; //parteArchivo.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg")); parteArchivo.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"file\"")); QFile* imagen = new QFile(url); if(imagen->open(QIODevice::ReadOnly)) { parteArchivo.setBodyDevice(imagen); imagen->setParent(multiparte); multiparte->append(parteArchivo); return true; } else { qDebug()<< imagen->errorString(); } return false; } void Rest::postArchivo() { respuestaBruta = manejadorConexion->post(peticion, multiparte); multiparte->setParent(respuestaBruta); qDebug()<<"Enviando Post"; connect(respuestaBruta, SIGNAL(finished()), this, SLOT(respuestaRecibida())); //multiparte->deleteLater();
}
But I get this error when the backend response:
Error del Endpoint: QNetworkReply::NetworkError(ProtocolInvalidOperationError) "Vary" : "Accept-Encoding" "Content-Encoding" : "gzip" "Content-Type" : "application/json; charset=utf-8"
-
Hi,
It seems the headers are not matching between your curl sample and your
peticion
object settings. The first one hasX-BB-SESSION
while the other one asX-BAASBOX-APPCODE
.By the way, if
llave
is a QString, you can use.toLatin1()
rather than doing that conversion. -
I update my code and it still give me the same error. the code is the following:
QString url = "http://127.0.0.1:9000/file"; QString campo = "X-BB-SESSION"; QString valor = "codigo usuario"; estatusRespuesta = false; peticion.setUrl(QUrl(url)); peticion.setRawHeader(QByteArray("X-BAASBOX-APPCODE"), QByteArray(llave.toStdString().c_str())); peticion.setRawHeader(QByteArray(campo.toStdString().c_str()), QByteArray(valor.toStdString().c_str())); QFile* imagen = new QFile(url); if(imagen->open(QIODevice::ReadOnly)) { QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); QHttpPart parteArchivo; parteArchivo.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg")); parteArchivo.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"file\"")); parteArchivo.setBodyDevice(imagen); imagen->setParent(multiPart); multiPart->append(parteArchivo); respuestaBruta = manejadorConexion->post(peticion, multiPart); connect(respuestaBruta, SIGNAL(finished()), this, SLOT(respuestaRecibida())); multiPart->setParent(respuestaBruta); qDebug()<<"Enviando Post"; return true; } else { qDebug()<< imagen->errorString(); }
-
Did you try to look for the exact content of the request you send ?
How does it compare to the curl call ?On a side note, rather than doing these multiple conversions that are rather useless, change the type of your variables to be QByteArray directly.
-
@SGaist said in Error when trying to upload image to BaasBox:
Hi, thanks for your reply and sorry for my late one.
I made some changes in my code and now BaasBox save the file I upload, but doesn't recognize what kind of file I'm uploading.
The actual code that make the post isarchivo = new QFile(url); QFileInfo informacionArchivo(url); if(archivo->open(QIODevice::ReadOnly)) { multiParte = new QHttpMultiPart(QHttpMultiPart::FormDataType); QHttpPart parteArchivo; parteArchivo.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"name\"; filename=\""+informacionArchivo.fileName()+"\";\r\n")); parteArchivo.setHeader(QNetworkRequest::ContentTypeHeader, "image/"+informacionArchivo.suffix().toUpper().toLatin1() ); parteArchivo.setBodyDevice(archivo); archivo->setParent(multiParte); multiParte->append(parteArchivo); respuestaBruta = manejadorConexion->post(peticion, multiParte); connect(respuestaBruta, SIGNAL(finished()), this, SLOT(respuestaRecibida())); multiParte->setParent(respuestaBruta); qDebug()<<"Enviando Post"; return true; } else { qDebug()<< archivo->errorString(); }
and Baasbox response with:
"Vary" : "Accept-Encoding" "Access-Control-Allow-Origin" : "*" "Access-Control-Allow-Headers" : "X-Requested-With" "Content-Encoding" : "gzip" "Content-Type" : "application/json; charset=utf-8" "Date" : "Mon, 11 Dec 2017 18:54:42 GMT" "BB-USERNAME" : "admin" "{\"result\":\"ok\",\"data\":{\"@version\":2,\"_creation_date\":\"2017-12-11T14:54:41.903-0400\",\"id\":\"383e5f4e-d393-449d-94d8-055917afd3b6\",\"_author\":\"admin\",\"fileName\":\"2e8f7c8c35a5615fcf295159fcdc00b9.jpg\",\"contentType\":\"image/jpeg\",\"contentLength\":26566,\"metadata\":{\"@version\":1,\"X-Parsed-By\":[\"org.apache.tika.parser.DefaultParser\",\"org.apache.tika.parser.jpeg.JpegParser\"],\"_bb_parser_version\":\"1.0.0-M3-20160325\",\"_bb_parser_exception\":\"org.apache.tika.exception.TikaException: Can't read JPEG metadata\\u000a\\u0009at org.apache.tika.parser.image.ImageMetadataExtractor.parseJpeg(ImageMetadataExtractor.java:100)\\u000a\\u0009at org.apache.tika.parser.jpeg.JpegParser.parse(JpegParser.java:56)\\u000a\\u0009at org.apache.tika.parser.CompositeParser.parse(CompositeParser.java:256)\\u000a\\u0009at org.apache.tika.parser.CompositeParser.parse(CompositeParser.java:256)\\u000a\\u0009at org.apache.tika.parser.AutoDetectParser.parse(AutoDetectParser.java:120)\\u000a\\u0009at com.baasbox.controllers.File.lambda$storeFile$160(File.java:256)\\u000a\\u0009at com.baasbox.db.DbHelper.lambda$withDbFromContext$267(DbHelper.java:876)\\u000a\\u0009at play.core.j.FPromiseHelper$$anonfun$promise$2.apply(FPromiseHelper.scala:34)\\u000a\\u0009at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)\\u000a\\u0009at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)\\u000a\\u0009at play.core.j.HttpExecutionContext$$anon$2.run(HttpExecutionContext.scala:37)\\u000a\\u0009at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:42)\\u000a\\u0009at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:386)\\u000a\\u0009at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)\\u000a\\u0009at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)\\u000a\\u0009at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)\\u000a\\u0009at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)\\u000aCaused by: com.drew.imaging.jpeg.JpegProcessingException: not a jpeg file\\u000a\\u0009at com.drew.imaging.jpeg.JpegSegmentReader.readSegments(JpegSegmentReader.java:215)\\u000a\\u0009at com.drew.imaging.jpeg.JpegSegmentReader.<init>(JpegSegmentReader.java:107)\\u000a\\u0009at com.drew.imaging.jpeg.JpegMetadataReader.readMetadata(JpegMetadataReader.java:70)\\u000a\\u0009at org.apache.tika.parser.image.ImageMetadataExtractor.parseJpeg(ImageMetadataExtractor.java:97)\\u000a\\u0009... 16 more\\u000a\",\"resourceName\":\"2e8f7c8c35a5615fcf295159fcdc00b9.jpg\",\"Content-Type\":\"image/jpeg\",\"_bb_parser_error\":\"TikaException: Can't read JPEG metadata\"},\"attachedData\":{}},\"http_code\":201}"
-
Did you try to follow more closely the example provided in the details of QHttpMultiPart ?
-
Yes, I followed that page to write my code, but I had to add
filename=\""+informacionArchivo.fileName()+"\";\r\n"
to the QHttpPart.setHeader method.
It seems that Baasbox can't read the file metadata and fails to identify the type of the file.
I try to upload my file in QByteArray form but QHttpPart.setBodyDevice only take a QIODevice object as parameter.
Is there any other way to upload a file to a server with a post method using qt? -
You can use a QBuffer but AFAIK it shouldn't change anything.
-
Thanks for your answer.
At last I found the solution and I would like to share it. I had to change this lineparteArchivo.setHeader(QNetworkRequest::ContentDispositionHeader,
QVariant("form-data; name="name"; filename=""+informacionArchivo.fileName()+"";\n"));at the end of the header I put \r\n at the end. I just remove the return of car and the backend recognize the file metadata
-
Glad you found out and thanks for sharing !
-
Thanks to all.
The problem was solved -
This post is deleted!