aboutsummaryrefslogtreecommitdiff
path: root/Foundation/GTMHTTPServer.h
blob: 3920968f167efc2e7c2f804747c5e01d5819cb0d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
//
//  GTMHTTPServer.h
//
//  This is a *very* *simple* webserver that can be built into something, it is
//  not meant to stand up a site, it sends all requests to its delegate for
//  processing on the main thread.  It does not support pipelining, etc.  It's
//  great for places where you need a simple webserver to unittest some code
//  that hits a server.
//
//  NOTE: there are several TODOs left in here as markers for things that could
//  be done if one wanted to add more to this class.
//
//  Copyright 2008 Google Inc.
//
//  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.
//
//  Based a little on HTTPServer, part of the CocoaHTTPServer sample code
//  http://developer.apple.com/samplecode/CocoaHTTPServer/index.html
//

#import <Foundation/Foundation.h>
#import "GTMDefines.h"

#if GTM_IPHONE_SDK
#import <CFNetwork/CFNetwork.h>
#endif // GTM_IPHONE_SDK

// Global contants needed for errors from start

#undef _EXTERN
#undef _INITIALIZE_AS
#ifdef GTMHTTPSERVER_DEFINE_GLOBALS
#define _EXTERN 
#define _INITIALIZE_AS(x) =x
#else
#define _EXTERN GTM_EXTERN
#define _INITIALIZE_AS(x)
#endif

_EXTERN NSString* kGTMHTTPServerErrorDomain _INITIALIZE_AS(@"com.google.mactoolbox.HTTPServerDomain");
enum {
  kGTMHTTPServerSocketCreateFailedError = -100,
  kGTMHTTPServerBindFailedError         = -101,
  kGTMHTTPServerListenFailedError       = -102,
  kGTMHTTPServerHandleCreateFailedError = -103,
};

@class GTMHTTPRequestMessage, GTMHTTPResponseMessage;

// ----------------------------------------------------------------------------

// See comment at top of file for the intened use of this class.
@interface GTMHTTPServer : NSObject {
 @private
  __weak id delegate_;
  uint16_t port_;
  BOOL reusePort_;
  BOOL localhostOnly_;
  NSFileHandle *listenHandle_;
  NSMutableArray *connections_;
}

// The delegate must support the httpServer:handleRequest: method in
// NSObject(GTMHTTPServerDelegateMethods) below.
- (id)initWithDelegate:(id)delegate;

- (id)delegate;

// Passing port zero will let one get assigned.
- (uint16_t)port;
- (void)setPort:(uint16_t)port;

// Controls listening socket behavior: SO_REUSEADDR vs SO_REUSEPORT.
// The default is NO (SO_REUSEADDR)
- (BOOL)reusePort;
- (void)setReusePort:(BOOL)reusePort;

// Receive connections on the localHost loopback address only or on all
// interfaces for this machine.  The default is to only listen on localhost.
- (BOOL)localhostOnly;
- (void)setLocalhostOnly:(BOOL)yesno;

// Start/Stop the web server.  If there is an error starting up the server, |NO|
// is returned, and the specific startup failure can be returned in |error| (see
// above for the error domain and error codes).  If the server is started, |YES|
// is returned and the server's delegate is called for any requests that come
// in.
- (BOOL)start:(NSError **)error;
- (void)stop;

// returns the number of requests currently active in the server (i.e.-being
// read in, sent replies).
- (NSUInteger)activeRequestCount;

@end

@interface NSObject (GTMHTTPServerDelegateMethods)
- (GTMHTTPResponseMessage *)httpServer:(GTMHTTPServer *)server
                         handleRequest:(GTMHTTPRequestMessage *)request;
@end

// ----------------------------------------------------------------------------

// Encapsulates an http request, one of these is sent to the server's delegate
// for each request.
@interface GTMHTTPRequestMessage : NSObject {
 @private
  CFHTTPMessageRef message_;
}
- (NSString *)version;
- (NSURL *)URL;
- (NSString *)method;
- (NSData *)body;
- (NSDictionary *)allHeaderFieldValues;
@end

// ----------------------------------------------------------------------------

// Encapsulates an http response, the server's delegate should return one for
// each request received.
@interface GTMHTTPResponseMessage : NSObject {
 @private
  CFHTTPMessageRef message_;
}
+ (id)responseWithString:(NSString *)plainText;
+ (id)responseWithHTMLString:(NSString *)htmlString;
+ (id)responseWithBody:(NSData *)body
           contentType:(NSString *)contentType
            statusCode:(int)statusCode;
+ (id)emptyResponseWithCode:(int)statusCode;
// TODO: class method for redirections?
// TODO: add helper for expire/no-cache
- (void)setValue:(NSString*)value forHeaderField:(NSString*)headerField;
@end