diff --git a/ChangeLog b/ChangeLog
index 41c15fd8..be792a23 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2007-03-25  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
+
+	Use filename and size from Metalink file instead of sending HEAD
+	request:
+	* src/UrlRequestInfo.h
+	(_filename): New variable.
+	(_totalLength): New variable.
+	(setTotalLength): New variable.
+	(setFilename): New variable.
+	* src/MetalinkRequestInfo.cc
+	(execute): Set filename and size to UrlRequestInfo
+	* src/UrlRequestInfo.cc
+	(execute): Use filename and size from Metalink instead of seding
+	HEAD request to servers.
+
 2007-03-24  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
 
 	To add the ability to resume downloading a partially downloaded file
diff --git a/src/MetalinkRequestInfo.cc b/src/MetalinkRequestInfo.cc
index 8e151a4a..b7fbb037 100644
--- a/src/MetalinkRequestInfo.cc
+++ b/src/MetalinkRequestInfo.cc
@@ -122,6 +122,8 @@ RequestInfos MetalinkRequestInfo::execute() {
 	urls.push_back((*itr)->url);
       }
       UrlRequestInfoHandle reqInfo = new UrlRequestInfo(urls, maxConnection, op);
+      reqInfo->setFilename(entry->filename);
+      reqInfo->setTotalLength(entry->size);
 #ifdef ENABLE_MESSAGE_DIGEST
       reqInfo->setChecksum(checksum);
       if(!entry->chunkChecksum.isNull()) {
diff --git a/src/UrlRequestInfo.cc b/src/UrlRequestInfo.cc
index c2f222a9..dc677b0b 100644
--- a/src/UrlRequestInfo.cc
+++ b/src/UrlRequestInfo.cc
@@ -159,13 +159,19 @@ RequestInfos UrlRequestInfo::execute() {
 
   RequestInfo* next = 0;
   try {
-    HeadResultHandle hr = getHeadResult();
-    
-    if(hr.isNull()) {
-      logger->notice("No URI to download. Download aborted.");
-      return RequestInfos();
+    HeadResultHandle hr(0);
+    if(_totalLength == 0 || _filename.length() == 0) {
+      hr = getHeadResult();
+      
+      if(hr.isNull()) {
+	logger->notice(MSG_NO_URL_TO_DOWNLOAD);
+	return RequestInfos();
+      }
+    } else {
+      hr = new HeadResult();
+      hr->filename = _filename;
+      hr->totalLength = _totalLength;
     }
-    
     logger->info("Head result: filename=%s, total length=%s",
 		 hr->filename.c_str(), Util::ullitos(hr->totalLength, true).c_str());
     
@@ -174,6 +180,11 @@ RequestInfos UrlRequestInfo::execute() {
 			   op->get(PREF_REFERER),
 			   op->getAsInt(PREF_SPLIT)));
     
+    if(requests.size() == 0) {
+      logger->notice(MSG_NO_URL_TO_DOWNLOAD);
+      return RequestInfos();
+    }
+
     adjustRequestSize(requests, reserved, maxConnections);
     
     SharedHandle<ConsoleDownloadEngine> e(DownloadEngineFactory::newConsoleEngine(op, requests, reserved));
diff --git a/src/UrlRequestInfo.h b/src/UrlRequestInfo.h
index 94e1680b..40f0152d 100644
--- a/src/UrlRequestInfo.h
+++ b/src/UrlRequestInfo.h
@@ -53,6 +53,8 @@ class UrlRequestInfo : public RequestInfo {
 private:
   Strings urls;
   int maxConnections;
+  string _filename;
+  int64_t _totalLength;
 #ifdef ENABLE_MESSAGE_DIGEST
   MessageDigestContext::DigestAlgo digestAlgo;
   int32_t chunkChecksumLength;
@@ -69,7 +71,8 @@ public:
   UrlRequestInfo(const Strings& urls, int maxConnections, Option* op):
     RequestInfo(op),
     urls(urls),
-    maxConnections(maxConnections)
+    maxConnections(maxConnections),
+    _totalLength(0)
 #ifdef ENABLE_MESSAGE_DIGEST
     ,
     digestAlgo(DIGEST_ALGO_SHA1),
@@ -98,6 +101,16 @@ public:
     this->chunkChecksums = chunkChecksums;
   }
 #endif // ENABLE_MESSAGE_DIGEST
+
+  void setTotalLength(int64_t totalLength)
+  {
+    _totalLength = totalLength;
+  }
+
+  void setFilename(const string& filename)
+  {
+    _filename = filename;
+  }
 };
 
 typedef SharedHandle<UrlRequestInfo> UrlRequestInfoHandle;
diff --git a/src/message.h b/src/message.h
index fc2d288e..26d42139 100644
--- a/src/message.h
+++ b/src/message.h
@@ -64,6 +64,7 @@
 #define MSG_SAVED_SEGMENT_FILE _("The segment file was saved successfully.")
 #define MSG_LOADING_SEGMENT_FILE _("Loading the segment file %s.")
 #define MSG_LOADED_SEGMENT_FILE _("The segment file was loaded successfully.")
+#define MSG_NO_URL_TO_DOWNLOAD _("No URI to download. Download aborted.")
 
 #define EX_TIME_OUT _("Timeout.")
 #define EX_INVALID_CHUNK_SIZE _("Invalid chunk size.")