From 91cd90b19ae0c7529947aacc55ff169e82c6a38e Mon Sep 17 00:00:00 2001 From: Matchman Green Date: Sun, 29 Apr 2012 10:22:58 +0800 Subject: [PATCH] fixed still memcpy bug --- src/drive/Drive.cc | 39 +++++++++++++++++-- src/protocol/HTTP.cc | 89 +++++++++++++++++++++++++++++++++++++++++--- src/protocol/HTTP.hh | 2 + 3 files changed, 121 insertions(+), 9 deletions(-) diff --git a/src/drive/Drive.cc b/src/drive/Drive.cc index c3f09a9..50e4942 100644 --- a/src/drive/Drive.cc +++ b/src/drive/Drive.cc @@ -31,6 +31,7 @@ #include #include #include +#include // for debugging only #include @@ -190,7 +191,7 @@ void Drive::UpdateFile( const Json& entry ) DateTime local = ifile ? os::FileMTime( path ) : DateTime() ; // remote file is newer, download file - if ( remote > local ) + if ( !ifile || remote > local ) { std::cout << "downloading " << path << std::endl ; http::GetFile( url, path, m_http_hdr ) ; @@ -213,9 +214,41 @@ void Drive::UploadFile( const Json& entry ) "http://schemas.google.com/g/2005#resumable-edit-media" )["href"] ; std::cout << resume_link.As() << std::endl ; - std::string resp = http::Put( resume_link.Get(), "", m_http_hdr ) ; + http::Headers hdr( m_http_hdr ) ; + hdr.push_back( "Expect:" ) ; + hdr.push_back( "If-Match: *" ) ; + hdr.push_back( "X-Upload-Content-Length: 29" ) ; + hdr.push_back( "X-Upload-Content-Type: text/plain" ) ; - std::cout << "resp " << resp ; + std::istringstream resp( http::Put( resume_link.Get(), "", hdr ) ) ; + + std::string line ; + while ( std::getline( resp, line ) ) + { + // find the location header + static const std::string location = "Location: " ; + if ( line.substr( 0, location.size() ) == location ) + { + std::string upload_uri = line.substr( location.size() ) ; + upload_uri = upload_uri.substr( 0, upload_uri.size() - 1 ) ; + std::cout << upload_uri << std::endl ; + + std::string upload_content = "this is the new text file!!!!" ; + + std::ostringstream content_range ; + content_range << "Content-Range: 0-" << upload_content.size()-1 << '/' << upload_content.size() ; + + http::Headers upload_hdr/*( m_http_hdr )*/ ; + upload_hdr.push_back( "Expect:" ) ; + upload_hdr.push_back( "Accept:" ) ; + upload_hdr.push_back( "Host:" ) ; +// upload_hdr.push_back( "Content-Type: text/plain" ) ; + upload_hdr.push_back( content_range.str() ) ; + + std::string resp2 = http::Put( upload_uri, upload_content, upload_hdr ) ; + std::cout << resp2 << std::endl ; + } + } } } // end of namespace diff --git a/src/protocol/HTTP.cc b/src/protocol/HTTP.cc index 452fddc..e084f3f 100644 --- a/src/protocol/HTTP.cc +++ b/src/protocol/HTTP.cc @@ -54,9 +54,10 @@ size_t ReadCallback( void *ptr, std::size_t size, std::size_t nmemb, std::string std::size_t count = std::min( size * nmemb, data->size() ) ; if ( count > 0 ) { - std::memcpy( &(*data)[0], ptr, count ) ; + std::memcpy( ptr, &(*data)[0], count ) ; data->erase( 0, count ) ; } + return count ; } @@ -162,7 +163,7 @@ std::string PostData( const std::string& url, const std::string& data, const Hea std::string post_data = data ; - curl_easy_setopt(curl, CURLOPT_POST, 1); + curl_easy_setopt(curl, CURLOPT_POST, 1L); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, &post_data[0] ) ; curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, post_data.size() ) ; @@ -183,18 +184,94 @@ std::string Put( { std::string resp ; CURL *curl = InitCurl( url, &resp, hdr ) ; - - std::string put_data = data ; - curl_easy_setopt(curl, CURLOPT_UPLOAD, 1); + std::string put_data = data ; + + // set common options + curl_easy_setopt(curl, CURLOPT_HEADER, 1L ); + curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L ) ; curl_easy_setopt(curl, CURLOPT_READFUNCTION, &ReadCallback ) ; curl_easy_setopt(curl, CURLOPT_READDATA , &put_data ) ; curl_easy_setopt(curl, CURLOPT_INFILESIZE, put_data.size() ) ; - + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L ) ; + DoCurl( curl ) ; return resp; } +void Custom( const std::string& url, const std::string& host, const Headers& headers ) +{ + CURL *curl = curl_easy_init(); + if ( curl == 0 ) + throw std::bad_alloc() ; + + // set common options + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1L ); + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L ) ; + if ( curl_easy_perform( curl ) != 0 ) + throw std::runtime_error( "curl perform fail" ) ; + + long sockextr; + curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, &sockextr); + curl_socket_t sockfd = sockextr ; + + struct timeval tv; + tv.tv_sec = 60 ; + tv.tv_usec = 0 ; + + fd_set infd, outfd, errfd; + FD_ZERO(&infd); + FD_ZERO(&outfd); + FD_ZERO(&errfd); + + FD_SET(sockfd, &errfd); /* always check for error */ + FD_SET(sockfd, &outfd); + if ( select(sockfd + 1, &infd, &outfd, &errfd, &tv) == -1 ) + throw std::runtime_error( "select fail" ) ; + + std::string path = url.substr( host.size() ) ; + std::cout << ("PUT " + path + "HTTP/1.1") << std::endl ; + + std::ostringstream req ; + req << ("PUT " + path + "HTTP/1.1\n") + << "Host: " << "docs.google.com" << "\n" ; + + for ( Headers::const_iterator i = headers.begin() ; i != headers.end() ; ++i ) + req << *i << '\n' ; + + std::string data = "hahaha this is the new file!!!!!" ; + req << "Content-Length: " << data.size() << '\n' + << "Content-Range: 0-" << data.size()-1 << '/' << data.size() << "\n\n\n" + << data ; + + std::string reqstr = req.str() ; + std::cout << "requesting: \n" << reqstr << std::endl ; + + std::size_t iolen ; + if ( curl_easy_send(curl, &reqstr[0], reqstr.size(), &iolen) != CURLE_OK ) + throw std::runtime_error( "cannot send" ) ; + + while ( true ) + { + char buf[1024+1] ; + FD_ZERO(&infd); + FD_ZERO(&outfd); + FD_ZERO(&errfd); + + FD_SET(sockfd, &errfd); /* always check for error */ + FD_SET(sockfd, &infd); + if ( select(sockfd + 1, &infd, &outfd, &errfd, &tv) == -1 ) + throw std::runtime_error( "select fail" ) ; + + if ( curl_easy_recv(curl, buf, 1024, &iolen) != CURLE_OK ) + throw std::runtime_error( "cannot send" ) ; + + buf[iolen] = '\0' ; + std::cout << "read: " << buf << std::endl ; + } +} + std::string Escape( const std::string& str ) { CURL *curl = curl_easy_init(); diff --git a/src/protocol/HTTP.hh b/src/protocol/HTTP.hh index 669d57c..107f2ef 100644 --- a/src/protocol/HTTP.hh +++ b/src/protocol/HTTP.hh @@ -53,6 +53,8 @@ namespace gr { namespace http const std::string& data, const Headers& hdr = Headers() ) ; + void Custom( const std::string& url, const std::string& host, const Headers& headers ) ; + std::string Escape( const std::string& str ) ; std::string Unescape( const std::string& str ) ;