PDA

View Full Version : HttpHeader Request only part of an entity



nhs_0702
21st April 2010, 11:11
Hi dear all,

I'm reading the code of QT attached http sample(examples\network\http).

In HttpWindow::downloadFile(), I added a key&value pair to the
QHttpRequestHeader, like this:




void HttpWindow::downloadFile()
{
QString qsLink = urlLineEdit->text();
QUrl quUrl(qsLink);
QString qsUrlPath = quUrl.path();
QFileInfo qfiFileInfor(qsUrlPath);
QString qsFileName = qfiFileInfor.fileName();
if (qsFileName.isEmpty())
qsFileName = "index.html";

if (QFile::exists(qsFileName)) {
if (QMessageBox::question(this, tr("HTTP"), tr("There already exists a file called %1 in the current directory. Overwrite?").arg(qsFileName), QMessageBox::Yes|QMessageBox::No, QMessageBox::No)== QMessageBox::No){
return;
}
QFile::remove(qsFileName);
}
qfFileOut = new QFile(qsFileName);
if (!qfFileOut->open(QIODevice::WriteOnly)) {
QMessageBox::information(this, tr("HTTP"),tr("Unable to save the file %1: %2.").arg(qsFileName).arg(qfFileOut->errorString()));
delete qfFileOut;
qfFileOut = 0;
return;
}
QString qsHost = quUrl.host();
QHttp::ConnectionMode qhconMode = quUrl.scheme().toLower() == "https" ? QHttp::ConnectionModeHttps : QHttp::ConnectionModeHttp;
qhHttp->setHost(qsHost, qhconMode, quUrl.port() == -1 ? 0 : quUrl.port());
if (!quUrl.userName().isEmpty())
qhHttp->setUser(quUrl.userName(), quUrl.password());
bHttpRequestAborted = false;
QByteArray qbaUrlPath = QUrl::toPercentEncoding(qsUrlPath, "!$&'()*+,;=:@/");
if (qbaUrlPath.isEmpty())
qbaUrlPath = "/";//_________________________________________
QHttpRequestHeader *qhrhHeader = new QHttpRequestHeader("GET", qbaUrlPath);
qhrhHeader->setValue("Connection", "Keep-Alive");
qhrhHeader->setValue("Accept-Ranges", "byte");
/*qhrhHeader->setValue("Content-Length", "1024");
qhrhHeader->setValue("Content-Type", "application/x-rar-compressed");*/
qhrhHeader->setValue("User-Agent", "Mozilla/5.0");
qhrhHeader->setValue("Range", "bytes=0-999");
qhrhHeader->setValue("Host", qsHost);
iHttpGetId = qhHttp->request(*qhrhHeader, 0, qfFileOut);//_________________________________
qpProgressDialog->setWindowTitle(tr("HTTP"));
qpProgressDialog->setLabelText(tr("Downloading %1.").arg(qsFileName));
downloadButton->setEnabled(false);
}


but when i build it return on funcition is 206



10.2.7 206 Partial Content

The server has fulfilled the partial GET request for the resource. The request MUST have included a Range header field (section 14.35) indicating the desired range, and MAY have included an If-Range header field (section 14.27) to make the request conditional.

The response MUST include the following header fields:

- Either a Content-Range header field (section 14.16) indicating
the range included with this response, or a multipart/byteranges
Content-Type including Content-Range fields for each part. If a
Content-Length header field is present in the response, its
value MUST match the actual number of OCTETs transmitted in the
message-body.

- Date

- ETag and/or Content-Location, if the header would have been sent
in a 200 response to the same request

- Expires, Cache-Control, and/or Vary, if the field-value might
differ from that sent in any previous response for the same
variant

If the 206 response is the result of an If-Range request that used a strong cache validator (see section 13.3.3), the response SHOULD NOT include other entity-headers. If the response is the result of an If-Range request that used a weak validator, the response MUST NOT include other entity-headers; this prevents inconsistencies between cached entity-bodies and updated headers. Otherwise, the response MUST include all of the entity-headers that would have been returned with a 200 (OK) response to the same request.

A cache MUST NOT combine a 206 response with other previously cached content if the ETag or Last-Modified headers do not match exactly, see 13.5.4.

A cache that does not support the Range and Content-Range headers MUST NOT cache 206 (Partial) responses.


can you help me and edit my source

http://www.mediafire.com/?dzjaztigrnm

wysota
21st April 2010, 13:01
So what's wrong with getting 206? That's not an error... It's just QHttp (which is obsolete since a few minor releases of Qt) doesn't support it.

squidge
21st April 2010, 13:24
"Content-Length" and "Content-type" is server header, not client header.

nhs_0702
21st April 2010, 16:50
"Content-Length" and "Content-type" is server header, not client header.

you can see link Http Header : http://en.wikipedia.org/wiki/List_of_HTTP_headers


So what's wrong with getting 206? That's not an error... It's just QHttp (which is obsolete since a few minor releases of Qt) doesn't support it.




i dont think so, i download file DownloadFile.cpp on link: http://cpowone.com/DownloadFile.cpp
error but when i download html,Ex: http://www.qtcentre.org/forums/2-Qt-Programming ,result download good,i think i use confused Header Http

squidge
21st April 2010, 19:05
you can see link Http Header : http://en.wikipedia.org/wiki/List_of_HTTP_headersYes, but your request header is neither a constant 1024 bytes, nor rar-compressed, so both are invalid. So what you are sending to the server is invalid.

nhs_0702
22nd April 2010, 04:51
Yes, but your request header is neither a constant 1024 bytes, nor rar-compressed, so both are invalid. So what you are sending to the server is invalid.

yes,beacause i dont known get Content-Type and Content-Length ,but when i download file http://cpowone.com/DownloadFile.cpp have size Content-Length = 24,487 bytes and Content-Type = text/plain --> it dont download,i dont understand


My new Project :
http://www.4shared.com/file/y0yjaia8/http_224.html


void HttpWindow::downloadFile()
{
QString qsLink = urlLineEdit->text();
QUrl quUrl(qsLink);
QString qsUrlPath = quUrl.path();
QFileInfo qfiFileInfor(qsUrlPath);
QString qsFileName = qfiFileInfor.fileName();
if (qsFileName.isEmpty())
qsFileName = "index.html";

if (QFile::exists(qsFileName)) {
if (QMessageBox::question(this, tr("HTTP"), tr("There already exists a file called %1 in the current directory. Overwrite?").arg(qsFileName), QMessageBox::Yes|QMessageBox::No, QMessageBox::No)== QMessageBox::No){
return;
}
QFile::remove(qsFileName);
}
qfFileOut = new QFile(qsFileName);
if (!qfFileOut->open(QIODevice::WriteOnly)) {
QMessageBox::information(this, tr("HTTP"),tr("Unable to save the file %1: %2.").arg(qsFileName).arg(qfFileOut->errorString()));
delete qfFileOut;
qfFileOut = 0;
return;
}
QString qsHost = quUrl.host();
QHttp::ConnectionMode qhconMode = quUrl.scheme().toLower() == "https" ? QHttp::ConnectionModeHttps : QHttp::ConnectionModeHttp;
qhHttp->setHost(qsHost, qhconMode, quUrl.port() == -1 ? 0 : quUrl.port());
if (!quUrl.userName().isEmpty())
qhHttp->setUser(quUrl.userName(), quUrl.password());
bHttpRequestAborted = false;
QByteArray qbaUrlPath = QUrl::toPercentEncoding(qsUrlPath, "!$&'()*+,;=:@/");
if (qbaUrlPath.isEmpty())
qbaUrlPath = "/";//_________________________________________
QHttpRequestHeader *qhrhHeader = new QHttpRequestHeader("GET", qbaUrlPath);
qhrhHeader->setValue("Connection", "Keep-Alive");
qhrhHeader->setValue("Accept-Ranges", "byte");
qhrhHeader->setValue("Content-Length", "24487");
qhrhHeader->setValue("Content-Type", "text/plain");
qhrhHeader->setValue("Date", "Tue, 15 Nov 1994 08:12:31 GMT");// Date: Tue, 15 Nov 1994 08:12:31 GMT
qhrhHeader->setValue("Content-Location", "/index.htm");// :
qhrhHeader->setValue("Expires", "Thu, 01 Dec 1994 16:00:00 GMT");
qhrhHeader->setValue("User-Agent", "Mozilla/5.0");//Expires: Thu, 01 Dec 1994 16:00:00 GMT
qhrhHeader->setValue("Range", "bytes=0-999");
qhrhHeader->setValue("Host", qsHost);
iHttpGetId = qhHttp->request(*qhrhHeader, 0, qfFileOut);//_________________________________
qpProgressDialog->setWindowTitle(tr("HTTP"));
qpProgressDialog->setLabelText(tr("Downloading %1.").arg(qsFileName));
downloadButton->setEnabled(false);
}

squidge
22nd April 2010, 08:57
You mis-understand. If you use headers such as Content-Length in your request header, you are specifying the length of your request body. When they are used by the server, they are specifying the length of the response body.

If you wish to only request the first 1024 bytes of a document, use the "Range" header.

nhs_0702
22nd April 2010, 18:12
You mis-understand. If you use headers such as Content-Length in your request header, you are specifying the length of your request body. When they are used by the server, they are specifying the length of the response body.

If you wish to only request the first 1024 bytes of a document, use the "Range" header.

please read my code, because I still use the "range" http header, but no connection, it error 206, if so would you please edit my project, thanks

wysota
22nd April 2010, 18:24
You also tell the server - "hey, there are 1024 bytes available for you to read after the last header" which is not true. I don't know if it confuses the server trying to read those 1024 bytes but I guess it could.

Please, don't expect anyone to edit your project for you :) Unless of course you offer a decent pay but then you should be posting in the "jobs" section of the site.

squidge
22nd April 2010, 19:08
please read my code, because I still use the "range" http header, but no connection, it error 206, if so would you please edit my project, thanksI very much doubt anyone here is going to edit your project. We are doing this for free, you should appreciate the helpful advice.

Secondly, 206 isn't an error. It means success. You asked for partial content, and the server provided it.

nhs_0702
22nd April 2010, 19:21
You also tell the server - "hey, there are 1024 bytes available for you to read after the last header" which is not true. I don't know if it confuses the server trying to read those 1024 bytes but I guess it could.

Please, don't expect anyone to edit your project for you :) Unless of course you offer a decent pay but then you should be posting in the "jobs" section of the site.

If I do not have "length Content 'and' Content-Type" will always error 206, how about you explain this?


I very much doubt anyone here is going to edit your project. We are doing this for free, you should appreciate the helpful advice.

Secondly, 206 isn't an error. It means success. You asked for partial content, and the server provided it.

My purpose is want to download each file, if the server returns a 206 error, which means I have not down anything, I'd love to do a similar thing as Internet Download Manager (http://www.internetdownloadmanager.com/)

squidge
22nd April 2010, 19:58
If I do not have "length Content 'and' Content-Type" will always error 206, how about you explain this?That would be correct, as those headers are nothing to do with how many bytes you are requesting, they are to tell the server how many bytes you are SENDING.


My purpose is want to download each file, if the server returns a 206 error, which means I have not down anythingActually, 206 means the server is returning partial file content (rather than the full file).

nhs_0702
22nd April 2010, 20:33
That would be correct, as those headers are nothing to do with how many bytes you are requesting, they are to tell the server how many bytes you are SENDING.

Actually, 206 means the server is returning partial file content (rather than the full file).

yes,i thank you very much,I was successful
if you allow, I want to ask you a bit more, you can only way I get "file size" of a file on the download link ?

squidge
22nd April 2010, 20:44
Send a HEAD request to the server, it will reply with the same header (but no body) as if you sent GET. In this header, you will receive Content-length which will be the size of the file as long as you do not include a "Range" header in your HEAD request (else you'll get the size of your range, which isn't what you want).

Note that not all servers support this, in which case you will be transferring "blind" and will have to depend on a short read.

nhs_0702
22nd April 2010, 20:56
Send a HEAD request to the server, it will reply with the same header (but no body) as if you sent GET. In this header, you will receive Content-length which will be the size of the file as long as you do not include a "Range" header in your HEAD request (else you'll get the size of your range, which isn't what you want).

Note that not all servers support this, in which case you will be transferring "blind" and will have to depend on a short read.

yes, I also think it will get by, but really I do not known write in QTcreator how to get respond Http header, I havent example by learn

wysota
22nd April 2010, 21:06
Come on, man. Simply instead of a "get" request, make a "head" request.

nhs_0702
23rd April 2010, 16:07
Come on, man. Simply instead of a "get" request, make a "head" request.


QFile qfFileHeader("Header.txt");
if (!qfFileHeader.open(QIODevice::WriteOnly)) {
QMessageBox::information(this, tr("HTTP"),tr("Unable to save the file %1: %2.").arg(qsFileName).arg(qfFileOut->errorString()));
return;
}
QHttpRequestHeader qhrhHeaderRespond("HEAD", qbaUrlPath);
qhrhHeaderRespond.setValue("Host", qsHost);
qhHttpRespond->setHost(qsHost, qhconMode, quUrl.port() == -1 ? 0 : quUrl.port());
if (!quUrl.userName().isEmpty())
qhHttpRespond->setUser(quUrl.userName(), quUrl.password());
qhHttpRespond->request(qhrhHeaderRespond, 0, &qfFileHeader);

it dont get in File Header.txt

wysota
23rd April 2010, 16:43
I think you misunderstand what a "head" request is.

http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

nhs_0702
24th April 2010, 02:38
I think you misunderstand what a "head" request is.

http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

must i get content-length in Funcition void HttpWindow::readResponseHeader(const QHttpResponseHeader &responseHeader) by funciton QString s =responseHeader.toString(); ?
but i get mis information

Ex:

+ s "HTTP/1.1 200 OK
Date: Sat, 24 Apr 2010 00:41:00 GMT
Server: Apache/2.0.63 (Unix) mod_ssl/2.0.63 OpenSSL/0.9.8e-fips-rhel5 mod_auth_passthrough/2.1 mod_bwlimited/1.4 PHP/5.2.8
Last-Modified: Sat, QString

wysota
25th April 2010, 09:30
must i get content-length in Funcition void HttpWindow::readResponseHeader(const QHttpResponseHeader &responseHeader) by funciton QString s =responseHeader.toString(); ?
but i get mis information

I have no idea what you mean. Please rephrase the question.

nhs_0702
25th April 2010, 10:18
I have no idea what you mean. Please rephrase the question.

thank you,i was get file size,thank you again

squidge
25th April 2010, 10:35
Not every server supports Content-length. You should use it if its there, but you can't depend on it being there. This is why web browsers sometimes say "Downloaded 130KB of unknown" for example.