2
Copyright (C) 2000-2005 SKYRIX Software AG
4
This file is part of SOPE.
6
SOPE is free software; you can redistribute it and/or modify it under
7
the terms of the GNU Lesser General Public License as published by the
8
Free Software Foundation; either version 2, or (at your option) any
11
SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
12
WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14
License for more details.
16
You should have received a copy of the GNU Lesser General Public
17
License along with SOPE; see the file COPYING. If not, write to the
18
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23
#include "NGBufferedDescriptor.h"
27
//#define HTTP_DETAIL_LOG 1
29
#define SNS_HTTP_METHOD "POST"
30
#define SNS_LOOKUP_URL "/snsd2/wa/lookupSession"
31
#define SNS_REQLINE "reqline"
32
#define SNS_APPNAME "appname"
33
#define SNS_COOKIES "cookies"
35
static inline int _isPlistBreakChar(unsigned char c)
37
if (!apr_isalnum(c)) return 1;
40
case '_': case '@': case '#': case '$':
41
case '.': case '=': case ';': case ',':
42
case '{': case '}': case '(': case ')':
43
case '<': case '>': case '/': case '\\':
52
static void _getSNSAddressForRequest(request_rec *_rq, struct sockaddr **_sns,
53
ngobjweb_dir_config *_cfg)
55
//extern struct sockaddr *sns;
56
struct sockaddr *result = NULL; //sns;
61
fprintf(stderr, "%s: missing request ...\n", __PRETTY_FUNCTION__);
65
ap_log_error(__FILE__, __LINE__, APLOG_ERR, 0, _rq->server,
66
"SNS: missing directory config for request ..");
70
if ((socket = _cfg->snsPort)) {
74
if (_cfg->snsPortDomain == AF_UNIX) {
75
result = apr_palloc(_rq->pool, sizeof(struct sockaddr_un));
76
memset(result, 0, sizeof(struct sockaddr_un));
78
((struct sockaddr_un *)result)->sun_family = AF_UNIX;
79
strncpy(((struct sockaddr_un *)result)->sun_path,
81
sizeof(((struct sockaddr_un *)result)->sun_path) - 1);
83
else if (_cfg->snsPortDomain == AF_INET) {
84
/* the string contained a number - the port of an IP address */
85
struct sockaddr_in *snsi;
88
/* try to convert port to number */
89
if ((pos = index(socket, ':'))) {
91
port = strtol((pos + 1), &end, 10);
93
host = apr_palloc(_rq->pool, (pos - socket) + 3);
94
strncpy(host, socket, (pos - socket));
95
host[pos - socket] = '\0';
99
port = strtol(socket, &end, 10);
102
result = apr_palloc(_rq->pool, sizeof(struct sockaddr_in));
103
memset(result, 0, sizeof(struct sockaddr_in));
104
snsi = (struct sockaddr_in *)result;
106
snsi->sin_addr.s_addr = apr_inet_addr(host);
108
snsi->sin_family = AF_INET;
109
snsi->sin_port = htons((short)(port & 0xFFFF));
111
if (snsi->sin_addr.s_addr == -1) {
112
ap_log_error(__FILE__, __LINE__, APLOG_ERR, 0, _rq->server,
113
"SNS: couldn't convert snsd IP address: %s", host);
115
if (HEAVY_LOG && 0) {
116
ap_log_error(__FILE__, __LINE__, APLOG_ERR, 0, _rq->server,
117
"SNS: connect IP address: %s", host);
121
ap_log_error(__FILE__, __LINE__, APLOG_ERR, 0, _rq->server,
122
"SNS: unknown socket domain %i for SNS server "
124
_cfg->snsPortDomain, _cfg->snsPort);
131
static void _logSNSConnect(request_rec *_rq, struct sockaddr *sns) {
133
ap_log_error(__FILE__, __LINE__, APLOG_INFO, 0, _rq->server,
134
"found no SNS socket address ...");
137
if (sns->sa_family == AF_INET) {
138
struct sockaddr_in *snsi = (struct sockaddr_in *)sns;
141
ap_log_error(__FILE__, __LINE__, APLOG_INFO, 0, _rq->server,
142
"SNS: connecting INET socket (family=%d, ip=%s:%i) ...",
144
inet_ntoa(snsi->sin_addr),
145
ntohs(snsi->sin_port));
148
else if (sns->sa_family == AF_UNIX) {
150
ap_log_error(__FILE__, __LINE__, APLOG_INFO, 0, _rq->server,
151
"SNS: connect UNIX socket (family=%d) ...",
156
ap_log_error(__FILE__, __LINE__, APLOG_ERR, 0, _rq->server,
157
"SNS: unknown socket address family: %d.",
162
void *_sendSNSQuery(request_rec *_rq, const char *_line,
164
int *_domain, size_t *_len,
165
const char *_appName,
166
ngobjweb_dir_config *_cfg)
169
Sends a query for the instance socket address to the session
172
NGBufferedDescriptor *toSNS = NULL;
174
struct sockaddr *sns;
177
_getSNSAddressForRequest(_rq, &sns, _cfg);
185
if (_line == NULL) _line = "";
186
if (_cookie == NULL) _cookie = "";
188
/* setup connection */
190
_logSNSConnect(_rq, sns);
192
fd = socket(sns->sa_family, SOCK_STREAM, 0);
194
ap_log_error(__FILE__, __LINE__, APLOG_ERR, 0, _rq->server,
195
"SNS: could not setup socket to SNS: %s.",
201
(sns->sa_family == AF_INET)
202
? sizeof(struct sockaddr_in)
203
: sizeof(struct sockaddr_un)) != 0) {
205
ap_log_error(__FILE__, __LINE__, APLOG_ERR, 0, _rq->server,
206
"could not connect sns daemon %s: %s.",
207
sns->sa_family == AF_UNIX
208
? ((struct sockaddr_un *)sns)->sun_path
216
toSNS = NGBufferedDescriptor_newWithOwnedDescriptorAndSize(fd, 1024);
218
ap_log_error(__FILE__, __LINE__, APLOG_ERR, 0, _rq->server,
219
"could not allocate buffered descriptor.");
227
char c = 50; // SNSLookupSession
228
int len = strlen(_line);
231
ap_log_error(__FILE__, __LINE__, APLOG_INFO, 0, _rq->server,
232
"SNS: line %s cookie '%s'", _line, _cookie);
235
/* send message code */
236
if (!NGBufferedDescriptor_safeWrite(toSNS, &c, 1)) {
241
/* send request line + space + appname */
242
len = strlen(_line) + 1 + strlen(_appName);
243
if (!NGBufferedDescriptor_safeWrite(toSNS, &len, sizeof(len))) {
248
if ((len = strlen(_line)) > 0) {
249
if (!NGBufferedDescriptor_safeWrite(toSNS, _line, len)) {
254
if (!NGBufferedDescriptor_safeWrite(toSNS, " ", 1)) {
258
if ((len = strlen(_appName)) > 0) {
259
if (!NGBufferedDescriptor_safeWrite(toSNS, _appName, len)) {
266
len = strlen(_cookie);
268
ap_log_error(__FILE__, __LINE__, APLOG_INFO, 0, _rq->server,
269
"WARNING: cookie length > 2000 bytes (%i bytes): %s",
272
if (!NGBufferedDescriptor_safeWrite(toSNS, &len, sizeof(len))) {
277
if (!NGBufferedDescriptor_safeWrite(toSNS, _cookie, len)) {
283
if (!NGBufferedDescriptor_flush(toSNS)) {
289
ap_log_error(__FILE__, __LINE__, APLOG_INFO, 0, _rq->server,
290
"SNS: reading response ..");
299
buffer = apr_palloc(_rq->pool, 1000);
300
memset(buffer, 0, 1000);
302
if (!NGBufferedDescriptor_safeRead(toSNS, &domain, sizeof(domain))) {
307
ap_log_error(__FILE__, __LINE__, APLOG_INFO, 0, _rq->server,
308
"SNS: domain: %i ..", domain);
311
if (!NGBufferedDescriptor_safeRead(toSNS, &size, sizeof(size))) {
316
ap_log_error(__FILE__, __LINE__, APLOG_INFO, 0, _rq->server,
317
"SNS: size: %i ..", size);
321
ap_log_error(__FILE__, __LINE__, APLOG_ERR, 0, _rq->server,
322
"SNS: size of returned address is too big (%i bytes) !",
327
if (!NGBufferedDescriptor_safeRead(toSNS, buffer, size)) {
333
ap_log_error(__FILE__, __LINE__, APLOG_INFO, 0, _rq->server,
334
"SNS: got address in domain %i, size is %i bytes !",
342
NGBufferedDescriptor_free(toSNS);
349
ap_log_error(__FILE__, __LINE__, APLOG_ERR, 0, _rq->server,
350
"SNS: lookup request failed (code=%i) !", failed);
353
NGBufferedDescriptor_free(toSNS);