summaryrefslogtreecommitdiff
path: root/methods
diff options
context:
space:
mode:
Diffstat (limited to 'methods')
-rw-r--r--methods/CMakeLists.txt20
-rw-r--r--methods/nshttp.h40
-rw-r--r--methods/nshttp.mm196
3 files changed, 247 insertions, 9 deletions
diff --git a/methods/CMakeLists.txt b/methods/CMakeLists.txt
index c4a32b4f5..14689bbfe 100644
--- a/methods/CMakeLists.txt
+++ b/methods/CMakeLists.txt
@@ -2,32 +2,34 @@
include_directories($<$<BOOL:${SECCOMP_FOUND}>:${SECCOMP_INCLUDE_DIR}>)
link_libraries(apt-pkg $<$<BOOL:${SECCOMP_FOUND}>:${SECCOMP_LIBRARIES}>)
-add_library(connectlib OBJECT connect.cc rfc2553emu.cc)
+#add_library(connectlib OBJECT connect.cc rfc2553emu.cc)
add_executable(file file.cc)
add_executable(copy copy.cc)
add_executable(store store.cc)
add_executable(gpgv gpgv.cc)
add_executable(cdrom cdrom.cc)
-add_executable(http http.cc basehttp.cc $<TARGET_OBJECTS:connectlib>)
+#add_executable(http http.cc basehttp.cc $<TARGET_OBJECTS:connectlib>)
+add_executable(https nshttp.mm)
add_executable(mirror mirror.cc)
-add_executable(ftp ftp.cc $<TARGET_OBJECTS:connectlib>)
+#add_executable(ftp ftp.cc $<TARGET_OBJECTS:connectlib>)
add_executable(rred rred.cc)
add_executable(rsh rsh.cc)
-target_compile_definitions(connectlib PRIVATE ${GNUTLS_DEFINITIONS})
-target_include_directories(connectlib PRIVATE ${GNUTLS_INCLUDE_DIR})
+#target_compile_definitions(connectlib PRIVATE ${GNUTLS_DEFINITIONS})
+#target_include_directories(connectlib PRIVATE ${GNUTLS_INCLUDE_DIR})
# Additional libraries to link against for networked stuff
-target_link_libraries(http ${GNUTLS_LIBRARIES})
-target_link_libraries(ftp ${GNUTLS_LIBRARIES})
+#target_link_libraries(http ${GNUTLS_LIBRARIES})
+target_link_libraries(https "-framework Foundation")
+#target_link_libraries(ftp ${GNUTLS_LIBRARIES})
# Install the library
-install(TARGETS file copy store gpgv cdrom http ftp rred rsh mirror
+install(TARGETS file copy store https gpgv cdrom rred rsh mirror
RUNTIME DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/apt/methods)
add_slaves(${CMAKE_INSTALL_LIBEXECDIR}/apt/methods mirror mirror+ftp mirror+http mirror+https mirror+file mirror+copy)
add_slaves(${CMAKE_INSTALL_LIBEXECDIR}/apt/methods rsh ssh)
-add_slaves(${CMAKE_INSTALL_LIBEXECDIR}/apt/methods http https)
+#add_slaves(${CMAKE_INSTALL_LIBEXECDIR}/apt/methods http https)
diff --git a/methods/nshttp.h b/methods/nshttp.h
new file mode 100644
index 000000000..d0a7c8c31
--- /dev/null
+++ b/methods/nshttp.h
@@ -0,0 +1,40 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+/* ######################################################################
+
+ HTTP method - Transfer files via rsh compatible program
+
+ ##################################################################### */
+ /*}}}*/
+#ifndef APT_NSHTTP_H
+#define APT_NSHTTP_H
+
+#include <string>
+#include <time.h>
+
+#include <apt-pkg/strutl.h>
+#include <Foundation/Foundation.h>
+
+class Hashes;
+class FileFd;
+
+#include "aptmethod.h"
+
+class HttpMethod : public aptMethod
+{
+ virtual bool Fetch(FetchItem *Itm) APT_OVERRIDE;
+ virtual bool Configuration(std::string Message) APT_OVERRIDE;
+
+ NSURLSession *session;
+
+ static std::string FailFile;
+ static int FailFd;
+ static time_t FailTime;
+ static APT_NORETURN void SigTerm(int);
+
+ public:
+
+ explicit HttpMethod(std::string &&Prog);
+};
+
+#endif
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 <bcollins@debian.org>, Copyright (c) 2000
+ Licensed under the GNU General Public License v2 [no exception clauses]
+
+ ##################################################################### */
+ /*}}}*/
+// Include Files /*{{{*/
+#include <config.h>
+
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/hashes.h>
+#include <apt-pkg/strutl.h>
+
+#include "nshttp.h"
+#include <errno.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+#include <apti18n.h>
+
+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();
+}