NSURLClient.mm 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #include "NSURLClient.h"
  2. #ifdef HTTPS_BACKEND_NSURL
  3. #import <Foundation/Foundation.h>
  4. #if ! __has_feature(objc_arc)
  5. #error "ARC is off"
  6. #endif
  7. bool NSURLClient::valid() const
  8. {
  9. return true;
  10. }
  11. static std::string toCppString(NSData *data)
  12. {
  13. return std::string((const char*) data.bytes, (size_t) data.length);
  14. }
  15. static std::string toCppString(NSString *str)
  16. {
  17. return std::string([str UTF8String]);
  18. }
  19. HTTPSClient::Reply NSURLClient::request(const HTTPSClient::Request &req)
  20. { @autoreleasepool {
  21. NSURL *url = [NSURL URLWithString:@(req.url.c_str())];
  22. NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
  23. NSData *bodydata = nil;
  24. switch(req.method)
  25. {
  26. case Request::GET:
  27. [request setHTTPMethod:@"GET"];
  28. break;
  29. case Request::POST:
  30. bodydata = [NSData dataWithBytesNoCopy:(void*) req.postdata.data() length:req.postdata.size() freeWhenDone:NO];
  31. [request setHTTPMethod:@"POST"];
  32. [request setHTTPBody:bodydata];
  33. break;
  34. }
  35. for (auto &header : req.headers)
  36. [request setValue:@(header.second.c_str()) forHTTPHeaderField:@(header.first.c_str())];
  37. __block NSHTTPURLResponse *response = nil;
  38. __block NSError *error = nil;
  39. __block NSData *body = nil;
  40. dispatch_semaphore_t sem = dispatch_semaphore_create(0);
  41. NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request
  42. completionHandler:^(NSData *data, NSURLResponse *resp, NSError *err) {
  43. body = data;
  44. response = (NSHTTPURLResponse *)resp;
  45. error = err;
  46. dispatch_semaphore_signal(sem);
  47. }];
  48. [task resume];
  49. dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
  50. HTTPSClient::Reply reply;
  51. reply.responseCode = 400;
  52. if (body)
  53. {
  54. reply.body = toCppString(body);
  55. }
  56. if (response)
  57. {
  58. reply.responseCode = [response statusCode];
  59. NSDictionary *headers = [response allHeaderFields];
  60. for (NSString *key in headers)
  61. {
  62. NSString *value = headers[key];
  63. reply.headers[toCppString(key)] = toCppString(value);
  64. }
  65. }
  66. return reply;
  67. }}
  68. #endif // HTTPS_BACKEND_NSURL