Skip to content

Commit d88fc26

Browse files
Add support for getting query_params from requests.
1 parent 780499b commit d88fc26

File tree

5 files changed

+86
-1
lines changed

5 files changed

+86
-1
lines changed

Cargo.lock

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/hyper_ruby/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,4 @@ h2 = "0.4"
2525
async-stream = "0.3.5"
2626
env_logger = "0.11"
2727
log = "0.4"
28+
form_urlencoded = "1.2.1"

ext/hyper_ruby/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,8 @@ fn init(ruby: &Ruby) -> Result<(), MagnusError> {
593593
let request_class = module.define_class("Request", ruby.class_object())?;
594594
request_class.define_method("http_method", method!(Request::method, 0))?;
595595
request_class.define_method("path", method!(Request::path, 0))?;
596+
request_class.define_method("query_params", method!(Request::query_params, 0))?;
597+
request_class.define_method("query_param", method!(Request::query_param, 1))?;
596598
request_class.define_method("header", method!(Request::header, 1))?;
597599
request_class.define_method("headers", method!(Request::headers, 0))?;
598600
request_class.define_method("body", method!(Request::body, 0))?;

ext/hyper_ruby/src/request.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use rb_sys::{rb_str_set_len, rb_str_modify, rb_str_modify_expand, rb_str_capacit
99

1010
use crate::grpc;
1111
use log::debug;
12+
use form_urlencoded;
1213

1314
// Trait for common buffer filling behavior
1415
trait FillBuffer {
@@ -104,6 +105,28 @@ impl Request {
104105
RString::new(self.request.uri().path())
105106
}
106107

108+
pub fn query_params(&self) -> RHash {
109+
let params = RHash::new();
110+
if let Some(query) = self.request.uri().query() {
111+
for (key, value) in form_urlencoded::parse(query.as_bytes()) {
112+
params.aset(key.to_string(), value.to_string()).unwrap();
113+
}
114+
}
115+
params
116+
}
117+
118+
pub fn query_param(&self, key: RString) -> Value {
119+
let key_str = unsafe { key.as_str().unwrap() };
120+
if let Some(query) = self.request.uri().query() {
121+
for (param_key, value) in form_urlencoded::parse(query.as_bytes()) {
122+
if param_key == key_str {
123+
return RString::new(&value).as_value();
124+
}
125+
}
126+
}
127+
qnil().as_value()
128+
}
129+
107130
pub fn header(&self, key: RString) -> Value {
108131
let key_str = unsafe { key.as_str().unwrap() };
109132
match self.request.headers().get(key_str) {
@@ -142,8 +165,11 @@ impl Request {
142165
pub fn inspect(&self) -> RString {
143166
let method = self.request.method().to_string();
144167
let path = self.request.uri().path();
168+
let query = self.request.uri().query().unwrap_or("");
169+
let query_display = if !query.is_empty() { format!("?{}", query) } else { String::new() };
145170
let body_size = self.body_size();
146-
RString::new(&format!("#<HyperRuby::Request method={} path={} body_size={}>", method, path, body_size))
171+
RString::new(&format!("#<HyperRuby::Request method={} path={}{} body_size={}>",
172+
method, path, query_display, body_size))
147173
}
148174
}
149175

test/test_http.rb

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,32 @@ def test_unix_socket_directory_error
215215
end
216216
end
217217

218+
def test_query_params
219+
with_server(-> (request) { handler_query_params(request) }) do |client|
220+
response = client.get("/?name=John&age=30&verified")
221+
assert_equal 200, response.status
222+
223+
data = JSON.parse(response.body)
224+
assert_equal "John", data["query_params"]["name"]
225+
assert_equal "30", data["query_params"]["age"]
226+
assert_equal "", data["query_params"]["verified"]
227+
228+
assert_equal "John", data["query_param_name"]
229+
assert_nil data["query_param_missing"]
230+
end
231+
end
232+
233+
def test_query_params_with_encoding
234+
with_server(-> (request) { handler_query_params(request) }) do |client|
235+
response = client.get("/?q=hello%20world&filter=type%3Duser")
236+
assert_equal 200, response.status
237+
238+
data = JSON.parse(response.body)
239+
assert_equal "hello world", data["query_params"]["q"]
240+
assert_equal "type=user", data["query_params"]["filter"]
241+
end
242+
end
243+
218244
private
219245

220246
def handler_simple(request)
@@ -242,4 +268,18 @@ def handler_accept(request, buffer)
242268
request.fill_body(buffer)
243269
ACCEPT_RESPONSE
244270
end
271+
272+
def handler_query_params(request)
273+
response_data = {
274+
query_params: request.query_params,
275+
query_param_name: request.query_param("name"),
276+
query_param_missing: request.query_param("missing")
277+
}
278+
279+
HyperRuby::Response.new(
280+
200,
281+
{ 'Content-Type' => 'application/json' },
282+
JSON.generate(response_data)
283+
)
284+
end
245285
end

0 commit comments

Comments
 (0)