From d784ec66fa0019ae1b359578a85488649fdbd621 Mon Sep 17 00:00:00 2001 From: CoolStar Date: Thu, 2 May 2019 01:02:42 -0700 Subject: 1.8.0-Sileo --- methods/nshttp.mm | 196 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 methods/nshttp.mm (limited to 'methods/nshttp.mm') diff --git a/methods/nshttp.mm b/methods/nshttp.mm new file mode 100644 index 000000000..4f4e438b0 --- /dev/null +++ b/methods/nshttp.mm @@ -0,0 +1,196 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +/* ###################################################################### + + RSH method - Transfer files via rsh compatible program + + Written by Ben Collins , Copyright (c) 2000 + Licensed under the GNU General Public License v2 [no exception clauses] + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include + +#include +#include +#include +#include +#include + +#include "nshttp.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +unsigned long TimeOut = 30; +Configuration::Item const *HttpOptions = 0; +time_t HttpMethod::FailTime = 0; + +// HttpMethod::HttpMethod - Constructor /*{{{*/ +HttpMethod::HttpMethod(std::string &&pProg) : aptMethod(std::move(pProg),"1.0",SendConfig) +{ + signal(SIGTERM,SigTerm); + signal(SIGINT,SigTerm); +} + /*}}}*/ +// HttpMethod::Configuration - Handle a configuration message /*{{{*/ +// --------------------------------------------------------------------- +bool HttpMethod::Configuration(std::string Message) +{ + // enabling privilege dropping for this method requires configuration… + // … which is otherwise lifted straight from root, so use it by default. + _config->Set(std::string("Binary::") + Binary + "::APT::Sandbox::User", ""); + + if (aptMethod::Configuration(Message) == false) + return false; + + std::string const timeconf = std::string("Acquire::") + Binary + "::Timeout"; + TimeOut = _config->FindI(timeconf, TimeOut); + std::string const optsconf = std::string("Acquire::") + Binary + "::Options"; + HttpOptions = _config->Tree(optsconf.c_str()); + + return true; +} + /*}}}*/ +// HttpMethod::SigTerm - Clean up and timestamp the files on exit /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void HttpMethod::SigTerm(int) +{ + _exit(100); +} + /*}}}*/ +// HttpMethod::Fetch - Fetch a URI /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool HttpMethod::Fetch(FetchItem *Itm) +{ + URI Get = Itm->Uri; + std::string cppGet = Get; + NSURL *URL = [NSURL URLWithString:[NSString stringWithUTF8String:cppGet.c_str()]]; + __block FetchResult Res; + Res.Filename = Itm->DestFile; + Res.IMSHit = false; + + __block BOOL success = NO; + + dispatch_semaphore_t sem = dispatch_semaphore_create(0); + + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:TimeOut]; + [request setHTTPMethod:@"HEAD"]; + [[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *, NSURLResponse *response, NSError *error){ + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; + if (httpResponse.statusCode >= 200){ + if (httpResponse.expectedContentLength != NSURLResponseUnknownLength) + Res.Size = httpResponse.expectedContentLength; + NSString *dateModified = httpResponse.allHeaderFields[@"Date"]; + if (dateModified){ + NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; + [formatter setLocale:[NSLocale localeWithLocaleIdentifier:@"en"]]; + [formatter setDateFormat:@"EEEE, dd LLL yyyy HH:mm:ss zzz"]; + NSDate *date = [formatter dateFromString:dateModified]; + this->FailTime = [date timeIntervalSince1970]; + [formatter release]; + } + success = YES; + } else { + success = NO; + } + dispatch_semaphore_signal(sem); + }] resume]; + + Status(_("Connecting to %s"), Get.Host.c_str()); + dispatch_semaphore_wait(sem, dispatch_time(DISPATCH_TIME_NOW, TimeOut * NSEC_PER_SEC)); + + // Get the files information + if (!success) + { + return false; + } + + // See if it is an IMS hit + if (Itm->LastModified == FailTime) { + Res.Size = 0; + Res.IMSHit = true; + URIDone(Res); + return true; + } + + // See if the file exists + struct stat Buf; + if (stat(Itm->DestFile.c_str(),&Buf) == 0) { + if (Res.Size == (unsigned long long)Buf.st_size && FailTime == Buf.st_mtime) { + Res.Size = Buf.st_size; + Res.LastModified = Buf.st_mtime; + Res.ResumePoint = Buf.st_size; + URIDone(Res); + return true; + } + + // Resume? + if (FailTime == Buf.st_mtime && Res.Size > (unsigned long long)Buf.st_size) + Res.ResumePoint = Buf.st_size; + } + + // Open the file + Hashes Hash(Itm->ExpectedHashes); + { + [request setHTTPMethod:@"GET"]; + + success = NO; + + NSURLSessionDownloadTask *task = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error){ + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; + if (httpResponse.statusCode == 200 && !error){ + NSString *destFile = [NSString stringWithUTF8String:Itm->DestFile.c_str()]; + [[NSFileManager defaultManager] removeItemAtPath:destFile error:nil]; + success = [[NSFileManager defaultManager] moveItemAtPath:location.path toPath:destFile error:&error]; + if (error){ + success = NO; + } + } + dispatch_semaphore_signal(sem); + }]; + [task resume]; + dispatch_semaphore_wait(sem, dispatch_time(DISPATCH_TIME_NOW, TimeOut * NSEC_PER_SEC)); + + if (!success){ + Fail(true); + return true; + } + + FileFd Fd(Itm->DestFile,FileFd::WriteExists); + Hash.AddFD(Fd,Hashes::UntilEOF); + + URIStart(Res); + + Res.Size = Fd.Size(); + struct timeval times[2]; + times[0].tv_sec = FailTime; + times[1].tv_sec = FailTime; + times[0].tv_usec = times[1].tv_usec = 0; + utimes(Fd.Name().c_str(), times); + } + + Res.LastModified = FailTime; + Res.TakeHashes(Hash); + + URIDone(Res); + + return true; +} + /*}}}*/ + +int main(int, const char *argv[]) +{ + return HttpMethod(flNotDir(argv[0])).Run(); +} -- cgit v1.2.3