mirror of https://github.com/vitalif/grive2
fixed upload
parent
99f6e4cc58
commit
c7c49b094a
|
@ -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 ;
|
||||
|
|
|
@ -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 ;
|
||||
|
|
|
@ -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 ;
|
||||
|
|
|
@ -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 ;
|
||||
|
|
|
@ -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 ;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "XmlResponse.hh"
|
||||
|
||||
#include "util/Log.hh"
|
||||
#include "xml/Node.hh"
|
||||
#include "xml/TreeBuilder.hh"
|
||||
|
||||
|
|
Loading…
Reference in New Issue