OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [libnetworking/] [rtems_webserver/] [handler.c] - Blame information for rev 173

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*
2
 * handler.c -- URL handler support
3
 *
4
 * Copyright (c) Go Ahead Software Inc., 1995-1999. All Rights Reserved.
5
 *
6
 * See the file "license.txt" for usage and redistribution license requirements
7
 */
8
 
9
/******************************** Description *********************************/
10
 
11
/*
12
 *      This module implements a URL handler interface and API to permit
13
 *      the addition of user definable URL processors.
14
 */
15
 
16
/********************************* Includes ***********************************/
17
 
18
#include        "wsIntrn.h"
19
 
20
/*********************************** Locals ***********************************/
21
 
22
static websUrlHandlerType*      websUrlHandler;                         /* URL handler list */
23
static int                                      websUrlHandlerMax;                      /* Number of entries */
24
 
25
/**************************** Forward Declarations ****************************/
26
 
27
static int      websUrlHandlerSort(const void* p1, const void* p2);
28
static int      websPublishHandler(webs_t wp, char_t *urlPrefix, char_t *webDir,
29
                                int sid, char_t *url, char_t *path, char_t *query);
30
 
31
/*********************************** Code *************************************/
32
/*
33
 *      Initialize the URL handler module
34
 */
35
 
36
int websUrlHandlerOpen()
37
{
38
        websAspOpen();
39
        return 0;
40
}
41
 
42
/******************************************************************************/
43
/*
44
 *      Close the URL handler module
45
 */
46
 
47
void websUrlHandlerClose()
48
{
49
        websUrlHandlerType*     sp;
50
 
51
        websAspClose();
52
        for (sp = websUrlHandler; sp < &websUrlHandler[websUrlHandlerMax]; sp++) {
53
                bfree(B_L, sp->urlPrefix);
54
                if (sp->webDir) {
55
                        bfree(B_L, sp->webDir);
56
                }
57
        }
58
        bfree(B_L, websUrlHandler);
59
        websUrlHandlerMax = 0;
60
}
61
 
62
/******************************************************************************/
63
/*
64
 *      Define a new URL handler. urlPrefix is the URL prefix to match. webDir is
65
 *      an optional root directory path for a web directory. arg is an optional
66
 *      arg to pass to the URL handler. flags defines the matching order. Valid
67
 *      flags include WEBS_HANDLER_LAST, WEBS_HANDLER_FIRST. If multiple users
68
 *      specify last or first, their order is defined alphabetically by the
69
 *      urlPrefix.
70
 */
71
 
72
int websUrlHandlerDefine(char_t *urlPrefix, char_t *webDir, int arg,
73
                int (*handler)(webs_t wp, char_t *urlPrefix, char_t *webdir, int arg,
74
                char_t *url, char_t *path, char_t *query), int flags)
75
{
76
        websUrlHandlerType      *sp;
77
        int                                     len;
78
 
79
        a_assert(urlPrefix);
80
        a_assert(handler);
81
 
82
/*
83
 *      Grow the URL handler array to create a new slot
84
 */
85
        len = (websUrlHandlerMax + 1) * sizeof(websUrlHandlerType);
86
        if ((websUrlHandler = brealloc(B_L, websUrlHandler, len)) == NULL) {
87
                return -1;
88
        }
89
        sp = &websUrlHandler[websUrlHandlerMax++];
90
        memset(sp, 0, sizeof(websUrlHandlerType));
91
 
92
        sp->urlPrefix = bstrdup(B_L, urlPrefix);
93
        sp->len = gstrlen(sp->urlPrefix);
94
        if (webDir) {
95
                sp->webDir = bstrdup(B_L, webDir);
96
        } else {
97
                sp->webDir = bstrdup(B_L, T(""));
98
        }
99
        sp->handler = handler;
100
        sp->arg = arg;
101
        sp->flags = flags;
102
 
103
/*
104
 *      Sort in decreasing URL length order observing the flags for first and last
105
 */
106
        qsort(websUrlHandler, websUrlHandlerMax, sizeof(websUrlHandlerType),
107
                websUrlHandlerSort);
108
        return 0;
109
}
110
 
111
/******************************************************************************/
112
/*
113
 *      Delete an existing URL handler. We don't reclaim the space of the old
114
 *      handler, just NULL the entry. Return -1 if handler is not found.
115
 */
116
 
117
int websUrlHandlerDelete(int (*handler)(webs_t wp, char_t *urlPrefix,
118
        char_t *webDir, int arg, char_t *url, char_t *path, char_t *query))
119
{
120
        websUrlHandlerType      *sp;
121
        int                                     i;
122
 
123
        for (i = 0; i < websUrlHandlerMax; i++) {
124
                sp = &websUrlHandler[i];
125
                if (sp->handler == handler) {
126
                        sp->handler = NULL;
127
                        return 0;
128
                }
129
        }
130
        return -1;
131
}
132
 
133
/******************************************************************************/
134
/*
135
 *      Sort in decreasing URL length order observing the flags for first and last
136
 */
137
 
138
static int websUrlHandlerSort(const void* p1, const void* p2)
139
{
140
        websUrlHandlerType      *s1, *s2;
141
        int                                     rc;
142
 
143
        a_assert(p1);
144
        a_assert(p2);
145
 
146
        s1 = (websUrlHandlerType*) p1;
147
        s2 = (websUrlHandlerType*) p2;
148
 
149
        if ((s1->flags & WEBS_HANDLER_FIRST) || (s2->flags & WEBS_HANDLER_LAST)) {
150
                return -1;
151
        }
152
 
153
        if ((s2->flags & WEBS_HANDLER_FIRST) || (s1->flags & WEBS_HANDLER_LAST)) {
154
                return 1;
155
        }
156
 
157
        if ((rc = gstrcmp(s1->urlPrefix, s2->urlPrefix)) == 0) {
158
                if (s1->len < s2->len) {
159
                        return 1;
160
                } else if (s1->len > s2->len) {
161
                        return -1;
162
                }
163
        }
164
        return -rc;
165
}
166
 
167
/******************************************************************************/
168
/*
169
 *      Publish a new web directory (Use the default URL handler)
170
 */
171
 
172
int websPublish(char_t *urlPrefix, char_t *path)
173
{
174
        return websUrlHandlerDefine(urlPrefix, path, 0, websPublishHandler, 0);
175
}
176
 
177
/******************************************************************************/
178
/*
179
 *      Return the directory for a given prefix. Ignore empty prefixes
180
 */
181
 
182
char_t *websGetPublishDir(char_t *path, char_t **urlPrefix)
183
{
184
        websUrlHandlerType      *sp;
185
        int                                     i;
186
 
187
        for (i = 0; i < websUrlHandlerMax; i++) {
188
                sp = &websUrlHandler[i];
189
                if (sp->urlPrefix[0] == '\0') {
190
                        continue;
191
                }
192
                if (sp->handler && gstrncmp(sp->urlPrefix, path, sp->len) == 0) {
193
                        if (urlPrefix) {
194
                                *urlPrefix = sp->urlPrefix;
195
                        }
196
                        return sp->webDir;
197
                }
198
        }
199
        return NULL;
200
}
201
 
202
/******************************************************************************/
203
/*
204
 *      Publish URL handler. We just patch the web page Directory and let the
205
 *      default handler do the rest.
206
 */
207
 
208
static int websPublishHandler(webs_t wp, char_t *urlPrefix, char_t *webDir,
209
        int sid, char_t *url, char_t *path, char_t *query)
210
{
211
        int             len;
212
 
213
        a_assert(websValid(wp));
214
        a_assert(path);
215
 
216
/*
217
 *      Trim the urlPrefix off the path and set the webdirectory. Add one to step
218
 *      over the trailing '/'
219
 */
220
        len = gstrlen(urlPrefix) + 1;
221
        websSetRequestPath(wp, webDir, &path[len]);
222
        return 0;
223
}
224
 
225
/******************************************************************************/
226
/*
227
 *      See if any valid handlers are defined for this request. If so, call them
228
 *      and continue calling valid handlers until one accepts the request.
229
 *      Return true if a handler was invoked, else return FALSE.
230
 */
231
 
232
int websUrlHandlerRequest(webs_t wp)
233
{
234
        websUrlHandlerType      *sp;
235
        int                                     i, first;
236
 
237
        a_assert(websValid(wp));
238
 
239
/*
240
 *      Delete the socket handler as we don't want to start reading any
241
 *      data on the connection as it may be for the next pipelined HTTP/1.1
242
 *      request if using Keep Alive
243
 */
244
        socketDeleteHandler(wp->sid);
245
        wp->state = WEBS_PROCESSING;
246
        websStats.handlerHits++;
247
 
248
        websSetRequestPath(wp, websGetDefaultDir(), NULL);
249
 
250
/*
251
 *      We loop over each handler in order till one accepts the request.
252
 *      The security handler will handle the request if access is NOT allowed.
253
 */
254
        first = 1;
255
        for (i = 0; i < websUrlHandlerMax; i++) {
256
                sp = &websUrlHandler[i];
257
                if (sp->handler && gstrncmp(sp->urlPrefix, wp->path, sp->len) == 0) {
258
                        if (first) {
259
                                websSetEnv(wp);
260
                                first = 0;
261
                        }
262
                        if ((*sp->handler)(wp, sp->urlPrefix, sp->webDir, sp->arg,
263
                                        wp->url, wp->path, wp->query)) {
264
                                return 1;
265
                        }
266
                        if (!websValid(wp)) {
267
                                goahead_trace(0,
268
                                T("webs: handler %s called websDone, but didn't return 1\n"),
269
                                        sp->urlPrefix);
270
                                return 1;
271
                        }
272
                }
273
        }
274
/*
275
 *      If no handler processed the request, then return an error. Note: It was
276
 *      the handlers responsibility to call websDone
277
 */
278
        if (i >= websUrlHandlerMax) {
279
                websError(wp, 200, T("No handler for this URL %s"), wp->url);
280
        }
281
        return 0;
282
}
283
 
284
/******************************************************************************/

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.