oversip 1.3.8 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
}
|