oversip 1.3.8 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +1 -1
- data/etc/oversip.conf +28 -0
- data/ext/sip_parser/{sip_parser.c → sip_message_parser.c} +119 -119
- data/ext/sip_parser/sip_parser.h +24 -2
- data/ext/sip_parser/sip_parser_ruby.c +84 -27
- data/ext/sip_parser/sip_uri_parser.c +39699 -0
- data/lib/oversip/config.rb +14 -0
- data/lib/oversip/errors.rb +3 -0
- data/lib/oversip/modules/outbound_mangling.rb +20 -24
- data/lib/oversip/sip/client.rb +135 -11
- data/lib/oversip/sip/launcher.rb +82 -38
- data/lib/oversip/sip/name_addr.rb +8 -0
- data/lib/oversip/sip/proxy.rb +22 -13
- data/lib/oversip/sip/request.rb +31 -1
- data/lib/oversip/sip/uac.rb +9 -13
- data/lib/oversip/sip/uac_request.rb +11 -10
- data/lib/oversip/sip/uri.rb +24 -0
- data/lib/oversip/version.rb +3 -3
- data/lib/oversip/websocket/launcher.rb +64 -30
- data/lib/oversip.rb +6 -0
- data/test/test_name_addr_parser.rb +24 -0
- data/test/{test_sip_parser.rb → test_sip_message_parser.rb} +15 -1
- data/test/test_sip_uri_parser.rb +56 -0
- data/test/test_uri.rb +11 -0
- data/thirdparty/stud/stud.tar.gz +0 -0
- metadata +10 -5
data/ext/sip_parser/sip_parser.h
CHANGED
@@ -156,7 +156,7 @@ typedef struct sip_message_parser {
|
|
156
156
|
char * error_start;
|
157
157
|
size_t error_len;
|
158
158
|
int error_pos;
|
159
|
-
|
159
|
+
|
160
160
|
size_t mark;
|
161
161
|
size_t hdr_field_start;
|
162
162
|
size_t hdr_field_len;
|
@@ -203,7 +203,7 @@ typedef struct sip_message_parser {
|
|
203
203
|
enum uri_scheme uri_scheme;
|
204
204
|
/* URI display name is quoted. */
|
205
205
|
size_t uri_display_name_quoted;
|
206
|
-
|
206
|
+
|
207
207
|
header_cb header;
|
208
208
|
struct_message message;
|
209
209
|
struct_uri uri;
|
@@ -216,6 +216,27 @@ typedef struct sip_message_parser {
|
|
216
216
|
VALUE ruby_sip_parser;
|
217
217
|
} sip_message_parser;
|
218
218
|
|
219
|
+
typedef struct sip_uri_parser {
|
220
|
+
/* Parser stuf. */
|
221
|
+
size_t mark;
|
222
|
+
size_t uri_start;
|
223
|
+
/* URI parameters. */
|
224
|
+
size_t uri_param_key_start;
|
225
|
+
size_t uri_param_key_len;
|
226
|
+
size_t uri_param_value_start;
|
227
|
+
size_t uri_param_value_len;
|
228
|
+
/* URI scheme type. */
|
229
|
+
enum uri_scheme uri_scheme;
|
230
|
+
/* URI display name is quoted. */
|
231
|
+
size_t uri_display_name_quoted;
|
232
|
+
|
233
|
+
struct_uri uri;
|
234
|
+
|
235
|
+
/* Will be set to OverSIP::SIP::Uri. */
|
236
|
+
VALUE parsed;
|
237
|
+
} sip_uri_parser;
|
238
|
+
|
239
|
+
|
219
240
|
|
220
241
|
int sip_message_parser_init(sip_message_parser *parser);
|
221
242
|
int sip_message_parser_finish(sip_message_parser *parser);
|
@@ -223,6 +244,7 @@ size_t sip_message_parser_execute(sip_message_parser *parser, const char *buffer
|
|
223
244
|
int sip_message_parser_has_error(sip_message_parser *parser);
|
224
245
|
int sip_message_parser_is_finished(sip_message_parser *parser);
|
225
246
|
#define sip_message_parser_nread(parser) (parser)->nread
|
247
|
+
int sip_uri_parser_execute(sip_uri_parser *parser, const char *buffer, size_t len, VALUE parsed, int allow_name_addr);
|
226
248
|
|
227
249
|
|
228
250
|
#endif
|
@@ -116,7 +116,8 @@ static VALUE string_Call_ID;
|
|
116
116
|
static VALUE string_Max_Forwards;
|
117
117
|
static VALUE string_Content_Length;
|
118
118
|
|
119
|
-
|
119
|
+
/* A single and global SIP URI parser. */
|
120
|
+
static sip_uri_parser *global_sip_uri_parser;
|
120
121
|
|
121
122
|
|
122
123
|
static void data_type(void *parser, enum data_type data_type)
|
@@ -124,7 +125,7 @@ static void data_type(void *parser, enum data_type data_type)
|
|
124
125
|
TRACE();
|
125
126
|
VALUE parsed;
|
126
127
|
sip_message_parser *sp = (sip_message_parser*)parser;
|
127
|
-
|
128
|
+
|
128
129
|
switch(data_type) {
|
129
130
|
case sip_request:
|
130
131
|
parsed = rb_obj_alloc(cSIPRequest);
|
@@ -171,7 +172,7 @@ static void header(VALUE parsed, const char *hdr_field, size_t hdr_field_len, co
|
|
171
172
|
|
172
173
|
/* Header name. */
|
173
174
|
f = headerize(hdr_field, hdr_field_len);
|
174
|
-
|
175
|
+
|
175
176
|
/* Header value. */
|
176
177
|
v = RB_STR_UTF8_NEW(hdr_value, hdr_value_len);
|
177
178
|
|
@@ -209,7 +210,7 @@ static void msg_method(VALUE parsed, const char *at, size_t length, enum method
|
|
209
210
|
{
|
210
211
|
TRACE();
|
211
212
|
VALUE v;
|
212
|
-
|
213
|
+
|
213
214
|
switch(method) {
|
214
215
|
/* If the method is known store it as a symbol (i.e. :INVITE). */
|
215
216
|
case method_INVITE:
|
@@ -308,7 +309,7 @@ static void msg_via_sent_by_host(VALUE parsed, const char *at, size_t length)
|
|
308
309
|
{
|
309
310
|
TRACE();
|
310
311
|
VALUE v;
|
311
|
-
|
312
|
+
|
312
313
|
v = RB_STR_UTF8_NEW(at, length);
|
313
314
|
rb_ivar_set(parsed, id_via_sent_by_host, v);
|
314
315
|
}
|
@@ -318,7 +319,7 @@ static void msg_via_sent_by_port(VALUE parsed, const char *at, size_t length)
|
|
318
319
|
{
|
319
320
|
TRACE();
|
320
321
|
VALUE v;
|
321
|
-
|
322
|
+
|
322
323
|
v = INT2FIX(str_to_int(at, length));
|
323
324
|
rb_ivar_set(parsed, id_via_sent_by_port, v);
|
324
325
|
}
|
@@ -337,7 +338,7 @@ static void msg_via_branch(VALUE parsed, const char *at, size_t length)
|
|
337
338
|
static void msg_via_branch_rfc3261(VALUE parsed, const char *at, size_t length)
|
338
339
|
{
|
339
340
|
TRACE();
|
340
|
-
|
341
|
+
|
341
342
|
rb_ivar_set(parsed, id_via_branch_rfc3261, Qtrue);
|
342
343
|
}
|
343
344
|
|
@@ -392,7 +393,7 @@ static void msg_max_forwards(VALUE parsed, const char *at, size_t length)
|
|
392
393
|
{
|
393
394
|
TRACE();
|
394
395
|
VALUE v;
|
395
|
-
|
396
|
+
|
396
397
|
v = INT2FIX(str_to_int(at, length));
|
397
398
|
rb_ivar_set(parsed, id_max_forwards, v);
|
398
399
|
}
|
@@ -443,6 +444,9 @@ static VALUE get_uri_object(VALUE parsed, enum uri_owner owner)
|
|
443
444
|
return RARRAY_PTR(routes_array)[RARRAY_LEN(routes_array)-1];
|
444
445
|
break;
|
445
446
|
case uri_owner_contact: return rb_ivar_get(parsed, id_contact); break;
|
447
|
+
/* Otherwise return the parsed object itself (useful for OverSIP::SIP::MessageParser.parse_uri method). */
|
448
|
+
default:
|
449
|
+
return parsed;
|
446
450
|
}
|
447
451
|
return Qnil;
|
448
452
|
}
|
@@ -579,7 +583,7 @@ static void uri_known_param(VALUE parsed, enum uri_owner owner, enum uri_param_n
|
|
579
583
|
v = my_rb_str_downcase(at, length);
|
580
584
|
break;
|
581
585
|
}
|
582
|
-
|
586
|
+
|
583
587
|
rb_ivar_set(get_uri_object(parsed, owner), p, v);
|
584
588
|
}
|
585
589
|
|
@@ -594,7 +598,7 @@ static void uri_has_param(VALUE parsed, enum uri_owner owner, enum uri_param_nam
|
|
594
598
|
case uri_param_lr: p = id_uri_lr_param; break;
|
595
599
|
case uri_param_ob: p = id_uri_ob_param; break;
|
596
600
|
}
|
597
|
-
|
601
|
+
|
598
602
|
rb_ivar_set(get_uri_object(parsed, owner), p, Qtrue);
|
599
603
|
}
|
600
604
|
|
@@ -616,7 +620,7 @@ static void uri_display_name(VALUE parsed, enum uri_owner owner, const char *at,
|
|
616
620
|
|
617
621
|
if (length == 0)
|
618
622
|
return;
|
619
|
-
|
623
|
+
|
620
624
|
v = RB_STR_UTF8_NEW(at, length);
|
621
625
|
rb_ivar_set(get_uri_object(parsed, owner), id_display_name, v);
|
622
626
|
}
|
@@ -698,7 +702,7 @@ static void option_tag(VALUE parsed, enum header_field header_field, const char
|
|
698
702
|
VALUE v;
|
699
703
|
VALUE id_option_tag_owner;
|
700
704
|
VALUE option_tag_owner;
|
701
|
-
|
705
|
+
|
702
706
|
switch(header_field) {
|
703
707
|
case header_field_require: id_option_tag_owner = id_require; break;
|
704
708
|
case header_field_proxy_require: id_option_tag_owner = id_proxy_require; break;
|
@@ -800,7 +804,7 @@ VALUE SipMessageParser_alloc(VALUE klass)
|
|
800
804
|
parser->message.header_param = header_param;
|
801
805
|
parser->message.option_tag = option_tag;
|
802
806
|
parser->message.init_component = init_component;
|
803
|
-
|
807
|
+
|
804
808
|
parser->uri.full = uri_full;
|
805
809
|
parser->uri.scheme = uri_scheme;
|
806
810
|
parser->uri.user = uri_user;
|
@@ -811,7 +815,7 @@ VALUE SipMessageParser_alloc(VALUE klass)
|
|
811
815
|
parser->uri.has_param = uri_has_param;
|
812
816
|
parser->uri.headers = uri_headers;
|
813
817
|
parser->uri.display_name = uri_display_name;
|
814
|
-
|
818
|
+
|
815
819
|
sip_message_parser_init(parser);
|
816
820
|
|
817
821
|
obj = Data_Wrap_Struct(klass, NULL, SipMessageParser_free, parser);
|
@@ -887,7 +891,7 @@ VALUE SipMessageParser_execute(VALUE self, VALUE buffer, VALUE start)
|
|
887
891
|
int from = 0;
|
888
892
|
char *dptr = NULL;
|
889
893
|
long dlen = 0;
|
890
|
-
|
894
|
+
|
891
895
|
REQUIRE_TYPE(buffer, T_STRING);
|
892
896
|
REQUIRE_TYPE(start, T_FIXNUM);
|
893
897
|
|
@@ -903,7 +907,7 @@ VALUE SipMessageParser_execute(VALUE self, VALUE buffer, VALUE start)
|
|
903
907
|
|
904
908
|
sip_message_parser_execute(parser, dptr, dlen, from);
|
905
909
|
|
906
|
-
if(sip_message_parser_has_error(parser))
|
910
|
+
if (sip_message_parser_has_error(parser))
|
907
911
|
return Qfalse;
|
908
912
|
else
|
909
913
|
return INT2FIX(sip_message_parser_nread(parser));
|
@@ -1072,7 +1076,7 @@ VALUE SipMessageParser_has_duplicated_core_header(VALUE self)
|
|
1072
1076
|
|
1073
1077
|
/* NOTE: Good moment for counting the num of Via values and store it. */
|
1074
1078
|
rb_ivar_set(parser->parsed, id_num_vias, INT2FIX(parser->num_via));
|
1075
|
-
|
1079
|
+
|
1076
1080
|
if (parser->num_from > 1)
|
1077
1081
|
return string_From;
|
1078
1082
|
else if (parser->num_to > 1)
|
@@ -1113,7 +1117,7 @@ VALUE SipMessageParser_has_missing_core_header(VALUE self)
|
|
1113
1117
|
return string_CSeq;
|
1114
1118
|
else if (parser->num_call_id == 0)
|
1115
1119
|
return string_Call_ID;
|
1116
|
-
|
1120
|
+
|
1117
1121
|
return Qfalse;
|
1118
1122
|
}
|
1119
1123
|
|
@@ -1125,11 +1129,8 @@ VALUE SipMessageParser_post_parsing(VALUE self)
|
|
1125
1129
|
DATA_GET(self, sip_message_parser, parser);
|
1126
1130
|
|
1127
1131
|
/* We just parse Contact if it's a single header with a single Name Addr within it. */
|
1128
|
-
if (! (parser->contact_is_valid == 1 && parser->num_contact == 1))
|
1129
|
-
/*printf("--- if (! (parser->contact_is_valid == 1 && parser->num_contact == 1)) returns false\n");
|
1130
|
-
printf("--- parser->num_contact = %d\n", parser->num_contact);*/
|
1132
|
+
if (! (parser->contact_is_valid == 1 && parser->num_contact == 1))
|
1131
1133
|
rb_ivar_set(parser->parsed, id_contact, Qnil);
|
1132
|
-
}
|
1133
1134
|
|
1134
1135
|
return Qnil;
|
1135
1136
|
}
|
@@ -1149,7 +1150,7 @@ VALUE SipMessageParser_Class_headerize(VALUE self, VALUE string)
|
|
1149
1150
|
TRACE();
|
1150
1151
|
if (TYPE(string) != T_STRING)
|
1151
1152
|
rb_raise(rb_eTypeError, "Argument must be a String");
|
1152
|
-
|
1153
|
+
|
1153
1154
|
if ((RSTRING_LEN(string)) == 0)
|
1154
1155
|
rb_str_new(RSTRING_PTR(string), RSTRING_LEN(string));
|
1155
1156
|
|
@@ -1157,15 +1158,67 @@ VALUE SipMessageParser_Class_headerize(VALUE self, VALUE string)
|
|
1157
1158
|
}
|
1158
1159
|
|
1159
1160
|
|
1161
|
+
/**
|
1162
|
+
* call-seq:
|
1163
|
+
* OverSIP::SIP::MessageParser.parse_uri(string) -> OverSIP::SIP::Uri
|
1164
|
+
*/
|
1165
|
+
VALUE SipMessageParser_Class_parse_uri(VALUE self, VALUE string, VALUE allow_name_addr)
|
1166
|
+
{
|
1167
|
+
TRACE();
|
1168
|
+
char *dptr = NULL;
|
1169
|
+
long dlen = 0;
|
1170
|
+
sip_uri_parser *parser;
|
1171
|
+
VALUE parsed;
|
1172
|
+
int int_allow_name_addr;
|
1173
|
+
|
1174
|
+
/* Initialize the global SIP URI parser if not set yet. */
|
1175
|
+
if (global_sip_uri_parser == NULL) {
|
1176
|
+
/* Asign functions to the pointers of global_sip_uri_parser struct. */
|
1177
|
+
global_sip_uri_parser = ALLOC(sip_uri_parser);
|
1178
|
+
global_sip_uri_parser->uri.full = uri_full;
|
1179
|
+
global_sip_uri_parser->uri.scheme = uri_scheme;
|
1180
|
+
global_sip_uri_parser->uri.user = uri_user;
|
1181
|
+
global_sip_uri_parser->uri.host = uri_host;
|
1182
|
+
global_sip_uri_parser->uri.port = uri_port;
|
1183
|
+
global_sip_uri_parser->uri.param = uri_param;
|
1184
|
+
global_sip_uri_parser->uri.known_param = uri_known_param;
|
1185
|
+
global_sip_uri_parser->uri.has_param = uri_has_param;
|
1186
|
+
global_sip_uri_parser->uri.headers = uri_headers;
|
1187
|
+
global_sip_uri_parser->uri.display_name = uri_display_name;
|
1188
|
+
}
|
1189
|
+
|
1190
|
+
REQUIRE_TYPE(string, T_STRING);
|
1191
|
+
|
1192
|
+
/* NOTE: We need to pass a \0 terminated string to the URI parser. StringValueCStr() gives
|
1193
|
+
* exactly that. So also increment dlen in 1. */
|
1194
|
+
dptr = StringValueCStr(string);
|
1195
|
+
dlen = RSTRING_LEN(string) + 1;
|
1196
|
+
|
1197
|
+
if (TYPE(allow_name_addr) == T_TRUE) {
|
1198
|
+
parsed = rb_obj_alloc(cNameAddr);
|
1199
|
+
int_allow_name_addr = 1;
|
1200
|
+
}
|
1201
|
+
else {
|
1202
|
+
parsed = rb_obj_alloc(cUri);
|
1203
|
+
int_allow_name_addr = 0;
|
1204
|
+
}
|
1205
|
+
|
1206
|
+
if (sip_uri_parser_execute(global_sip_uri_parser, dptr, dlen, parsed, int_allow_name_addr) == 0)
|
1207
|
+
return parsed;
|
1208
|
+
else
|
1209
|
+
return Qfalse;
|
1210
|
+
}
|
1211
|
+
|
1212
|
+
|
1160
1213
|
|
1161
1214
|
|
1162
1215
|
void Init_sip_parser()
|
1163
1216
|
{
|
1164
1217
|
TRACE();
|
1165
|
-
|
1218
|
+
|
1166
1219
|
mOverSIP = rb_define_module("OverSIP");
|
1167
1220
|
eOverSIPError = rb_define_class_under(mOverSIP, "Error", rb_eStandardError);
|
1168
|
-
|
1221
|
+
|
1169
1222
|
mSIP = rb_define_module_under(mOverSIP, "SIP");
|
1170
1223
|
cSIPMessageParser = rb_define_class_under(mSIP, "MessageParser", rb_cObject);
|
1171
1224
|
cSIPMessage = rb_define_class_under(mSIP, "Message", rb_cObject);
|
@@ -1190,6 +1243,7 @@ void Init_sip_parser()
|
|
1190
1243
|
rb_define_method(cSIPMessageParser, "post_parsing", SipMessageParser_post_parsing,0);
|
1191
1244
|
|
1192
1245
|
rb_define_module_function(cSIPMessageParser, "headerize", SipMessageParser_Class_headerize,1);
|
1246
|
+
rb_define_module_function(cSIPMessageParser, "parse_uri", SipMessageParser_Class_parse_uri,2);
|
1193
1247
|
|
1194
1248
|
init_common_headers();
|
1195
1249
|
init_short_headers();
|
@@ -1231,7 +1285,7 @@ void Init_sip_parser()
|
|
1231
1285
|
id_hdr_from = rb_intern("@hdr_from");
|
1232
1286
|
id_hdr_to = rb_intern("@hdr_to");
|
1233
1287
|
id_hdr_route = rb_intern("@hdr_route");
|
1234
|
-
|
1288
|
+
|
1235
1289
|
id_display_name = rb_intern("@display_name");
|
1236
1290
|
id_uri = rb_intern("@uri");
|
1237
1291
|
id_uri_scheme = rb_intern("@scheme");
|
@@ -1278,7 +1332,7 @@ void Init_sip_parser()
|
|
1278
1332
|
symbol_ipv4 = ID2SYM(rb_intern("ipv4"));
|
1279
1333
|
symbol_ipv6 = ID2SYM(rb_intern("ipv6"));
|
1280
1334
|
symbol_ipv6_reference = ID2SYM(rb_intern("ipv6_reference"));
|
1281
|
-
|
1335
|
+
|
1282
1336
|
string_Via = rb_str_new2("Via");
|
1283
1337
|
string_Via = rb_obj_freeze(string_Via);
|
1284
1338
|
rb_global_variable(&string_Via);
|
@@ -1300,4 +1354,7 @@ void Init_sip_parser()
|
|
1300
1354
|
string_Content_Length = rb_str_new2("Content-Length");
|
1301
1355
|
string_Content_Length = rb_obj_freeze(string_Content_Length);
|
1302
1356
|
rb_global_variable(&string_Content_Length);
|
1357
|
+
|
1358
|
+
/* Initialize global_sip_uri_parser struct to NULL. */
|
1359
|
+
global_sip_uri_parser = NULL;
|
1303
1360
|
}
|