fixed upload

pull/40/head
Matchman Green 2012-05-21 00:10:29 +08:00
parent 99f6e4cc58
commit c7c49b094a
7 changed files with 62 additions and 41 deletions

View File

@ -103,6 +103,22 @@ const std::vector<std::string>& Entry::ParentHrefs() const
return m_parent_hrefs ;
}
/// only assign the key members
void Entry::AssignID( const Entry& entry )
{
m_self_href = entry.m_self_href ;
m_resource_id = entry.m_resource_id ;
m_parent_hrefs = entry.m_parent_hrefs ;
m_upload_link = entry.m_upload_link ;
m_etag = entry.m_etag ;
}
void Entry::Update( const std::string& md5, const DateTime& mtime )
{
m_mtime = mtime ;
m_md5 = md5 ;
}
std::string Entry::Title() const
{
return m_title ;

View File

@ -54,6 +54,8 @@ public :
const DateTime& mtime,
const std::string& parent_href ) ;
void AssignID( const Entry& entry ) ;
std::string Title() const ;
std::string Filename() const ;
std::string Kind() const ;
@ -73,6 +75,7 @@ public :
void Swap( Entry& e ) ;
void Update( const xml::Node& entry ) ;
void Update( const std::string& md5, const DateTime& mtime ) ;
private :
std::string m_title ;

View File

@ -28,11 +28,11 @@
#include "util/Crypt.hh"
#include "util/Log.hh"
#include "util/OS.hh"
#include "util/StdioFile.hh"
#include "xml/Node.hh"
#include "xml/NodeSet.hh"
#include <cassert>
#include <fstream>
// for debugging
#include <iostream>
@ -103,12 +103,14 @@ void Resource::FromRemote( const Entry& remote )
else
{
assert( m_state == local_new || m_state == local_changed || m_state == local_deleted ) ;
m_state = ( remote.MTime() > m_entry.MTime() ? remote_changed : m_state ) ;
m_state = ( m_state == local_new ? local_changed : m_state ) ;
Log( "%1% state is %2%", Name(), m_state, log::verbose ) ;
}
m_entry = remote ;
m_entry.AssignID( remote ) ;
}
void Resource::FromLocal()
@ -119,25 +121,19 @@ void Resource::FromLocal()
m_state = local_deleted ;
Log( "%1% in state but not exist on disk: %2%", Name(), m_state ) ;
}
// to save time, compare mtime before checksum
else if ( os::FileMTime( path ) > m_entry.MTime() )
{
if ( m_entry.MD5() == crypt::MD5( path ) )
{
m_state = local_new ;
Log( "%1% mtime newer on disk but unchanged: %2%", Name(), m_state ) ;
}
else
{
m_state = local_changed ;
Log( "%1% changed on disk: %2%", Name(), m_state ) ;
}
}
else
{
m_state = local_new ;
Log( "%1% unchanged on disk: %2%", Name(), m_state ) ;
// to save time, compare mtime before checksum
DateTime mtime = os::FileMTime( path ) ;
if ( mtime > m_entry.MTime() )
{
Log( "%1% mtime newer on disk: %2%", Name(), m_state ) ;
m_entry.Update( crypt::MD5( path ), mtime ) ;
}
else
Log( "%1% unchanged on disk: %2%", Name(), m_state ) ;
}
}
@ -279,12 +275,6 @@ void Resource::Download( http::Agent* http, const fs::path& file, const http::He
}
bool Resource::Upload( http::Agent* http, const http::Headers& auth )
{
std::ifstream ifile( Path().string().c_str(), std::ios::binary | std::ios::in ) ;
return Upload( http, ifile.rdbuf(), auth ) ;
}
bool Resource::Upload( http::Agent* http, std::streambuf *file, const http::Headers& auth )
{
// upload link missing means that file is read only
if ( m_entry.UploadLink().empty() )
@ -294,6 +284,7 @@ bool Resource::Upload( http::Agent* http, std::streambuf *file, const http::Head
}
Log( "Uploading %1%", m_entry.Title() ) ;
// std::ifstream ifile( Path().string().c_str(), std::ios::binary | std::ios::in ) ;
std::string meta =
"<?xml version='1.0' encoding='UTF-8'?>\n"
@ -303,10 +294,20 @@ bool Resource::Upload( http::Agent* http, std::streambuf *file, const http::Head
"<title>" + m_entry.Filename() + "</title>"
"</entry>" ;
std::string data(
(std::istreambuf_iterator<char>(file)),
(std::istreambuf_iterator<char>()) ) ;
// std::string data(
// (std::istreambuf_iterator<char>(ifile)),
// (std::istreambuf_iterator<char>()) ) ;
StdioFile file( Path(), "rb" ) ;
std::string data ;
char buf[4096] ;
std::size_t count = 0 ;
while ( (count = file.Read( buf, sizeof(buf) )) > 0 )
data.append( buf, count ) ;
Trace( "%1% bytes: \"%2%\"", data.size(), data ) ;
Trace( "etag \"%1%\"", m_entry.ETag() ) ;
std::ostringstream xcontent_len ;
xcontent_len << "X-Upload-Content-Length: " << data.size() ;
@ -320,18 +321,16 @@ bool Resource::Upload( http::Agent* http, std::streambuf *file, const http::Head
http::StringResponse str ;
http->Put( m_entry.UploadLink(), meta, &str, hdr ) ;
std::string uplink = http->RedirLocation() ;
// parse the header and find "Location"
http::Headers uphdr ;
uphdr.push_back( "Expect:" ) ;
uphdr.push_back( "Accept:" ) ;
http::XmlResponse xml ;
http->Put( uplink, data, &xml, uphdr ) ;
// uphdr.push_back( "If-Match: " + m_entry.ETag() ) ;
Trace( "Receipted response = %1%", xml.Response() ) ;
// the content upload URL is in the "Location" HTTP header
std::string uplink = http->RedirLocation() ;
http::XmlResponse xml ;
http->Put( uplink, data, &xml, uphdr ) ;
m_entry.Update( xml.Response() ) ;
return true ;

View File

@ -114,7 +114,6 @@ private :
private :
void Download( http::Agent* http, const fs::path& file, const http::Headers& auth ) const ;
bool Upload( http::Agent* http, const http::Headers& auth ) ;
bool Upload( http::Agent* http, std::streambuf *file, const http::Headers& auth ) ;
private :
Entry m_entry ;

View File

@ -72,8 +72,6 @@ struct Agent::Impl
{
CURL *curl ;
std::string location ;
char error[CURL_ERROR_SIZE] ;
std::string log_prefix ;
} ;
@ -85,7 +83,6 @@ Agent::Agent() :
::curl_easy_setopt( m_pimpl->curl, CURLOPT_SSL_VERIFYHOST, 0L ) ;
::curl_easy_setopt( m_pimpl->curl, CURLOPT_HEADERFUNCTION, &Agent::HeaderCallback ) ;
::curl_easy_setopt( m_pimpl->curl, CURLOPT_WRITEHEADER , this ) ;
::curl_easy_setopt( m_pimpl->curl, CURLOPT_ERRORBUFFER, m_pimpl->error ) ;
::curl_easy_setopt( m_pimpl->curl, CURLOPT_HEADER, 0L ) ;
}
@ -127,9 +124,12 @@ long Agent::ExecCurl(
{
CURL *curl = m_pimpl->curl ;
assert( curl != 0 ) ;
char error[CURL_ERROR_SIZE] ;
::curl_easy_setopt( m_pimpl->curl, CURLOPT_ERRORBUFFER, error ) ;
SetHeader( hdr ) ;
dest->Clear() ;
CURLcode curl_code = ::curl_easy_perform(curl);
@ -143,7 +143,7 @@ long Agent::ExecCurl(
throw Error()
<< CurlCode( curl_code )
<< HttpResponse( http_code )
<< expt::ErrMsg( m_pimpl->error ) ;
<< expt::ErrMsg( error ) ;
}
return http_code ;

View File

@ -31,4 +31,7 @@ typedef boost::error_info<struct CurlCodeTag, int> CurlCode ;
// HTTP response code
typedef boost::error_info<struct HttpResponseTag, int> HttpResponse ;
// HTTP response code
typedef boost::error_info<struct HttpResponseStrTag, std::string> HttpResponseText ;
} } // end of namespace

View File

@ -19,6 +19,7 @@
#include "XmlResponse.hh"
#include "util/Log.hh"
#include "xml/Node.hh"
#include "xml/TreeBuilder.hh"