File: TestWebServer.h

package info (click to toggle)
gnustep-base 1.31.1-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 26,580 kB
  • sloc: objc: 239,446; ansic: 36,519; cpp: 122; sh: 112; makefile: 100; xml: 32
file content (274 lines) | stat: -rw-r--r-- 9,417 bytes parent folder | download | duplicates (2)
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274

/** -*- objc -*-
 *
 *  Author: Sergei Golovin <svgdev@mail.ru>
 *
 *  TestWebServer is intended to be used in the tests where a web service is
 *  needed. The class's instance is instantiated with the method
 *  -[initWithAddress:port:mode:extra] and then started with the call -[start:].
 *  When started the TestWebServer starts in it's turn a SimpleWebServer instance
 *  in the same thread unless it is initialized with the argument 'mode' set to
 *  'YES' to run it in a detached thread.
 *
 *  It is designed to call the delegate's callbacks (if implemented) of
 *  the TestWebServerDelegate protocol for every request made to
 *  the SimpleWebServer's assigned address on the SimpleWebServer's assigned port
 *  (by default localhost and 1234 respectively). However it currently doesn't
 *  handle any request on it's own. Instead the class uses a collection of
 *  handlers. Every handler makes a custom response. So the TestWebServer only
 *  has to dispatch a request to a corresponding handler and then to send back
 *  the handler's response to the SimpleWebServer instance. See RequestHandler
 *  for more information.
 *
 *  TestWebServer can be supplied with additional parameters via the argument
 *  'extra' of the initializer -[initWithAddress:port:mode:extra].
 *  See that method's description for the currently supported key-value pairs.
 *
 *  The pattern of use:
 *  ----------------------------------------------------------------------------
 *  NSDictionary *extra = [NSDictionary dictionaryWithObjectsAndKeys:
 *                                      @"https", @"Protocol",
 *                                      nil];
 *  TestWebServer *server = [[TestWebServer alloc] initWithAddress: @"localhost"
 *                                                            port: @"1234"
 *                                                            mode: NO
 *                                                           extra: extra];
 *  ADelegateClass *del = [ADelegateClass new];
 *  [server setDelegate: del];
 *  [server start: extra];
 *  ....
 *  <runloop>
 *  ....
 *  [server stop];
 *  DESTROY(server);
 *  DESTROY(del);
 *  ----------------------------------------------------------------------------
 *
 *
 *  The TestWebServer can response to the following resource paths:
 *
 *      /index
 *            displays the page with all supported resources
 *      /withoutauth/
 *            if it is a part of the request's URL then the TestWebServer
 *            will NOT check authentication/authorization of the client.
 *
 *      /204/
 *      /301/
 *      /400/
 *      /401/
 *      /402/
 *      /404/
 *      /405/
 *      /409/
 *      /500/
 *      /505/
 *      /507/
 *            a try to access to this resources will lead the TestWebServer
 *            to produce one of the pre-defined responses with the status code
 *            is equal to the corresponding number.
 *            The pre-defined responses are:
 *              204 "" (empty string)
 *              301 "Redirect to <URL>"
 *                  Returns in the header 'Location' a new <URL> which by default
 *                  has the same protocol, address but the port is incremented by
 *                  1 (e.g. http://localhost:1235/ with other parameters set to
 *                  their default values).
 *              400 "You have issued a request with invalid data"
 *              401 "Invalid login or password"
 *              403 "Check your balance"
 *              404 "The resource you are trying to access is not found"
 *              405 "You can't do that"
 *              409 "The resource you are trying to access is busy"
 *              500 "System error"
 *              505 "There is network protocol inconsistency"
 *              507 "Insufficient storage"
 *
 *  If you want more verbosity call the method -[setDebug: YES].
 *
 */ 

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

@class RequestHandler;

@interface TestWebServer : NSObject <SimpleWebServerDelegate>
{
  /* the debug mode flag */
  BOOL _debug;
  /* the IP address to attach to... see DEFAULTADDRESS at the beginning
   * of the implementaion */
  NSString *_address;
  /* the port to listen on... see DEFAULTPORT in the beginning
   * of the implementaion */
  NSString *_port;
  /* whether the TestWebServer listens for HTTPS requests */
  BOOL _isSecure;
  /* the login for basic authentication */
  NSString *_login;
  /* the password for basic authentication */
  NSString *_password;
  /* holds the extra argument which is for a future use...
   * Currently it is expected to be a dictionary with predetermined 
   * keys ( see the description of -[initWithAddress:port:mode:extra:]) */
  id _extra;
  /* the flag used as a trigger to stop the detached thread */
  BOOL _threadToQuit;
  /* holds the SimpleWebServer accepting incoming connections */
  SimpleWebServer *_server;
  /* holds the detached thread the SimpleWebServer is running on...
   * nil if it runs in the same thread as the calling code */
  NSThread *_serverThread;
  /* the delegate ... NOT RETAINED...
   * see below the protocol TestWebServerDelegate */
  id _delegate;
  /* the lock used for synchronization between threads mainly
   * to wait for the SimpleWebServer is started/stopped...
   * the condition list:
   *     READY   - the initial condition
   *     STARTED - the SimpleWebServer has been started;
   *     STOPPED - the SimpleWebServer has been stopped;
   */
  NSConditionLock *_lock;
  /* the traversal map used to pick a right handler from the request's path */
  NSMutableDictionary *_traversalMap;
}

/**
 *  Initializes the intance with default parameters.
 */
- (id)init;

/**
 *  Initializes an instance with it's SimpleWebServer accepting connection on
 *  the specified address and port. The mode decides whether to run
 *  the SimpleWebServer on the detached thread (NO means it won't be detached).
 *  The argument extra is for future enhancement and could be of the class
 *  NSDictionary whose key-value pairs set various parameters.
 *  The current code supports the following extra keys:
 *     'Login'        - the login for basic authentication
 *     'Password'     - the password for basic authentication
 *     'Protocol'     - 'http' means waiting for HTTP requests
 *                      'https' - for HTTPS requests
 */
- (id)initWithAddress:(NSString *)address
                 port:(NSString *)port
                 mode:(BOOL)detached
                extra:(id)extra;
- (void)dealloc;

/**
 *  Starts the SimpleWebServer accepting incoming connections.
 *  The supplied argument is for future enhancement and currently has no meaning.
 *  It isn't retained by the method.
 */
- (void)start:(id)extra;

/**
 *  Stops the SimpleWebServer. The instance ceases to accept incoming connections.
 */
- (void)stop;

/* SimpleWebServerDelegate */
/**
 *  The main job of request-response cycle is done here. The method is called
 *  when all request's bytes are read. It must be supplied with the incoming
 *  request and the response document which is about to be sent back to the web
 *  client. The handling code within the method would change the supplied response.
 */
- (BOOL) processRequest:(GSMimeDocument *)request
               response:(GSMimeDocument *)response
		    for:(SimpleWebServer *)server;
/* end of SimpleWebServerDelegate */

/* getters */

/**
 *  Returns the address which SimpleWebServer is bound to.
 */
- (NSString *)address;

/**
 *  Returns the port which the SimpleWebServer listens on.
 */
- (NSString *)port;

/**
 *  Returns the login for basic authentication.
 */
- (NSString *)login;

/**
 *  Returns the password for basic authentication.
 */
- (NSString *)password;

/**
 *  Returns YES if the instance waits for HTTPS requests.
 */
- (BOOL)isSecure;

/* end of getters */

/* setters */

/**
 *  Sets the delegate implementing TestWebServerDelegate protocol.
 *  The argument isn't retained by the method.
 */
- (void)setDelegate:(id)delegate;

/**
 *  Sets the debug mode (more verbose).
 */
- (void)setDebug:(BOOL)mode;

/* end of setters */

@end /* TestWebServer */

/**
 *  The protocol's methods are called during processing of a request.
 */
@protocol TestWebServerDelegate

/**
 *  Called by the handler when it has got the supplied request
 *  from the supplied TestWebServer instance.
 */
- (void)handler:(id)handler
     gotRequest:(GSMimeDocument *)request
	   with:(TestWebServer *)server;

/**
 *  Called by the handler when it is going to send the response
 *  on an unauthorized request (an invalid request or no credentials are supplied)
 *  via the supplied TestWebServer.
 */
- (void)handler:(id)handler
willSendUnauthorized:(GSMimeDocument *)response
	   with:(TestWebServer *)server;

/**
 *  Called by the handler when it has got the supplied request
 *  with valid credentials from the supplied TestWebServer instance.
 */
- (void)handler:(id)handler
  gotAuthorized:(GSMimeDocument *)request
	   with:(TestWebServer *)server;

/**
 *  Called by the handler when it is going to send the response
 *  on any request except an unauthorized one via the supplied TestWebServer.
 */
- (void)handler:(id)handler
       willSend:(GSMimeDocument *)response
	   with:(TestWebServer *)server;

/**
 *  Called when the timeout is exceeded.
 */
- (void)timeoutExceededByHandler:(id)handler;

@end /* TestWebServerDelegate */