summaryrefslogtreecommitdiff
path: root/src/HttpConnection.cc
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2007-06-30 09:52:39 +0000
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2007-06-30 09:52:39 +0000
commite36a3de0f458a9267f4d4907e78e706400b7a18c (patch)
tree2802fa3d5bf59eed3e07368764a18904b11f05ab /src/HttpConnection.cc
parent50b4cf67e04f4253891c53c1b1b97168fdc1aa76 (diff)
2007-06-30 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Made -S option work with metalink file and provided selective download to metalink. * src/MetalinkEntry.h, src/MetalinkEntry.cc (filename): Removed. (file): New variable. (size): Removed. (operator=): Updated. (getPath): New function. (getLength): New function. (toFileEntry): New function. * src/TorrentRequestInfo.h, src/TorrentRequestInfo.cc (execute): Use toStream. (showFileEntry): Removed. * src/MetalinkRequestInfo.h (targetFiles): New variable. (setTargetFiles): New variable. * src/MetalinkRequestInfo.cc (execute): Added the ability to print file information included in a metalink file. Added selective download mode to metalink. * src/main.cc (showUsage): Updated to denote that -S and --select-file options are applicable to metalink. * src/FileEntry.h (operator=): New function. (getBasename): New function. (getDirname): New function. * src/Util.h, src/Util.cc (toStream): New function. * src/Xml2MetalinkProcessor.cc: Updated. Made aria2 work with metalink with directory structure. * src/File.h, src/File.cc (getBasename): New function. (getDirname): New function. * src/RequestGroup.h, src/RequestGroup.cc (_topDir): New variable. (setTopDir): New function. (initSegmentMan): A directory structure is added to _segmentMan->dir. Rewrote HTTP header parsing with stringstream. * src/HttpConnection.h, src/HttpConnection.cc (HttpRequestEntry): New class. (headerBuf): Removed. (headerBufLength): Removed. (outstandingHttpRequests): Now its element type is HttpRequestEntryHandle. (findEndOfHeader): Removed. (receiveResponse): Rewritten. Updated doc for -j option to notice that it should be used with -i option. * src/main.cc (showUsage) Removed unused classes. * src/RequestInfo.h (FileInfo): Removed. (checksum): Removed. (fileInfo): Removed. (setChecksum): Removed. (getChecksum): Removed. (getFileInfo): Removed. Use ISO units. * src/ConsoleDownloadEngine.cc * src/TorrentConsoleDownloadEngine.cc * src/Util.cc (abbrevSize)
Diffstat (limited to 'src/HttpConnection.cc')
-rw-r--r--src/HttpConnection.cc102
1 files changed, 28 insertions, 74 deletions
diff --git a/src/HttpConnection.cc b/src/HttpConnection.cc
index c35273ed..7f93bb26 100644
--- a/src/HttpConnection.cc
+++ b/src/HttpConnection.cc
@@ -34,6 +34,7 @@
/* copyright --> */
#include "HttpConnection.h"
#include "DlRetryEx.h"
+#include "DlAbortEx.h"
#include "Util.h"
#include "Base64.h"
#include "message.h"
@@ -44,9 +45,8 @@
HttpConnection::HttpConnection(int cuid,
const SocketHandle& socket,
const Option* op):
- cuid(cuid), socket(socket), option(op), headerBufLength(0) {
- logger = LogFactory::getInstance();
-}
+ cuid(cuid), socket(socket), option(op), logger(LogFactory::getInstance())
+{}
string HttpConnection::eraseConfidentialInfo(const string& request)
{
@@ -70,7 +70,8 @@ void HttpConnection::sendRequest(const HttpRequestHandle& httpRequest)
string request = httpRequest->createRequest();
logger->info(MSG_SENDING_REQUEST, cuid, eraseConfidentialInfo(request).c_str());
socket->writeData(request.c_str(), request.size());
- outstandingHttpRequests.push_back(httpRequest);
+ outstandingHttpRequests.push_back(new HttpRequestEntry(httpRequest,
+ new HttpHeaderProcessor()));
}
void HttpConnection::sendProxyRequest(const HttpRequestHandle& httpRequest)
@@ -78,88 +79,41 @@ void HttpConnection::sendProxyRequest(const HttpRequestHandle& httpRequest)
string request = httpRequest->createProxyRequest();
logger->info(MSG_SENDING_REQUEST, cuid, eraseConfidentialInfo(request).c_str());
socket->writeData(request.c_str(), request.size());
- outstandingHttpRequests.push_back(httpRequest);
-}
-
-int HttpConnection::findEndOfHeader(const char* buf, const char* substr, int bufLength) const {
- const char* p = buf;
- while(bufLength > p-buf && bufLength-(p-buf) >= (int)strlen(substr)) {
- if(memcmp(p, substr, strlen(substr)) == 0) {
- return p-buf;
- }
- p++;
- }
- return -1;
+ outstandingHttpRequests.push_back(new HttpRequestEntry(httpRequest,
+ new HttpHeaderProcessor()));
}
HttpResponseHandle HttpConnection::receiveResponse() {
- //char buf[512];
- string header;
- int delimiterSwitch = 0;
- char* delimiters[] = { "\r\n", "\n" };
-
- int size = HEADERBUF_SIZE-headerBufLength;
- if(size < 0) {
- // TODO too large header
- throw new DlRetryEx("too large header > 4096");
+ if(outstandingHttpRequests.size() == 0) {
+ throw new DlAbortEx("No HttpRequestEntry found.");
}
- socket->peekData(headerBuf+headerBufLength, size);
+ HttpRequestEntryHandle entry = outstandingHttpRequests.front();
+ HttpHeaderProcessorHandle proc = entry->getHttpHeaderProcessor();
+
+ char buf[512];
+ int32_t size = sizeof(buf);
+ socket->peekData(buf, size);
if(size == 0) {
throw new DlRetryEx(EX_INVALID_RESPONSE);
}
- //buf[size] = '\0';
- int hlenTemp = headerBufLength+size;
- //header += buf;
- //string::size_type p;
- int eohIndex;
-
- if((eohIndex = findEndOfHeader(headerBuf, "\r\n\r\n", hlenTemp)) == -1 &&
- (eohIndex = findEndOfHeader(headerBuf, "\n\n", hlenTemp)) == -1) {
- socket->readData(headerBuf+headerBufLength, size);
- headerBufLength += size;
- } else {
- if(headerBuf[eohIndex] == '\n') {
- // for crapping non-standard HTTP server
- delimiterSwitch = 1;
- } else {
- delimiterSwitch = 0;
- }
- headerBuf[eohIndex+strlen(delimiters[delimiterSwitch])*2] = '\0';
- header = headerBuf;
- size = eohIndex+strlen(delimiters[delimiterSwitch])*2-headerBufLength;
- socket->readData(headerBuf+headerBufLength, size);
- }
- if(!Util::endsWith(header, "\r\n\r\n") && !Util::endsWith(header, "\n\n")) {
+ proc->update(buf, size);
+ if(!proc->eoh()) {
+ socket->readData(buf, size);
return 0;
}
+ int32_t putbackDataLength = proc->getPutBackDataLength();
+ size -= putbackDataLength;
+ socket->readData(buf, size);
+
// OK, we got all headers.
- logger->info(MSG_RECEIVE_RESPONSE, cuid, header.c_str());
- string::size_type p, np;
- p = np = 0;
- np = header.find(delimiters[delimiterSwitch], p);
- if(np == string::npos) {
- throw new DlRetryEx(EX_NO_STATUS_HEADER);
- }
- // check HTTP status value
- if(header.size() <= 12) {
- throw new DlRetryEx(EX_NO_STATUS_HEADER);
- }
- string status = header.substr(9, 3);
- p = np+2;
- HttpHeaderHandle httpHeader = new HttpHeader();
- // retreive status name-value pairs, then push these into map
- while((np = header.find(delimiters[delimiterSwitch], p)) != string::npos && np != p) {
- string line = header.substr(p, np-p);
- p = np+2;
- pair<string, string> hp;
- Util::split(hp, line, ':');
- httpHeader->put(hp.first, hp.second);
- }
+ logger->info(MSG_RECEIVE_RESPONSE, cuid, proc->getHeaderString().c_str());
+
+ pair<string, HttpHeaderHandle> httpStatusHeader = proc->getHttpStatusHeader();
HttpResponseHandle httpResponse = new HttpResponse();
httpResponse->setCuid(cuid);
- httpResponse->setStatus(strtol(status.c_str(), 0, 10));
- httpResponse->setHttpHeader(httpHeader);
- httpResponse->setHttpRequest(outstandingHttpRequests.front());
+ httpResponse->setStatus(strtol(httpStatusHeader.first.c_str(), 0, 10));
+ httpResponse->setHttpHeader(httpStatusHeader.second);
+ httpResponse->setHttpRequest(entry->getHttpRequest());
outstandingHttpRequests.pop_front();