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