oversip 1.3.8 → 1.4.0

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