1use crate::dispatcher;
16use crate::types::*;
17use std::ptr::{null, null_mut};
18use std::time::{Duration, SystemTime, UNIX_EPOCH};
19
20extern "C" {
21 fn proxy_log(level: LogLevel, message_data: *const u8, message_size: usize) -> Status;
22}
23
24pub fn log(level: LogLevel, message: &str) -> Result<(), Status> {
25 unsafe {
26 match proxy_log(level, message.as_ptr(), message.len()) {
27 Status::Ok => Ok(()),
28 status => panic!("unexpected status: {}", status as u32),
29 }
30 }
31}
32
33extern "C" {
34 fn proxy_get_log_level(return_level: *mut LogLevel) -> Status;
35}
36
37pub fn get_log_level() -> Result<LogLevel, Status> {
38 let mut return_level: LogLevel = LogLevel::Trace;
39 unsafe {
40 match proxy_get_log_level(&mut return_level) {
41 Status::Ok => Ok(return_level),
42 status => panic!("unexpected status: {}", status as u32),
43 }
44 }
45}
46
47extern "C" {
48 fn proxy_get_current_time_nanoseconds(return_time: *mut u64) -> Status;
49}
50
51pub fn get_current_time() -> Result<SystemTime, Status> {
52 let mut return_time: u64 = 0;
53 unsafe {
54 match proxy_get_current_time_nanoseconds(&mut return_time) {
55 Status::Ok => Ok(UNIX_EPOCH + Duration::from_nanos(return_time)),
56 status => panic!("unexpected status: {}", status as u32),
57 }
58 }
59}
60
61extern "C" {
62 fn proxy_set_tick_period_milliseconds(period: u32) -> Status;
63}
64
65pub fn set_tick_period(period: Duration) -> Result<(), Status> {
66 unsafe {
67 match proxy_set_tick_period_milliseconds(period.as_millis() as u32) {
68 Status::Ok => Ok(()),
69 status => panic!("unexpected status: {}", status as u32),
70 }
71 }
72}
73
74extern "C" {
75 fn proxy_get_buffer_bytes(
76 buffer_type: BufferType,
77 start: usize,
78 max_size: usize,
79 return_buffer_data: *mut *mut u8,
80 return_buffer_size: *mut usize,
81 ) -> Status;
82}
83
84pub fn get_buffer(
85 buffer_type: BufferType,
86 start: usize,
87 max_size: usize,
88) -> Result<Option<Bytes>, Status> {
89 let mut return_data: *mut u8 = null_mut();
90 let mut return_size: usize = 0;
91 unsafe {
92 match proxy_get_buffer_bytes(
93 buffer_type,
94 start,
95 max_size,
96 &mut return_data,
97 &mut return_size,
98 ) {
99 Status::Ok => {
100 if !return_data.is_null() {
101 Ok(Some(Vec::from_raw_parts(
102 return_data,
103 return_size,
104 return_size,
105 )))
106 } else {
107 Ok(None)
108 }
109 }
110 Status::NotFound => Ok(None),
111 status => panic!("unexpected status: {}", status as u32),
112 }
113 }
114}
115
116extern "C" {
117 fn proxy_set_buffer_bytes(
118 buffer_type: BufferType,
119 start: usize,
120 size: usize,
121 buffer_data: *const u8,
122 buffer_size: usize,
123 ) -> Status;
124}
125
126pub fn set_buffer(
127 buffer_type: BufferType,
128 start: usize,
129 size: usize,
130 value: &[u8],
131) -> Result<(), Status> {
132 unsafe {
133 match proxy_set_buffer_bytes(buffer_type, start, size, value.as_ptr(), value.len()) {
134 Status::Ok => Ok(()),
135 status => panic!("unexpected status: {}", status as u32),
136 }
137 }
138}
139
140extern "C" {
141 fn proxy_get_header_map_pairs(
142 map_type: MapType,
143 return_map_data: *mut *mut u8,
144 return_map_size: *mut usize,
145 ) -> Status;
146}
147
148pub fn get_map(map_type: MapType) -> Result<Vec<(String, String)>, Status> {
149 unsafe {
150 let mut return_data: *mut u8 = null_mut();
151 let mut return_size: usize = 0;
152 match proxy_get_header_map_pairs(map_type, &mut return_data, &mut return_size) {
153 Status::Ok => {
154 if !return_data.is_null() {
155 let serialized_map = std::slice::from_raw_parts(return_data, return_size);
156 Ok(utils::deserialize_map(serialized_map))
157 } else {
158 Ok(Vec::new())
159 }
160 }
161 status => panic!("unexpected status: {}", status as u32),
162 }
163 }
164}
165
166pub fn get_map_bytes(map_type: MapType) -> Result<Vec<(String, Bytes)>, Status> {
167 unsafe {
168 let mut return_data: *mut u8 = null_mut();
169 let mut return_size: usize = 0;
170 match proxy_get_header_map_pairs(map_type, &mut return_data, &mut return_size) {
171 Status::Ok => {
172 if !return_data.is_null() {
173 let serialized_map = std::slice::from_raw_parts(return_data, return_size);
174 Ok(utils::deserialize_map_bytes(serialized_map))
175 } else {
176 Ok(Vec::new())
177 }
178 }
179 status => panic!("unexpected status: {}", status as u32),
180 }
181 }
182}
183
184extern "C" {
185 fn proxy_set_header_map_pairs(
186 map_type: MapType,
187 map_data: *const u8,
188 map_size: usize,
189 ) -> Status;
190}
191
192pub fn set_map(map_type: MapType, map: Vec<(&str, &str)>) -> Result<(), Status> {
193 let serialized_map = utils::serialize_map(&map);
194 unsafe {
195 match proxy_set_header_map_pairs(map_type, serialized_map.as_ptr(), serialized_map.len()) {
196 Status::Ok => Ok(()),
197 status => panic!("unexpected status: {}", status as u32),
198 }
199 }
200}
201
202pub fn set_map_bytes(map_type: MapType, map: Vec<(&str, &[u8])>) -> Result<(), Status> {
203 let serialized_map = utils::serialize_map_bytes(&map);
204 unsafe {
205 match proxy_set_header_map_pairs(map_type, serialized_map.as_ptr(), serialized_map.len()) {
206 Status::Ok => Ok(()),
207 status => panic!("unexpected status: {}", status as u32),
208 }
209 }
210}
211
212extern "C" {
213 fn proxy_get_header_map_value(
214 map_type: MapType,
215 key_data: *const u8,
216 key_size: usize,
217 return_value_data: *mut *mut u8,
218 return_value_size: *mut usize,
219 ) -> Status;
220}
221
222pub fn get_map_value(map_type: MapType, key: &str) -> Result<Option<String>, Status> {
223 let mut return_data: *mut u8 = null_mut();
224 let mut return_size: usize = 0;
225 unsafe {
226 match proxy_get_header_map_value(
227 map_type,
228 key.as_ptr(),
229 key.len(),
230 &mut return_data,
231 &mut return_size,
232 ) {
233 Status::Ok => {
234 if !return_data.is_null() {
235 Ok(Some(
236 String::from_utf8(Vec::from_raw_parts(
237 return_data,
238 return_size,
239 return_size,
240 ))
241 .unwrap(),
242 ))
243 } else {
244 Ok(Some(String::new()))
245 }
246 }
247 Status::NotFound => Ok(None),
248 status => panic!("unexpected status: {}", status as u32),
249 }
250 }
251}
252
253pub fn get_map_value_bytes(map_type: MapType, key: &str) -> Result<Option<Bytes>, Status> {
254 let mut return_data: *mut u8 = null_mut();
255 let mut return_size: usize = 0;
256 unsafe {
257 match proxy_get_header_map_value(
258 map_type,
259 key.as_ptr(),
260 key.len(),
261 &mut return_data,
262 &mut return_size,
263 ) {
264 Status::Ok => {
265 if !return_data.is_null() {
266 Ok(Some(Vec::from_raw_parts(
267 return_data,
268 return_size,
269 return_size,
270 )))
271 } else {
272 Ok(Some(Vec::new()))
273 }
274 }
275 Status::NotFound => Ok(None),
276 status => panic!("unexpected status: {}", status as u32),
277 }
278 }
279}
280
281extern "C" {
282 fn proxy_remove_header_map_value(
283 map_type: MapType,
284 key_data: *const u8,
285 key_size: usize,
286 ) -> Status;
287}
288
289pub fn remove_map_value(map_type: MapType, key: &str) -> Result<(), Status> {
290 unsafe {
291 match proxy_remove_header_map_value(map_type, key.as_ptr(), key.len()) {
292 Status::Ok => Ok(()),
293 status => panic!("unexpected status: {}", status as u32),
294 }
295 }
296}
297
298extern "C" {
299 fn proxy_replace_header_map_value(
300 map_type: MapType,
301 key_data: *const u8,
302 key_size: usize,
303 value_data: *const u8,
304 value_size: usize,
305 ) -> Status;
306}
307
308pub fn set_map_value(map_type: MapType, key: &str, value: Option<&str>) -> Result<(), Status> {
309 unsafe {
310 if let Some(value) = value {
311 match proxy_replace_header_map_value(
312 map_type,
313 key.as_ptr(),
314 key.len(),
315 value.as_ptr(),
316 value.len(),
317 ) {
318 Status::Ok => Ok(()),
319 status => panic!("unexpected status: {}", status as u32),
320 }
321 } else {
322 match proxy_remove_header_map_value(map_type, key.as_ptr(), key.len()) {
323 Status::Ok => Ok(()),
324 status => panic!("unexpected status: {}", status as u32),
325 }
326 }
327 }
328}
329
330pub fn set_map_value_bytes(
331 map_type: MapType,
332 key: &str,
333 value: Option<&[u8]>,
334) -> Result<(), Status> {
335 unsafe {
336 if let Some(value) = value {
337 match proxy_replace_header_map_value(
338 map_type,
339 key.as_ptr(),
340 key.len(),
341 value.as_ptr(),
342 value.len(),
343 ) {
344 Status::Ok => Ok(()),
345 status => panic!("unexpected status: {}", status as u32),
346 }
347 } else {
348 match proxy_remove_header_map_value(map_type, key.as_ptr(), key.len()) {
349 Status::Ok => Ok(()),
350 status => panic!("unexpected status: {}", status as u32),
351 }
352 }
353 }
354}
355
356extern "C" {
357 fn proxy_add_header_map_value(
358 map_type: MapType,
359 key_data: *const u8,
360 key_size: usize,
361 value_data: *const u8,
362 value_size: usize,
363 ) -> Status;
364}
365
366pub fn add_map_value(map_type: MapType, key: &str, value: &str) -> Result<(), Status> {
367 unsafe {
368 match proxy_add_header_map_value(
369 map_type,
370 key.as_ptr(),
371 key.len(),
372 value.as_ptr(),
373 value.len(),
374 ) {
375 Status::Ok => Ok(()),
376 status => panic!("unexpected status: {}", status as u32),
377 }
378 }
379}
380
381pub fn add_map_value_bytes(map_type: MapType, key: &str, value: &[u8]) -> Result<(), Status> {
382 unsafe {
383 match proxy_add_header_map_value(
384 map_type,
385 key.as_ptr(),
386 key.len(),
387 value.as_ptr(),
388 value.len(),
389 ) {
390 Status::Ok => Ok(()),
391 status => panic!("unexpected status: {}", status as u32),
392 }
393 }
394}
395
396extern "C" {
397 fn proxy_get_property(
398 path_data: *const u8,
399 path_size: usize,
400 return_value_data: *mut *mut u8,
401 return_value_size: *mut usize,
402 ) -> Status;
403}
404
405pub fn get_property(path: Vec<&str>) -> Result<Option<Bytes>, Status> {
406 let serialized_path = utils::serialize_property_path(path);
407 let mut return_data: *mut u8 = null_mut();
408 let mut return_size: usize = 0;
409 unsafe {
410 match proxy_get_property(
411 serialized_path.as_ptr(),
412 serialized_path.len(),
413 &mut return_data,
414 &mut return_size,
415 ) {
416 Status::Ok => {
417 if !return_data.is_null() {
418 Ok(Some(Vec::from_raw_parts(
419 return_data,
420 return_size,
421 return_size,
422 )))
423 } else {
424 Ok(None)
425 }
426 }
427 Status::NotFound => Ok(None),
428 Status::SerializationFailure => Err(Status::SerializationFailure),
429 Status::InternalFailure => Err(Status::InternalFailure),
430 status => panic!("unexpected status: {}", status as u32),
431 }
432 }
433}
434
435extern "C" {
436 fn proxy_set_property(
437 path_data: *const u8,
438 path_size: usize,
439 value_data: *const u8,
440 value_size: usize,
441 ) -> Status;
442}
443
444pub fn set_property(path: Vec<&str>, value: Option<&[u8]>) -> Result<(), Status> {
445 let serialized_path = utils::serialize_property_path(path);
446 unsafe {
447 match proxy_set_property(
448 serialized_path.as_ptr(),
449 serialized_path.len(),
450 value.map_or(null(), |value| value.as_ptr()),
451 value.map_or(0, |value| value.len()),
452 ) {
453 Status::Ok => Ok(()),
454 status => panic!("unexpected status: {}", status as u32),
455 }
456 }
457}
458
459extern "C" {
460 fn proxy_get_shared_data(
461 key_data: *const u8,
462 key_size: usize,
463 return_value_data: *mut *mut u8,
464 return_value_size: *mut usize,
465 return_cas: *mut u32,
466 ) -> Status;
467}
468
469pub fn get_shared_data(key: &str) -> Result<(Option<Bytes>, Option<u32>), Status> {
470 let mut return_data: *mut u8 = null_mut();
471 let mut return_size: usize = 0;
472 let mut return_cas: u32 = 0;
473 unsafe {
474 match proxy_get_shared_data(
475 key.as_ptr(),
476 key.len(),
477 &mut return_data,
478 &mut return_size,
479 &mut return_cas,
480 ) {
481 Status::Ok => {
482 let cas = match return_cas {
483 0 => None,
484 cas => Some(cas),
485 };
486 if !return_data.is_null() {
487 Ok((
488 Some(Vec::from_raw_parts(return_data, return_size, return_size)),
489 cas,
490 ))
491 } else {
492 Ok((None, cas))
493 }
494 }
495 Status::NotFound => Ok((None, None)),
496 status => panic!("unexpected status: {}", status as u32),
497 }
498 }
499}
500
501extern "C" {
502 fn proxy_set_shared_data(
503 key_data: *const u8,
504 key_size: usize,
505 value_data: *const u8,
506 value_size: usize,
507 cas: u32,
508 ) -> Status;
509}
510
511pub fn set_shared_data(key: &str, value: Option<&[u8]>, cas: Option<u32>) -> Result<(), Status> {
512 unsafe {
513 match proxy_set_shared_data(
514 key.as_ptr(),
515 key.len(),
516 value.map_or(null(), |value| value.as_ptr()),
517 value.map_or(0, |value| value.len()),
518 cas.unwrap_or(0),
519 ) {
520 Status::Ok => Ok(()),
521 Status::CasMismatch => Err(Status::CasMismatch),
522 status => panic!("unexpected status: {}", status as u32),
523 }
524 }
525}
526
527extern "C" {
528 fn proxy_register_shared_queue(
529 name_data: *const u8,
530 name_size: usize,
531 return_id: *mut u32,
532 ) -> Status;
533}
534
535pub fn register_shared_queue(name: &str) -> Result<u32, Status> {
536 unsafe {
537 let mut return_id: u32 = 0;
538 match proxy_register_shared_queue(name.as_ptr(), name.len(), &mut return_id) {
539 Status::Ok => Ok(return_id),
540 status => panic!("unexpected status: {}", status as u32),
541 }
542 }
543}
544
545extern "C" {
546 fn proxy_resolve_shared_queue(
547 vm_id_data: *const u8,
548 vm_id_size: usize,
549 name_data: *const u8,
550 name_size: usize,
551 return_id: *mut u32,
552 ) -> Status;
553}
554
555pub fn resolve_shared_queue(vm_id: &str, name: &str) -> Result<Option<u32>, Status> {
556 let mut return_id: u32 = 0;
557 unsafe {
558 match proxy_resolve_shared_queue(
559 vm_id.as_ptr(),
560 vm_id.len(),
561 name.as_ptr(),
562 name.len(),
563 &mut return_id,
564 ) {
565 Status::Ok => Ok(Some(return_id)),
566 Status::NotFound => Ok(None),
567 status => panic!("unexpected status: {}", status as u32),
568 }
569 }
570}
571
572extern "C" {
573 fn proxy_dequeue_shared_queue(
574 queue_id: u32,
575 return_value_data: *mut *mut u8,
576 return_value_size: *mut usize,
577 ) -> Status;
578}
579
580pub fn dequeue_shared_queue(queue_id: u32) -> Result<Option<Bytes>, Status> {
581 let mut return_data: *mut u8 = null_mut();
582 let mut return_size: usize = 0;
583 unsafe {
584 match proxy_dequeue_shared_queue(queue_id, &mut return_data, &mut return_size) {
585 Status::Ok => {
586 if !return_data.is_null() {
587 Ok(Some(Vec::from_raw_parts(
588 return_data,
589 return_size,
590 return_size,
591 )))
592 } else {
593 Ok(None)
594 }
595 }
596 Status::Empty => Ok(None),
597 Status::NotFound => Err(Status::NotFound),
598 status => panic!("unexpected status: {}", status as u32),
599 }
600 }
601}
602
603extern "C" {
604 fn proxy_enqueue_shared_queue(
605 queue_id: u32,
606 value_data: *const u8,
607 value_size: usize,
608 ) -> Status;
609}
610
611pub fn enqueue_shared_queue(queue_id: u32, value: Option<&[u8]>) -> Result<(), Status> {
612 unsafe {
613 match proxy_enqueue_shared_queue(
614 queue_id,
615 value.map_or(null(), |value| value.as_ptr()),
616 value.map_or(0, |value| value.len()),
617 ) {
618 Status::Ok => Ok(()),
619 Status::NotFound => Err(Status::NotFound),
620 status => panic!("unexpected status: {}", status as u32),
621 }
622 }
623}
624
625extern "C" {
626 fn proxy_continue_stream(stream_type: StreamType) -> Status;
627}
628
629pub fn resume_downstream() -> Result<(), Status> {
630 unsafe {
631 match proxy_continue_stream(StreamType::Downstream) {
632 Status::Ok => Ok(()),
633 status => panic!("unexpected status: {}", status as u32),
634 }
635 }
636}
637
638pub fn resume_upstream() -> Result<(), Status> {
639 unsafe {
640 match proxy_continue_stream(StreamType::Upstream) {
641 Status::Ok => Ok(()),
642 status => panic!("unexpected status: {}", status as u32),
643 }
644 }
645}
646
647pub fn resume_http_request() -> Result<(), Status> {
648 unsafe {
649 match proxy_continue_stream(StreamType::HttpRequest) {
650 Status::Ok => Ok(()),
651 status => panic!("unexpected status: {}", status as u32),
652 }
653 }
654}
655
656pub fn resume_http_response() -> Result<(), Status> {
657 unsafe {
658 match proxy_continue_stream(StreamType::HttpResponse) {
659 Status::Ok => Ok(()),
660 status => panic!("unexpected status: {}", status as u32),
661 }
662 }
663}
664
665extern "C" {
666 fn proxy_close_stream(stream_type: StreamType) -> Status;
667}
668
669pub fn close_downstream() -> Result<(), Status> {
670 unsafe {
671 match proxy_close_stream(StreamType::Downstream) {
672 Status::Ok => Ok(()),
673 status => panic!("unexpected status: {}", status as u32),
674 }
675 }
676}
677pub fn close_upstream() -> Result<(), Status> {
678 unsafe {
679 match proxy_close_stream(StreamType::Upstream) {
680 Status::Ok => Ok(()),
681 status => panic!("unexpected status: {}", status as u32),
682 }
683 }
684}
685
686pub fn reset_http_request() -> Result<(), Status> {
687 unsafe {
688 match proxy_close_stream(StreamType::HttpRequest) {
689 Status::Ok => Ok(()),
690 status => panic!("unexpected status: {}", status as u32),
691 }
692 }
693}
694
695pub fn reset_http_response() -> Result<(), Status> {
696 unsafe {
697 match proxy_close_stream(StreamType::HttpResponse) {
698 Status::Ok => Ok(()),
699 status => panic!("unexpected status: {}", status as u32),
700 }
701 }
702}
703
704extern "C" {
705 fn proxy_send_local_response(
706 status_code: u32,
707 status_code_details_data: *const u8,
708 status_code_details_size: usize,
709 body_data: *const u8,
710 body_size: usize,
711 headers_data: *const u8,
712 headers_size: usize,
713 grpc_status: i32,
714 ) -> Status;
715}
716
717pub fn send_http_response(
718 status_code: u32,
719 headers: Vec<(&str, &str)>,
720 body: Option<&[u8]>,
721) -> Result<(), Status> {
722 let serialized_headers = utils::serialize_map(&headers);
723 unsafe {
724 match proxy_send_local_response(
725 status_code,
726 null(),
727 0,
728 body.map_or(null(), |body| body.as_ptr()),
729 body.map_or(0, |body| body.len()),
730 serialized_headers.as_ptr(),
731 serialized_headers.len(),
732 -1,
733 ) {
734 Status::Ok => Ok(()),
735 status => panic!("unexpected status: {}", status as u32),
736 }
737 }
738}
739
740pub fn send_grpc_response(
741 grpc_status: GrpcStatusCode,
742 grpc_status_message: Option<&str>,
743 custom_metadata: Vec<(&str, &[u8])>,
744) -> Result<(), Status> {
745 let serialized_custom_metadata = utils::serialize_map_bytes(&custom_metadata);
746 unsafe {
747 match proxy_send_local_response(
748 200,
749 null(),
750 0,
751 grpc_status_message.map_or(null(), |grpc_status_message| grpc_status_message.as_ptr()),
752 grpc_status_message.map_or(0, |grpc_status_message| grpc_status_message.len()),
753 serialized_custom_metadata.as_ptr(),
754 serialized_custom_metadata.len(),
755 grpc_status as i32,
756 ) {
757 Status::Ok => Ok(()),
758 status => panic!("unexpected status: {}", status as u32),
759 }
760 }
761}
762
763extern "C" {
764 fn proxy_http_call(
765 upstream_data: *const u8,
766 upstream_size: usize,
767 headers_data: *const u8,
768 headers_size: usize,
769 body_data: *const u8,
770 body_size: usize,
771 trailers_data: *const u8,
772 trailers_size: usize,
773 timeout: u32,
774 return_token: *mut u32,
775 ) -> Status;
776}
777
778pub fn dispatch_http_call(
779 upstream: &str,
780 headers: Vec<(&str, &str)>,
781 body: Option<&[u8]>,
782 trailers: Vec<(&str, &str)>,
783 timeout: Duration,
784) -> Result<u32, Status> {
785 let serialized_headers = utils::serialize_map(&headers);
786 let serialized_trailers = utils::serialize_map(&trailers);
787 let mut return_token: u32 = 0;
788 unsafe {
789 match proxy_http_call(
790 upstream.as_ptr(),
791 upstream.len(),
792 serialized_headers.as_ptr(),
793 serialized_headers.len(),
794 body.map_or(null(), |body| body.as_ptr()),
795 body.map_or(0, |body| body.len()),
796 serialized_trailers.as_ptr(),
797 serialized_trailers.len(),
798 timeout.as_millis() as u32,
799 &mut return_token,
800 ) {
801 Status::Ok => {
802 dispatcher::register_callout(return_token);
803 Ok(return_token)
804 }
805 Status::BadArgument => Err(Status::BadArgument),
806 Status::InternalFailure => Err(Status::InternalFailure),
807 status => panic!("unexpected status: {}", status as u32),
808 }
809 }
810}
811
812extern "C" {
813 fn proxy_grpc_call(
814 upstream_data: *const u8,
815 upstream_size: usize,
816 service_name_data: *const u8,
817 service_name_size: usize,
818 method_name_data: *const u8,
819 method_name_size: usize,
820 initial_metadata_data: *const u8,
821 initial_metadata_size: usize,
822 message_data_data: *const u8,
823 message_data_size: usize,
824 timeout: u32,
825 return_callout_id: *mut u32,
826 ) -> Status;
827}
828
829pub fn dispatch_grpc_call(
830 upstream_name: &str,
831 service_name: &str,
832 method_name: &str,
833 initial_metadata: Vec<(&str, &[u8])>,
834 message: Option<&[u8]>,
835 timeout: Duration,
836) -> Result<u32, Status> {
837 let mut return_callout_id = 0;
838 let serialized_initial_metadata = utils::serialize_map_bytes(&initial_metadata);
839 unsafe {
840 match proxy_grpc_call(
841 upstream_name.as_ptr(),
842 upstream_name.len(),
843 service_name.as_ptr(),
844 service_name.len(),
845 method_name.as_ptr(),
846 method_name.len(),
847 serialized_initial_metadata.as_ptr(),
848 serialized_initial_metadata.len(),
849 message.map_or(null(), |message| message.as_ptr()),
850 message.map_or(0, |message| message.len()),
851 timeout.as_millis() as u32,
852 &mut return_callout_id,
853 ) {
854 Status::Ok => {
855 dispatcher::register_grpc_callout(return_callout_id);
856 Ok(return_callout_id)
857 }
858 Status::ParseFailure => Err(Status::ParseFailure),
859 Status::InternalFailure => Err(Status::InternalFailure),
860 status => panic!("unexpected status: {}", status as u32),
861 }
862 }
863}
864
865extern "C" {
866 fn proxy_grpc_stream(
867 upstream_data: *const u8,
868 upstream_size: usize,
869 service_name_data: *const u8,
870 service_name_size: usize,
871 method_name_data: *const u8,
872 method_name_size: usize,
873 initial_metadata_data: *const u8,
874 initial_metadata_size: usize,
875 return_stream_id: *mut u32,
876 ) -> Status;
877}
878
879pub fn open_grpc_stream(
880 upstream_name: &str,
881 service_name: &str,
882 method_name: &str,
883 initial_metadata: Vec<(&str, &[u8])>,
884) -> Result<u32, Status> {
885 let mut return_stream_id = 0;
886 let serialized_initial_metadata = utils::serialize_map_bytes(&initial_metadata);
887 unsafe {
888 match proxy_grpc_stream(
889 upstream_name.as_ptr(),
890 upstream_name.len(),
891 service_name.as_ptr(),
892 service_name.len(),
893 method_name.as_ptr(),
894 method_name.len(),
895 serialized_initial_metadata.as_ptr(),
896 serialized_initial_metadata.len(),
897 &mut return_stream_id,
898 ) {
899 Status::Ok => {
900 dispatcher::register_grpc_stream(return_stream_id);
901 Ok(return_stream_id)
902 }
903 Status::ParseFailure => Err(Status::ParseFailure),
904 Status::InternalFailure => Err(Status::InternalFailure),
905 status => panic!("unexpected status: {}", status as u32),
906 }
907 }
908}
909
910extern "C" {
911 fn proxy_grpc_send(
912 token: u32,
913 message_ptr: *const u8,
914 message_len: usize,
915 end_stream: bool,
916 ) -> Status;
917}
918
919pub fn send_grpc_stream_message(
920 token: u32,
921 message: Option<&[u8]>,
922 end_stream: bool,
923) -> Result<(), Status> {
924 unsafe {
925 match proxy_grpc_send(
926 token,
927 message.map_or(null(), |message| message.as_ptr()),
928 message.map_or(0, |message| message.len()),
929 end_stream,
930 ) {
931 Status::Ok => Ok(()),
932 Status::BadArgument => Err(Status::BadArgument),
933 Status::NotFound => Err(Status::NotFound),
934 status => panic!("unexpected status: {}", status as u32),
935 }
936 }
937}
938
939extern "C" {
940 fn proxy_grpc_cancel(token_id: u32) -> Status;
941}
942
943pub fn cancel_grpc_call(token_id: u32) -> Result<(), Status> {
944 unsafe {
945 match proxy_grpc_cancel(token_id) {
946 Status::Ok => Ok(()),
947 Status::NotFound => Err(Status::NotFound),
948 status => panic!("unexpected status: {}", status as u32),
949 }
950 }
951}
952
953pub fn cancel_grpc_stream(token_id: u32) -> Result<(), Status> {
954 unsafe {
955 match proxy_grpc_cancel(token_id) {
956 Status::Ok => Ok(()),
957 Status::NotFound => Err(Status::NotFound),
958 status => panic!("unexpected status: {}", status as u32),
959 }
960 }
961}
962
963extern "C" {
964 fn proxy_grpc_close(token_id: u32) -> Status;
965}
966
967pub fn close_grpc_stream(token_id: u32) -> Result<(), Status> {
968 unsafe {
969 match proxy_grpc_close(token_id) {
970 Status::Ok => Ok(()),
971 Status::NotFound => Err(Status::NotFound),
972 status => panic!("unexpected status: {}", status as u32),
973 }
974 }
975}
976
977extern "C" {
978 fn proxy_get_status(
979 return_code: *mut u32,
980 return_message_data: *mut *mut u8,
981 return_message_size: *mut usize,
982 ) -> Status;
983}
984
985pub fn get_grpc_status() -> Result<(u32, Option<String>), Status> {
986 let mut return_code: u32 = 0;
987 let mut return_data: *mut u8 = null_mut();
988 let mut return_size: usize = 0;
989 unsafe {
990 match proxy_get_status(&mut return_code, &mut return_data, &mut return_size) {
991 Status::Ok => {
992 if !return_data.is_null() {
993 Ok((
994 return_code,
995 Some(
996 String::from_utf8(Vec::from_raw_parts(
997 return_data,
998 return_size,
999 return_size,
1000 ))
1001 .unwrap(),
1002 ),
1003 ))
1004 } else {
1005 Ok((return_code, None))
1006 }
1007 }
1008 status => panic!("unexpected status: {}", status as u32),
1009 }
1010 }
1011}
1012
1013extern "C" {
1014 fn proxy_set_effective_context(context_id: u32) -> Status;
1015}
1016
1017pub fn set_effective_context(context_id: u32) -> Result<(), Status> {
1018 unsafe {
1019 match proxy_set_effective_context(context_id) {
1020 Status::Ok => Ok(()),
1021 Status::BadArgument => Err(Status::BadArgument),
1022 status => panic!("unexpected status: {}", status as u32),
1023 }
1024 }
1025}
1026
1027extern "C" {
1028 fn proxy_call_foreign_function(
1029 function_name_data: *const u8,
1030 function_name_size: usize,
1031 arguments_data: *const u8,
1032 arguments_size: usize,
1033 results_data: *mut *mut u8,
1034 results_size: *mut usize,
1035 ) -> Status;
1036}
1037
1038pub fn call_foreign_function(
1039 function_name: &str,
1040 arguments: Option<&[u8]>,
1041) -> Result<Option<Bytes>, Status> {
1042 let mut return_data: *mut u8 = null_mut();
1043 let mut return_size: usize = 0;
1044 unsafe {
1045 match proxy_call_foreign_function(
1046 function_name.as_ptr(),
1047 function_name.len(),
1048 arguments.map_or(null(), |arguments| arguments.as_ptr()),
1049 arguments.map_or(0, |arguments| arguments.len()),
1050 &mut return_data,
1051 &mut return_size,
1052 ) {
1053 Status::Ok => {
1054 if !return_data.is_null() {
1055 Ok(Some(Vec::from_raw_parts(
1056 return_data,
1057 return_size,
1058 return_size,
1059 )))
1060 } else {
1061 Ok(None)
1062 }
1063 }
1064 Status::NotFound => Err(Status::NotFound),
1065 Status::BadArgument => Err(Status::BadArgument),
1066 Status::SerializationFailure => Err(Status::SerializationFailure),
1067 Status::InternalFailure => Err(Status::InternalFailure),
1068 status => panic!("unexpected status: {}", status as u32),
1069 }
1070 }
1071}
1072
1073extern "C" {
1074 fn proxy_done() -> Status;
1075}
1076
1077pub fn done() -> Result<(), Status> {
1078 unsafe {
1079 match proxy_done() {
1080 Status::Ok => Ok(()),
1081 status => panic!("unexpected status: {}", status as u32),
1082 }
1083 }
1084}
1085
1086extern "C" {
1087 fn proxy_define_metric(
1088 metric_type: MetricType,
1089 name_data: *const u8,
1090 name_size: usize,
1091 return_id: *mut u32,
1092 ) -> Status;
1093}
1094
1095pub fn define_metric(metric_type: MetricType, name: &str) -> Result<u32, Status> {
1096 let mut return_id: u32 = 0;
1097 unsafe {
1098 match proxy_define_metric(metric_type, name.as_ptr(), name.len(), &mut return_id) {
1099 Status::Ok => Ok(return_id),
1100 status => panic!("unexpected status: {}", status as u32),
1101 }
1102 }
1103}
1104
1105extern "C" {
1106 fn proxy_get_metric(metric_id: u32, return_value: *mut u64) -> Status;
1107}
1108
1109pub fn get_metric(metric_id: u32) -> Result<u64, Status> {
1110 let mut return_value: u64 = 0;
1111 unsafe {
1112 match proxy_get_metric(metric_id, &mut return_value) {
1113 Status::Ok => Ok(return_value),
1114 Status::NotFound => Err(Status::NotFound),
1115 Status::BadArgument => Err(Status::BadArgument),
1116 status => panic!("unexpected status: {}", status as u32),
1117 }
1118 }
1119}
1120
1121extern "C" {
1122 fn proxy_record_metric(metric_id: u32, value: u64) -> Status;
1123}
1124
1125pub fn record_metric(metric_id: u32, value: u64) -> Result<(), Status> {
1126 unsafe {
1127 match proxy_record_metric(metric_id, value) {
1128 Status::Ok => Ok(()),
1129 Status::NotFound => Err(Status::NotFound),
1130 status => panic!("unexpected status: {}", status as u32),
1131 }
1132 }
1133}
1134
1135extern "C" {
1136 fn proxy_increment_metric(metric_id: u32, offset: i64) -> Status;
1137}
1138
1139pub fn increment_metric(metric_id: u32, offset: i64) -> Result<(), Status> {
1140 unsafe {
1141 match proxy_increment_metric(metric_id, offset) {
1142 Status::Ok => Ok(()),
1143 Status::NotFound => Err(Status::NotFound),
1144 Status::BadArgument => Err(Status::BadArgument),
1145 status => panic!("unexpected status: {}", status as u32),
1146 }
1147 }
1148}
1149
1150mod utils {
1151 use crate::types::Bytes;
1152 use std::convert::TryFrom;
1153
1154 pub(super) fn serialize_property_path(path: Vec<&str>) -> Bytes {
1155 if path.is_empty() {
1156 return Vec::new();
1157 }
1158 let mut size: usize = 0;
1159 for part in &path {
1160 size += part.len() + 1;
1161 }
1162 let mut bytes: Bytes = Vec::with_capacity(size);
1163 for part in &path {
1164 bytes.extend_from_slice(part.as_bytes());
1165 bytes.push(0);
1166 }
1167 bytes.pop();
1168 bytes
1169 }
1170
1171 pub(super) fn serialize_map(map: &[(&str, &str)]) -> Bytes {
1172 let mut size: usize = 4;
1173 for (name, value) in map {
1174 size += name.len() + value.len() + 10;
1175 }
1176 let mut bytes: Bytes = Vec::with_capacity(size);
1177 bytes.extend_from_slice(&(map.len() as u32).to_le_bytes());
1178 for (name, value) in map {
1179 bytes.extend_from_slice(&(name.len() as u32).to_le_bytes());
1180 bytes.extend_from_slice(&(value.len() as u32).to_le_bytes());
1181 }
1182 for (name, value) in map {
1183 bytes.extend_from_slice(name.as_bytes());
1184 bytes.push(0);
1185 bytes.extend_from_slice(value.as_bytes());
1186 bytes.push(0);
1187 }
1188 bytes
1189 }
1190
1191 pub(super) fn serialize_map_bytes(map: &[(&str, &[u8])]) -> Bytes {
1192 let mut size: usize = 4;
1193 for (name, value) in map {
1194 size += name.len() + value.len() + 10;
1195 }
1196 let mut bytes: Bytes = Vec::with_capacity(size);
1197 bytes.extend_from_slice(&(map.len() as u32).to_le_bytes());
1198 for (name, value) in map {
1199 bytes.extend_from_slice(&(name.len() as u32).to_le_bytes());
1200 bytes.extend_from_slice(&(value.len() as u32).to_le_bytes());
1201 }
1202 for (name, value) in map {
1203 bytes.extend_from_slice(name.as_bytes());
1204 bytes.push(0);
1205 bytes.extend_from_slice(value);
1206 bytes.push(0);
1207 }
1208 bytes
1209 }
1210
1211 pub(super) fn deserialize_map(bytes: &[u8]) -> Vec<(String, String)> {
1212 if bytes.is_empty() {
1213 return Vec::new();
1214 }
1215 let size = u32::from_le_bytes(<[u8; 4]>::try_from(&bytes[0..4]).unwrap()) as usize;
1216 let mut map = Vec::with_capacity(size);
1217 let mut p = 4 + size * 8;
1218 for n in 0..size {
1219 let s = 4 + n * 8;
1220 let size = u32::from_le_bytes(<[u8; 4]>::try_from(&bytes[s..s + 4]).unwrap()) as usize;
1221 let key = bytes[p..p + size].to_vec();
1222 p += size + 1;
1223 let size =
1224 u32::from_le_bytes(<[u8; 4]>::try_from(&bytes[s + 4..s + 8]).unwrap()) as usize;
1225 let value = bytes[p..p + size].to_vec();
1226 p += size + 1;
1227 map.push((
1228 String::from_utf8(key).unwrap(),
1229 String::from_utf8(value).unwrap(),
1230 ));
1231 }
1232 map
1233 }
1234
1235 pub(super) fn deserialize_map_bytes(bytes: &[u8]) -> Vec<(String, Bytes)> {
1236 if bytes.is_empty() {
1237 return Vec::new();
1238 }
1239 let size = u32::from_le_bytes(<[u8; 4]>::try_from(&bytes[0..4]).unwrap()) as usize;
1240 let mut map = Vec::with_capacity(size);
1241 let mut p = 4 + size * 8;
1242 for n in 0..size {
1243 let s = 4 + n * 8;
1244 let size = u32::from_le_bytes(<[u8; 4]>::try_from(&bytes[s..s + 4]).unwrap()) as usize;
1245 let key = bytes[p..p + size].to_vec();
1246 p += size + 1;
1247 let size =
1248 u32::from_le_bytes(<[u8; 4]>::try_from(&bytes[s + 4..s + 8]).unwrap()) as usize;
1249 let value = bytes[p..p + size].to_vec();
1250 p += size + 1;
1251 map.push((String::from_utf8(key).unwrap(), value));
1252 }
1253 map
1254 }
1255
1256 #[cfg(test)]
1257 mod tests {
1258 use super::*;
1259
1260 #[cfg(nightly)]
1261 use test::Bencher;
1262
1263 static MAP: &[(&str, &str)] = &[
1264 (":method", "GET"),
1265 (":path", "/bytes/1"),
1266 (":authority", "httpbin.org"),
1267 ("Powered-By", "proxy-wasm"),
1268 ];
1269
1270 #[rustfmt::skip]
1271 static SERIALIZED_MAP: &[u8] = &[
1272 4, 0, 0, 0,
1274 7, 0, 0, 0, 3, 0, 0, 0,
1276 5, 0, 0, 0, 8, 0, 0, 0,
1278 10, 0, 0, 0, 11, 0, 0, 0,
1280 10, 0, 0, 0, 10, 0, 0, 0,
1282 58, 109, 101, 116, 104, 111, 100, 0,
1284 71, 69, 84, 0,
1286 58, 112, 97, 116, 104, 0,
1288 47, 98, 121, 116, 101, 115, 47, 49, 0,
1290 58, 97, 117, 116, 104, 111, 114, 105, 116, 121, 0,
1292 104, 116, 116, 112, 98, 105, 110, 46, 111, 114, 103, 0,
1294 80, 111, 119, 101, 114, 101, 100, 45, 66, 121, 0,
1296 112, 114, 111, 120, 121, 45, 119, 97, 115, 109, 0,
1298 ];
1299
1300 #[test]
1301 fn test_serialize_map_empty() {
1302 let serialized_map = serialize_map(&[]);
1303 assert_eq!(serialized_map, [0, 0, 0, 0]);
1304 }
1305
1306 #[test]
1307 fn test_serialize_map_empty_bytes() {
1308 let serialized_map = serialize_map_bytes(&[]);
1309 assert_eq!(serialized_map, [0, 0, 0, 0]);
1310 }
1311
1312 #[test]
1313 fn test_deserialize_map_empty() {
1314 let map = deserialize_map(&[]);
1315 assert_eq!(map, []);
1316 let map = deserialize_map(&[0, 0, 0, 0]);
1317 assert_eq!(map, []);
1318 }
1319
1320 #[test]
1321 fn test_deserialize_map_empty_bytes() {
1322 let map = deserialize_map_bytes(&[]);
1323 assert_eq!(map, []);
1324 let map = deserialize_map_bytes(&[0, 0, 0, 0]);
1325 assert_eq!(map, []);
1326 }
1327
1328 #[test]
1329 fn test_serialize_map() {
1330 let serialized_map = serialize_map(MAP);
1331 assert_eq!(serialized_map, SERIALIZED_MAP);
1332 }
1333
1334 #[test]
1335 fn test_serialize_map_bytes() {
1336 let map: Vec<(&str, &[u8])> = MAP.iter().map(|x| (x.0, x.1.as_bytes())).collect();
1337 let serialized_map = serialize_map_bytes(&map);
1338 assert_eq!(serialized_map, SERIALIZED_MAP);
1339 }
1340
1341 #[test]
1342 fn test_deserialize_map() {
1343 let map = deserialize_map(SERIALIZED_MAP);
1344 assert_eq!(map.len(), MAP.len());
1345 for (got, expected) in map.into_iter().zip(MAP) {
1346 assert_eq!(got.0, expected.0);
1347 assert_eq!(got.1, expected.1);
1348 }
1349 }
1350
1351 #[test]
1352 fn test_deserialize_map_bytes() {
1353 let map = deserialize_map_bytes(SERIALIZED_MAP);
1354 assert_eq!(map.len(), MAP.len());
1355 for (got, expected) in map.into_iter().zip(MAP) {
1356 assert_eq!(got.0, expected.0);
1357 assert_eq!(got.1, expected.1.as_bytes());
1358 }
1359 }
1360
1361 #[test]
1362 fn test_deserialize_map_roundtrip() {
1363 let map = deserialize_map(SERIALIZED_MAP);
1364 let map_refs: Vec<(&str, &str)> =
1366 map.iter().map(|x| (x.0.as_ref(), x.1.as_ref())).collect();
1367 let serialized_map = serialize_map(&map_refs);
1368 assert_eq!(serialized_map, SERIALIZED_MAP);
1369 }
1370
1371 #[test]
1372 fn test_deserialize_map_roundtrip_bytes() {
1373 let map = deserialize_map_bytes(SERIALIZED_MAP);
1374 let map_refs: Vec<(&str, &[u8])> =
1376 map.iter().map(|x| (x.0.as_ref(), x.1.as_ref())).collect();
1377 let serialized_map = serialize_map_bytes(&map_refs);
1378 assert_eq!(serialized_map, SERIALIZED_MAP);
1379 }
1380
1381 #[test]
1382 fn test_deserialize_map_all_chars() {
1383 for i in 0..0x7f {
1385 let serialized_src = [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 99, 0, i, 0];
1386 let map = deserialize_map(&serialized_src);
1387 let map_refs: Vec<(&str, &str)> =
1389 map.iter().map(|x| (x.0.as_ref(), x.1.as_ref())).collect();
1390 let serialized_map = serialize_map(&map_refs);
1391 assert_eq!(serialized_map, serialized_src);
1392 }
1393 for i in 0x80..0xff {
1395 let serialized_src = [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 99, 0, i, 0];
1396 std::panic::set_hook(Box::new(|_| {}));
1397 let result = std::panic::catch_unwind(|| {
1398 deserialize_map(&serialized_src);
1399 });
1400 assert!(result.is_err());
1401 }
1402 }
1403
1404 #[test]
1405 fn test_deserialize_map_all_chars_bytes() {
1406 for i in 0..0xff {
1408 let serialized_src = [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 99, 0, i, 0];
1409 let map = deserialize_map_bytes(&serialized_src);
1410 let map_refs: Vec<(&str, &[u8])> =
1412 map.iter().map(|x| (x.0.as_ref(), x.1.as_ref())).collect();
1413 let serialized_map = serialize_map_bytes(&map_refs);
1414 assert_eq!(serialized_map, serialized_src);
1415 }
1416 }
1417
1418 #[cfg(nightly)]
1419 #[bench]
1420 fn bench_serialize_map(b: &mut Bencher) {
1421 let map = MAP.to_vec();
1422 b.iter(|| {
1423 serialize_map(test::black_box(&map));
1424 });
1425 }
1426
1427 #[cfg(nightly)]
1428 #[bench]
1429 fn bench_serialize_map_bytes(b: &mut Bencher) {
1430 let map: Vec<(&str, &[u8])> = MAP.iter().map(|x| (x.0, x.1.as_bytes())).collect();
1431 b.iter(|| {
1432 serialize_map_bytes(test::black_box(&map));
1433 });
1434 }
1435
1436 #[cfg(nightly)]
1437 #[bench]
1438 fn bench_deserialize_map(b: &mut Bencher) {
1439 let serialized_map = SERIALIZED_MAP.to_vec();
1440 b.iter(|| {
1441 deserialize_map(test::black_box(&serialized_map));
1442 });
1443 }
1444
1445 #[cfg(nightly)]
1446 #[bench]
1447 fn bench_deserialize_map_bytes(b: &mut Bencher) {
1448 let serialized_map = SERIALIZED_MAP.to_vec();
1449 b.iter(|| {
1450 deserialize_map_bytes(test::black_box(&serialized_map));
1451 });
1452 }
1453 }
1454}