jabberd2  2.7.0
error.c
Go to the documentation of this file.
1 /*
2  * jabberd - Jabber Open Source Server
3  * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney,
4  * Ryan Eatmon, Robert Norris
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
19  */
20 
21 #include "sx.h"
22 
24 static const char *_stream_errors[] = {
25  "bad-format",
26  "bad-namespace-prefix",
27  "conflict",
28  "connection-timeout",
29  "host-gone",
30  "host-unknown",
31  "improper-addressing",
32  "internal-server-error",
33  "invalid-from",
34  "invalid-id",
35  "invalid-namespace",
36  "invalid-xml",
37  "not-authorized",
38  "policy-violation",
39  "remote-connection-failed",
40  "restricted-xml",
41  "resource-constraint",
42  "see-other-host",
43  "system-shutdown",
44  "undefined-condition",
45  "unsupported-encoding",
46  "unsupported-stanza-type",
47  "unsupported-version",
48  "xml-not-well-formed",
49  NULL
50 };
51 
53 void _sx_error(sx_t s, int err, const char *text) {
54  int len = 0;
55  sx_buf_t buf;
56 
57  /* open stream if not already */
58  if(s->state < state_STREAM) {
59  if (s->flags & SX_WEBSOCKET_WRAPPER)
60  jqueue_push(s->wbufq, _sx_buffer_new("<open xmlns='" uri_XFRAMING "' version='1.0' />", sizeof(uri_XFRAMING) + 30, NULL, NULL), 0);
61  else
62  jqueue_push(s->wbufq, _sx_buffer_new("<stream:stream xmlns:stream='" uri_STREAMS "' version='1.0'>", sizeof(uri_STREAMS) + 44, NULL, NULL), 0);
63  }
64 
65  /* build the error */
66  len = strlen(uri_STREAMS) + strlen(uri_STREAM_ERR) + strlen(_stream_errors[err]) + 58;
67  if(text != NULL) len += strlen(uri_STREAM_ERR) + strlen(text) + 22;
68 
69  buf = _sx_buffer_new(NULL, len, NULL, NULL);
70 
71  if(text == NULL)
72  len = sprintf(buf->data, "<stream:error xmlns:stream='" uri_STREAMS "'><%s xmlns='" uri_STREAM_ERR "'/></stream:error>", _stream_errors[err]);
73  else
74  len = sprintf(buf->data, "<stream:error xmlns:stream='" uri_STREAMS "'><%s xmlns='" uri_STREAM_ERR "'/><text xmlns='" uri_STREAM_ERR "'>%s</text></stream:error>", _stream_errors[err], text);
75 
76  buf->len--;
77  assert(len == buf->len);
78 
79  _sx_debug(ZONE, "prepared error: %.*s", buf->len, buf->data);
80  jqueue_push(s->wbufq, buf, 0);
81 
82  /* close the stream if needed */
83  if(s->state < state_STREAM) {
84  if (s->flags & SX_WEBSOCKET_WRAPPER)
85  jqueue_push(s->wbufq, _sx_buffer_new("<close xmlns='" uri_XFRAMING "' />", sizeof(uri_XFRAMING) + 17, NULL, NULL), 0);
86  else
87  jqueue_push(s->wbufq, _sx_buffer_new("</stream:stream>", 16, NULL, NULL), 0);
88  }
89 
90  /* stuff to write */
91  s->want_write = 1;
92 }
93 
94 void sx_error(sx_t s, int err, const char *text) {
95  assert(s != NULL);
96  assert(err >= 0 && err < stream_err_LAST);
97 
98  _sx_error(s, err, text);
99 
100  _sx_event(s, event_WANT_WRITE, NULL);
101 }
102 
103 //** send an extended error with custom contents other than text */
104 // Ideally should be merged with sx_error. sx_error should permit additional content beneath the <stream:error> element, other than a <text> node.
105 void _sx_error_extended(sx_t s, int err, const char *content) {
106  int len = 0;
107  sx_buf_t buf;
108 
109  /* build the string */
110  if(s->state < state_STREAM) len = strlen(uri_STREAMS) + 61;
111  len += strlen(uri_STREAMS) + strlen(uri_STREAM_ERR) + strlen(_stream_errors[err]) + 58;
112  if(content != NULL) len += strlen(content) + strlen(_stream_errors[err]) + 2;
113 
114  buf = _sx_buffer_new(NULL, len, NULL, NULL);
115  len = 0;
116 
117  if(s->state < state_STREAM)
118  len = sprintf(buf->data, "<stream:stream xmlns:stream='" uri_STREAMS "' version='1.0'>");
119 
120  if(content == NULL)
121  len += sprintf(&(buf->data[len]), "<stream:error xmlns:stream='" uri_STREAMS "'><%s xmlns='" uri_STREAM_ERR "'/></stream:error>", _stream_errors[err]);
122  else
123  len += sprintf(&(buf->data[len]), "<stream:error xmlns:stream='" uri_STREAMS "'><%s xmlns='" uri_STREAM_ERR "'>%s</%s></stream:error>", _stream_errors[err], content, _stream_errors[err]);
124 
125  if(s->state < state_STREAM)
126  len += sprintf(&(buf->data[len]), "</stream:stream>");
127 
128  buf->len--;
129  assert(len == buf->len);
130 
131  _sx_debug(ZONE, "prepared error: %.*s", buf->len, buf->data);
132 
133  /* go */
134  jqueue_push(s->wbufq, buf, 0);
135 
136  /* stuff to write */
137  s->want_write = 1;
138 }
139 
140 void sx_error_extended(sx_t s, int err, const char *content) {
141  assert(s != NULL);
142  assert(err >= 0 && err < stream_err_LAST);
143 
144  _sx_error_extended(s, err, content);
145 
146  _sx_event(s, event_WANT_WRITE, NULL);
147 }
Definition: sx.h:113
_sx_state_t state
Definition: sx.h:319
#define _sx_event(s, e, data)
Definition: sx.h:395
unsigned int flags
Definition: sx.h:276
jqueue_t wbufq
Definition: sx.h:301
void _sx_error_extended(sx_t s, int err, const char *content)
Definition: error.c:105
static const char * _stream_errors[]
if you change these, reflect your changes in the defines in sx.h
Definition: error.c:24
holds the state for a single stream
Definition: sx.h:253
char * data
Definition: sx.h:114
void jqueue_push(jqueue_t q, void *data, int priority)
Definition: jqueue.c:44
#define stream_err_LAST
Definition: sx.h:148
sx_buf_t _sx_buffer_new(const char *data, int len, _sx_notify_t notify, void *notify_arg)
utility: make a new buffer if len>0 but data is NULL, the buffer will contain that many bytes of garb...
Definition: sx.c:220
void sx_error_extended(sx_t s, int err, const char *content)
Definition: error.c:140
#define SX_WEBSOCKET_WRAPPER
Definition: plugins.h:34
#define _sx_debug
Definition: sx.h:408
#define uri_STREAMS
Definition: uri.h:34
void sx_error(sx_t s, int err, const char *text)
Definition: error.c:94
unsigned int len
Definition: sx.h:115
#define uri_STREAM_ERR
Definition: uri.h:50
void _sx_error(sx_t s, int err, const char *text)
send an error
Definition: error.c:53
#define ZONE
Definition: mio_impl.h:76
#define uri_XFRAMING
Definition: uri.h:44
int want_write
Definition: sx.h:306