blob: 6391bead8c01e17c222369506f01d16cd58fe97a [file] [log] [blame]
David Reissea2cba82009-03-30 21:35:00 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
Mark Slee2ac60ed2007-09-19 21:10:18 +000020#import "THTTPClient.h"
21#import "TTransportException.h"
22
23@implementation THTTPClient
24
Mark Slee2ac60ed2007-09-19 21:10:18 +000025
Mark Slee84406052007-11-20 01:39:25 +000026- (void) setupRequest
27{
28 if (mRequest != nil) {
29 [mRequest release];
30 }
David Reiss0c90f6f2008-02-06 22:18:40 +000031
Mark Slee2ac60ed2007-09-19 21:10:18 +000032 // set up our request object that we'll use for each request
33 mRequest = [[NSMutableURLRequest alloc] initWithURL: mURL];
34 [mRequest setHTTPMethod: @"POST"];
35 [mRequest setValue: @"application/x-thrift" forHTTPHeaderField: @"Content-Type"];
36 [mRequest setValue: @"application/x-thrift" forHTTPHeaderField: @"Accept"];
David Reissb0232b32008-01-23 20:35:39 +000037
38 NSString * userAgent = mUserAgent;
39 if (!userAgent) {
40 userAgent = @"Cocoa/THTTPClient";
41 }
42 [mRequest setValue: userAgent forHTTPHeaderField: @"User-Agent"];
43
Mark Slee2ac60ed2007-09-19 21:10:18 +000044 [mRequest setCachePolicy: NSURLRequestReloadIgnoringCacheData];
David Reissb0232b32008-01-23 20:35:39 +000045 if (mTimeout) {
46 [mRequest setTimeoutInterval: mTimeout];
47 }
Mark Slee84406052007-11-20 01:39:25 +000048}
49
50
51- (id) initWithURL: (NSURL *) aURL
52{
David Reissb0232b32008-01-23 20:35:39 +000053 return [self initWithURL: aURL
54 userAgent: nil
55 timeout: 0];
56}
57
58
David Reiss0c90f6f2008-02-06 22:18:40 +000059- (id) initWithURL: (NSURL *) aURL
David Reissb0232b32008-01-23 20:35:39 +000060 userAgent: (NSString *) userAgent
61 timeout: (int) timeout
62{
Mark Slee84406052007-11-20 01:39:25 +000063 self = [super init];
David Reissb0232b32008-01-23 20:35:39 +000064 if (!self) {
65 return nil;
66 }
David Reiss0c90f6f2008-02-06 22:18:40 +000067
David Reissb0232b32008-01-23 20:35:39 +000068 mTimeout = timeout;
69 if (userAgent) {
70 mUserAgent = [userAgent retain];
71 }
Mark Slee84406052007-11-20 01:39:25 +000072 mURL = [aURL retain];
73
74 [self setupRequest];
Mark Slee2ac60ed2007-09-19 21:10:18 +000075
76 // create our request data buffer
77 mRequestData = [[NSMutableData alloc] initWithCapacity: 1024];
David Reiss0c90f6f2008-02-06 22:18:40 +000078
Mark Slee2ac60ed2007-09-19 21:10:18 +000079 return self;
80}
81
82
Mark Slee84406052007-11-20 01:39:25 +000083- (void) setURL: (NSURL *) aURL
84{
85 [aURL retain];
86 [mURL release];
87 mURL = aURL;
David Reiss0c90f6f2008-02-06 22:18:40 +000088
Mark Slee84406052007-11-20 01:39:25 +000089 [self setupRequest];
90}
91
92
Mark Slee2ac60ed2007-09-19 21:10:18 +000093- (void) dealloc
94{
95 [mURL release];
David Reissb0232b32008-01-23 20:35:39 +000096 [mUserAgent release];
Mark Slee2ac60ed2007-09-19 21:10:18 +000097 [mRequest release];
98 [mRequestData release];
Mark Slee77575e62007-09-24 19:24:53 +000099 [mResponseData release];
Mark Slee2ac60ed2007-09-19 21:10:18 +0000100 [super dealloc];
101}
102
103
104- (int) readAll: (uint8_t *) buf offset: (int) off length: (int) len
105{
106 NSRange r;
107 r.location = mResponseDataOffset;
108 r.length = len;
109
110 [mResponseData getBytes: buf+off range: r];
111 mResponseDataOffset += len;
112
113 return len;
114}
115
116
117- (void) write: (const uint8_t *) data offset: (unsigned int) offset length: (unsigned int) length
118{
119 [mRequestData appendBytes: data+offset length: length];
120}
121
122
123- (void) flush
124{
125 [mRequest setHTTPBody: mRequestData]; // not sure if it copies the data
126
127 // make the HTTP request
128 NSURLResponse * response;
129 NSError * error;
David Reiss0c90f6f2008-02-06 22:18:40 +0000130 NSData * responseData =
Mark Slee2ac60ed2007-09-19 21:10:18 +0000131 [NSURLConnection sendSynchronousRequest: mRequest returningResponse: &response error: &error];
132
133 [mRequestData setLength: 0];
134
135 if (responseData == nil) {
Mark Slee77575e62007-09-24 19:24:53 +0000136 @throw [TTransportException exceptionWithName: @"TTransportException"
137 reason: @"Could not make HTTP request"
Mark Slee2ac60ed2007-09-19 21:10:18 +0000138 error: error];
139 }
140 if (![response isKindOfClass: [NSHTTPURLResponse class]]) {
Mark Slee77575e62007-09-24 19:24:53 +0000141 @throw [TTransportException exceptionWithName: @"TTransportException"
142 reason: @"Unexpected NSURLResponse type"];
Mark Slee2ac60ed2007-09-19 21:10:18 +0000143 }
144
145 NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse *) response;
146 if ([httpResponse statusCode] != 200) {
Mark Slee77575e62007-09-24 19:24:53 +0000147 @throw [TTransportException exceptionWithName: @"TTransportException"
David Reiss0c90f6f2008-02-06 22:18:40 +0000148 reason: [NSString stringWithFormat: @"Bad response from HTTP server: %d",
Mark Slee77575e62007-09-24 19:24:53 +0000149 [httpResponse statusCode]]];
Mark Slee2ac60ed2007-09-19 21:10:18 +0000150 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000151
Mark Slee2ac60ed2007-09-19 21:10:18 +0000152 // phew!
153 [mResponseData release];
154 mResponseData = [responseData retain];
155 mResponseDataOffset = 0;
156}
157
158
159@end