Index: util/net/http_transport_mac.mm |
diff --git a/util/net/http_transport_mac.mm b/util/net/http_transport_mac.mm |
new file mode 100644 |
index 0000000000000000000000000000000000000000..44a93d0ae41719a4ba5445f20f56811f4195cf85 |
--- /dev/null |
+++ b/util/net/http_transport_mac.mm |
@@ -0,0 +1,161 @@ |
+// Copyright 2014 The Crashpad Authors. All rights reserved. |
+// |
+// Licensed under the Apache License, Version 2.0 (the "License"); |
+// you may not use this file except in compliance with the License. |
+// You may obtain a copy of the License at |
+// |
+// http://www.apache.org/licenses/LICENSE-2.0 |
+// |
+// Unless required by applicable law or agreed to in writing, software |
+// distributed under the License is distributed on an "AS IS" BASIS, |
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+// See the License for the specific language governing permissions and |
+// limitations under the License. |
+ |
+#include "util/net/http_transport_mac.h" |
+ |
+#import <Foundation/Foundation.h> |
+ |
+#include "base/mac/foundation_util.h" |
+#import "base/mac/scoped_nsobject.h" |
+#include "base/strings/stringprintf.h" |
+#include "base/strings/sys_string_conversions.h" |
+#include "util/net/http_body.h" |
+ |
+@interface CrashpadHTTPBodyStreamTransport : NSInputStream { |
+ @private |
+ NSStreamStatus streamStatus_; |
+ id<NSStreamDelegate> delegate_; |
+ crashpad::HTTPBodyStream* bodyStream_; |
Mark Mentovai
2014/10/30 21:13:54
// weak
Robert Sesek
2014/10/31 14:48:14
Done.
|
+} |
+- (instancetype)initWithBodyStream:(crashpad::HTTPBodyStream*)bodyStream; |
+@end |
+ |
+@implementation CrashpadHTTPBodyStreamTransport |
+ |
+- (instancetype)initWithBodyStream:(crashpad::HTTPBodyStream*)bodyStream { |
+ if ((self = [super init])) { |
+ streamStatus_ = NSStreamStatusNotOpen; |
+ bodyStream_ = bodyStream; |
+ } |
+ return self; |
+} |
+ |
+// NSInputStream: |
+ |
+- (BOOL)hasBytesAvailable { |
+ // Per Apple's documentation: "May also return YES if a read must be attempted |
+ // in order to determine the availability of bytes." |
+ return YES; |
Mark Mentovai
2014/10/30 21:13:54
I guess you could return NO if streamStatus_ is NS
Robert Sesek
2014/10/31 14:48:15
Done.
|
+} |
+ |
+- (NSInteger)read:(uint8_t*)buffer maxLength:(NSUInteger)maxLen { |
+ NSInteger rv = bodyStream_->GetBytesBuffer(buffer, maxLen); |
+ if (rv == 0) |
+ streamStatus_ = NSStreamStatusAtEnd; |
+ else if (rv < 0) |
+ streamStatus_ = NSStreamStatusError; |
+ else |
+ streamStatus_ = NSStreamStatusReading; |
Mark Mentovai
2014/10/30 21:13:54
The documentation for this status says that it’s s
Robert Sesek
2014/10/31 14:48:15
Done.
|
+ return rv; |
+} |
+ |
+- (BOOL)getBuffer:(uint8_t**)buffer length:(NSUInteger*)length { |
+ return NO; |
+} |
+ |
+// NSStream: |
+ |
+- (void)scheduleInRunLoop:(NSRunLoop*)runLoop |
Mark Mentovai
2014/10/30 21:13:55
Can you add a comment about why this is unnecessar
Robert Sesek
2014/10/31 14:48:14
I would if I knew why it were necessary ;). I don'
|
+ forMode:(NSString*)mode { |
+} |
+ |
+- (void)removeFromRunLoop:(NSRunLoop*)runLoop |
+ forMode:(NSString*)mode { |
+} |
+ |
+- (void)open { |
+ streamStatus_ = NSStreamStatusOpen; |
+} |
+ |
+- (void)close { |
+ streamStatus_ = NSStreamStatusClosed; |
+} |
+ |
+- (NSStreamStatus)streamStatus { |
+ return streamStatus_; |
+} |
+ |
+- (id<NSStreamDelegate>)delegate { |
+ return delegate_; |
+} |
+ |
+- (void)setDelegate:(id)delegate { |
+ delegate_ = delegate; |
+} |
+ |
+@end |
+ |
+namespace crashpad { |
+ |
+HTTPTransportMac::HTTPTransportMac() : HTTPTransport() { |
+} |
+ |
+HTTPTransportMac::~HTTPTransportMac() { |
+} |
+ |
+bool HTTPTransportMac::ExecuteSynchronously() { |
+ DCHECK(body_stream()); |
+ |
+ @autoreleasepool { |
+ NSString* urlNSString = base::SysUTF8ToNSString(url()); |
Mark Mentovai
2014/10/30 21:13:54
You’re not in the @implementation anymore here: ur
Robert Sesek
2014/10/31 14:48:14
Done.
|
+ NSURL* url = [NSURL URLWithString:urlNSString]; |
+ NSMutableURLRequest* request = |
+ [NSMutableURLRequest requestWithURL:url |
+ cachePolicy:NSURLRequestUseProtocolCachePolicy |
+ timeoutInterval:15.0]; |
Mark Mentovai
2014/10/30 21:13:55
It’d be reasonable for this to be tunable at the H
Robert Sesek
2014/10/31 14:48:14
Done.
|
+ [request setHTTPMethod:base::SysUTF8ToNSString(method())]; |
+ |
+ for (const auto& pair : headers()) { |
+ [request setValue:base::SysUTF8ToNSString(pair.second) |
+ forHTTPHeaderField:base::SysUTF8ToNSString(pair.first)]; |
+ } |
+ |
+ base::scoped_nsobject<CrashpadHTTPBodyStreamTransport> transport( |
+ [[CrashpadHTTPBodyStreamTransport alloc] initWithBodyStream: |
+ body_stream()]); |
+ [request setHTTPBodyStream:transport.get()]; |
+ |
+ NSURLResponse* response = nil; |
+ NSError* error = nil; |
+ [NSURLConnection sendSynchronousRequest:request |
+ returningResponse:&response |
+ error:&error]; |
+ |
+ if (error) { |
+ LOG(ERROR) << [[error localizedDescription] UTF8String] << " (" |
+ << [[error domain] UTF8String] << " " << [error code] << ")"; |
+ return false; |
+ } |
+ if (!response) { |
+ LOG(ERROR) << "no response"; |
+ return false; |
+ } |
+ NSHTTPURLResponse* httpResponse = |
+ base::mac::ObjCCast<NSHTTPURLResponse>(response); |
+ if (!httpResponse) { |
+ LOG(ERROR) << "no httpResponse"; |
+ return false; |
+ } |
+ NSInteger httpStatus = [httpResponse statusCode]; |
+ if (httpStatus != 200) { |
+ LOG(ERROR) << base::StringPrintf("HTTP status %ld", |
+ static_cast<long>(httpStatus)); |
+ return false; |
+ } |
+ |
+ return true; |
+ } |
+} |
+ |
+} // namespace crashpad |