blob: 6391bead8c01e17c222369506f01d16cd58fe97a [file] [log] [blame]
Gavin McDonald0b75e1a2010-10-28 02:12:01 +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
20#import "THTTPClient.h"
21#import "TTransportException.h"
22
23@implementation THTTPClient
24
25
26- (void) setupRequest
27{
28 if (mRequest != nil) {
29 [mRequest release];
30 }
31
32 // 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"];
37
38 NSString * userAgent = mUserAgent;
39 if (!userAgent) {
40 userAgent = @"Cocoa/THTTPClient";
41 }
42 [mRequest setValue: userAgent forHTTPHeaderField: @"User-Agent"];
43
44 [mRequest setCachePolicy: NSURLRequestReloadIgnoringCacheData];
45 if (mTimeout) {
46 [mRequest setTimeoutInterval: mTimeout];
47 }
48}
49
50
51- (id) initWithURL: (NSURL *) aURL
52{
53 return [self initWithURL: aURL
54 userAgent: nil
55 timeout: 0];
56}
57
58
59- (id) initWithURL: (NSURL *) aURL
60 userAgent: (NSString *) userAgent
61 timeout: (int) timeout
62{
63 self = [super init];
64 if (!self) {
65 return nil;
66 }
67
68 mTimeout = timeout;
69 if (userAgent) {
70 mUserAgent = [userAgent retain];
71 }
72 mURL = [aURL retain];
73
74 [self setupRequest];
75
76 // create our request data buffer
77 mRequestData = [[NSMutableData alloc] initWithCapacity: 1024];
78
79 return self;
80}
81
82
83- (void) setURL: (NSURL *) aURL
84{
85 [aURL retain];
86 [mURL release];
87 mURL = aURL;
88
89 [self setupRequest];
90}
91
92
93- (void) dealloc
94{
95 [mURL release];
96 [mUserAgent release];
97 [mRequest release];
98 [mRequestData release];
99 [mResponseData release];
100 [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;
130 NSData * responseData =
131 [NSURLConnection sendSynchronousRequest: mRequest returningResponse: &response error: &error];
132
133 [mRequestData setLength: 0];
134
135 if (responseData == nil) {
136 @throw [TTransportException exceptionWithName: @"TTransportException"
137 reason: @"Could not make HTTP request"
138 error: error];
139 }
140 if (![response isKindOfClass: [NSHTTPURLResponse class]]) {
141 @throw [TTransportException exceptionWithName: @"TTransportException"
142 reason: @"Unexpected NSURLResponse type"];
143 }
144
145 NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse *) response;
146 if ([httpResponse statusCode] != 200) {
147 @throw [TTransportException exceptionWithName: @"TTransportException"
148 reason: [NSString stringWithFormat: @"Bad response from HTTP server: %d",
149 [httpResponse statusCode]]];
150 }
151
152 // phew!
153 [mResponseData release];
154 mResponseData = [responseData retain];
155 mResponseDataOffset = 0;
156}
157
158
159@end