| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* GATE PROJECT LICENSE: | ||
| 2 | +----------------------------------------------------------------------------+ | ||
| 3 | | Copyright(c) 2018-2025, Stefan Meislinger | | ||
| 4 | | All rights reserved. | | ||
| 5 | | | | ||
| 6 | | Redistribution and use in source and binary forms, with or without | | ||
| 7 | | modification, are permitted provided that the following conditions are met:| | ||
| 8 | | | | ||
| 9 | | 1. Redistributions of source code must retain the above copyright notice, | | ||
| 10 | | this list of conditions and the following disclaimer. | | ||
| 11 | | 2. Redistributions in binary form must reproduce the above copyright | | ||
| 12 | | notice, this list of conditions and the following disclaimer in the | | ||
| 13 | | documentation and/or other materials provided with the distribution. | | ||
| 14 | | | | ||
| 15 | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"| | ||
| 16 | | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | ||
| 17 | | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | ||
| 18 | | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | | ||
| 19 | | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | ||
| 20 | | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | ||
| 21 | | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | ||
| 22 | | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | ||
| 23 | | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | ||
| 24 | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | | ||
| 25 | | THE POSSIBILITY OF SUCH DAMAGE. | | ||
| 26 | +----------------------------------------------------------------------------+ | ||
| 27 | */ | ||
| 28 | |||
| 29 | #include "gate/tech/webapis.h" | ||
| 30 | #include "gate/results.h" | ||
| 31 | #include "gate/net/httpclients.h" | ||
| 32 | #include "gate/encode/json.h" | ||
| 33 | |||
| 34 | #define GATE_WEBAPIS_IPWHOIS_REQUEST_NAME GATE_STRUCT_WEBAPIS_NAME("ipwhois_request") | ||
| 35 | #define GATE_WEBAPIS_IPWHOIS_RESPONSE_NAME GATE_STRUCT_WEBAPIS_NAME("ipwhois_response") | ||
| 36 | |||
| 37 | |||
| 38 | static gate_struct_item_t const ipwhois_request_members[] = | ||
| 39 | { | ||
| 40 | GATE_STRUCT_ITEM_EX(gate_tech_webapi_ipwhois_request_t, GATE_TYPE_STRING, ip_address, "IP address", GATE_STRUCT_FLAG_DEFAULT) | ||
| 41 | }; | ||
| 42 | |||
| 43 | static gate_struct_descriptor_t const ipwhois_request_descriptor = | ||
| 44 | GATE_STRUCT_DESCRIPTOR(gate_tech_webapi_ipwhois_request_t, GATE_WEBAPIS_IPWHOIS_REQUEST_NAME, ipwhois_request_members); | ||
| 45 | |||
| 46 | 1 | GATE_TECH_API void gate_tech_webapi_ipwhois_request_init(gate_tech_webapi_ipwhois_request_t* request) | |
| 47 | { | ||
| 48 | 1 | gate_mem_clear(request, sizeof(gate_tech_webapi_ipwhois_request_t)); | |
| 49 | 1 | request->struct_base.struct_descriptor = &ipwhois_request_descriptor; | |
| 50 | 1 | } | |
| 51 | |||
| 52 | |||
| 53 | |||
| 54 | static gate_struct_item_t const ipwhois_response_members[] = | ||
| 55 | { | ||
| 56 | GATE_STRUCT_ITEM_EX(gate_tech_webapi_ipwhois_response_t, GATE_TYPE_STRING, ip_address, "IP address", GATE_STRUCT_FLAG_DEFAULT), | ||
| 57 | GATE_STRUCT_ITEM_EX(gate_tech_webapi_ipwhois_response_t, GATE_TYPE_STRING, range, "IP range", GATE_STRUCT_FLAG_DEFAULT), | ||
| 58 | |||
| 59 | GATE_STRUCT_ITEM_EX(gate_tech_webapi_ipwhois_response_t, GATE_TYPE_STRING, inet_org, "Organization", GATE_STRUCT_FLAG_DEFAULT), | ||
| 60 | GATE_STRUCT_ITEM_EX(gate_tech_webapi_ipwhois_response_t, GATE_TYPE_STRING, inet_netname,"Name", GATE_STRUCT_FLAG_DEFAULT), | ||
| 61 | GATE_STRUCT_ITEM_EX(gate_tech_webapi_ipwhois_response_t, GATE_TYPE_STRING, inet_descr, "Description", GATE_STRUCT_FLAG_DEFAULT), | ||
| 62 | GATE_STRUCT_ITEM_EX(gate_tech_webapi_ipwhois_response_t, GATE_TYPE_STRING, inet_country,"Country", GATE_STRUCT_FLAG_DEFAULT), | ||
| 63 | GATE_STRUCT_ITEM_EX(gate_tech_webapi_ipwhois_response_t, GATE_TYPE_TIME, inet_created, "Created", GATE_STRUCT_FLAG_DEFAULT), | ||
| 64 | GATE_STRUCT_ITEM_EX(gate_tech_webapi_ipwhois_response_t, GATE_TYPE_TIME, inet_modified, "Modified", GATE_STRUCT_FLAG_DEFAULT), | ||
| 65 | |||
| 66 | GATE_STRUCT_ITEM_EX(gate_tech_webapi_ipwhois_response_t, GATE_TYPE_STRING, org_name, "Org name", GATE_STRUCT_FLAG_DEFAULT), | ||
| 67 | GATE_STRUCT_ITEM_EX(gate_tech_webapi_ipwhois_response_t, GATE_TYPE_STRING, org_country, "Org country", GATE_STRUCT_FLAG_DEFAULT), | ||
| 68 | GATE_STRUCT_ITEM_EX(gate_tech_webapi_ipwhois_response_t, GATE_TYPE_STRING, org_type, "Org type", GATE_STRUCT_FLAG_DEFAULT), | ||
| 69 | GATE_STRUCT_ITEM_EX(gate_tech_webapi_ipwhois_response_t, GATE_TYPE_STRING, org_address, "Org address", GATE_STRUCT_FLAG_DEFAULT), | ||
| 70 | GATE_STRUCT_ITEM_EX(gate_tech_webapi_ipwhois_response_t, GATE_TYPE_STRING, org_phone, "Org phone", GATE_STRUCT_FLAG_DEFAULT), | ||
| 71 | GATE_STRUCT_ITEM_EX(gate_tech_webapi_ipwhois_response_t, GATE_TYPE_STRING, org_mail, "Org e-mail", GATE_STRUCT_FLAG_DEFAULT), | ||
| 72 | |||
| 73 | GATE_STRUCT_ITEM_EX(gate_tech_webapi_ipwhois_response_t, GATE_TYPE_STRING, role_name, "Role name", GATE_STRUCT_FLAG_DEFAULT), | ||
| 74 | GATE_STRUCT_ITEM_EX(gate_tech_webapi_ipwhois_response_t, GATE_TYPE_STRING, role_address,"Role address", GATE_STRUCT_FLAG_DEFAULT), | ||
| 75 | GATE_STRUCT_ITEM_EX(gate_tech_webapi_ipwhois_response_t, GATE_TYPE_STRING, role_mail, "Role mail", GATE_STRUCT_FLAG_DEFAULT), | ||
| 76 | GATE_STRUCT_ITEM_EX(gate_tech_webapi_ipwhois_response_t, GATE_TYPE_STRING, role_admin_c,"Role admin-c", GATE_STRUCT_FLAG_DEFAULT), | ||
| 77 | GATE_STRUCT_ITEM_EX(gate_tech_webapi_ipwhois_response_t, GATE_TYPE_STRING, role_tech_c, "Role tech-c", GATE_STRUCT_FLAG_DEFAULT), | ||
| 78 | |||
| 79 | GATE_STRUCT_ITEM_EX(gate_tech_webapi_ipwhois_response_t, GATE_TYPE_STRING, route_name, "Route name", GATE_STRUCT_FLAG_DEFAULT), | ||
| 80 | GATE_STRUCT_ITEM_EX(gate_tech_webapi_ipwhois_response_t, GATE_TYPE_STRING, route_descr, "Route description", GATE_STRUCT_FLAG_DEFAULT) | ||
| 81 | }; | ||
| 82 | |||
| 83 | static gate_struct_descriptor_t const ipwhois_response_descriptor = | ||
| 84 | GATE_STRUCT_DESCRIPTOR(gate_tech_webapi_ipwhois_response_t, GATE_WEBAPIS_IPWHOIS_RESPONSE_NAME, ipwhois_response_members); | ||
| 85 | |||
| 86 | 1 | GATE_TECH_API void gate_tech_webapi_ipwhois_response_init(gate_tech_webapi_ipwhois_response_t* response) | |
| 87 | { | ||
| 88 | 1 | gate_mem_clear(response, sizeof(gate_tech_webapi_ipwhois_response_t)); | |
| 89 | 1 | response->struct_base.struct_descriptor = &ipwhois_response_descriptor; | |
| 90 | 1 | } | |
| 91 | |||
| 92 | |||
| 93 | 10 | static gate_size_t gate_tech_webapi_ipwhois_extract_attribute_values( | |
| 94 | gate_property_t const* prop_attributes, char const* name, gate_string_t* output) | ||
| 95 | { | ||
| 96 | static gate_string_t const attr_name = GATE_STRING_INIT_STATIC("name"); | ||
| 97 | static gate_string_t const attr_value = GATE_STRING_INIT_STATIC("value"); | ||
| 98 | 10 | gate_size_t ret = 0; | |
| 99 | 10 | gate_strbuilder_t builder = GATE_INIT_EMPTY; | |
| 100 | gate_size_t length; | ||
| 101 | gate_size_t index; | ||
| 102 | gate_property_t const* prop_entry; | ||
| 103 | gate_property_t const* prop_name; | ||
| 104 | gate_property_t const* prop_value; | ||
| 105 | 10 | gate_string_t value = GATE_STRING_INIT_EMPTY; | |
| 106 | gate_result_t result; | ||
| 107 | |||
| 108 | do | ||
| 109 | { | ||
| 110 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
|
10 | if (!gate_string_is_empty(output)) |
| 111 | { | ||
| 112 | // value already received | ||
| 113 | ✗ | break; | |
| 114 | } | ||
| 115 | |||
| 116 | 10 | gate_strbuilder_create(&builder, 0); | |
| 117 | |||
| 118 | 10 | length = gate_property_array_length(prop_attributes); | |
| 119 |
2/2✓ Branch 0 taken 225 times.
✓ Branch 1 taken 10 times.
|
235 | for (index = 0; index != length; ++index) |
| 120 | { | ||
| 121 | 225 | prop_entry = gate_property_array_get(prop_attributes, index); | |
| 122 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 225 times.
|
225 | if (!prop_entry) continue; |
| 123 | |||
| 124 | 225 | prop_name = gate_property_resolve_path(prop_entry, &attr_name); | |
| 125 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 225 times.
|
225 | if (!prop_name) continue; |
| 126 | 225 | prop_value = gate_property_resolve_path(prop_entry, &attr_value); | |
| 127 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 225 times.
|
225 | if (!prop_value) continue; |
| 128 | |||
| 129 |
2/2✓ Branch 1 taken 8 times.
✓ Branch 2 taken 217 times.
|
225 | if (gate_property_equals_str(prop_name, name)) |
| 130 | { | ||
| 131 | 8 | result = gate_property_get_string(prop_value, &value); | |
| 132 |
1/2✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
|
8 | if (GATE_SUCCEEDED(result)) |
| 133 | { | ||
| 134 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
|
8 | if (gate_strbuilder_length(&builder) > 0) |
| 135 | { | ||
| 136 | ✗ | gate_strbuilder_append_text(&builder, "\n", 1); | |
| 137 | } | ||
| 138 | 8 | gate_strbuilder_append_string(&builder, &value); | |
| 139 | 8 | gate_string_release(&value); | |
| 140 | 8 | ++ret; | |
| 141 | } | ||
| 142 | } | ||
| 143 | } | ||
| 144 | } while (0); | ||
| 145 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2 times.
|
10 | if (ret > 0) |
| 146 | { | ||
| 147 | 8 | gate_strbuilder_to_string(&builder, output); | |
| 148 | } | ||
| 149 | 10 | gate_strbuilder_release(&builder); | |
| 150 | 10 | return ret; | |
| 151 | } | ||
| 152 | |||
| 153 | 1 | GATE_TECH_API gate_result_t gate_tech_webapi_ipwhois(gate_tech_webapi_context_t* context, | |
| 154 | gate_tech_webapi_ipwhois_request_t* request, | ||
| 155 | gate_tech_webapi_ipwhois_response_t* response) | ||
| 156 | { | ||
| 157 | 1 | gate_result_t ret = GATE_RESULT_FAILED; | |
| 158 | static gate_string_t const server = GATE_STRING_INIT_STATIC("rest.db.ripe.net"); | ||
| 159 | static gate_uint16_t const port = GATE_HTTP_DEFAULT_HTTP_PORT; | ||
| 160 | static gate_string_t const attributes_subpath = GATE_STRING_INIT_STATIC("attributes.attribute"); | ||
| 161 | static gate_string_t const objects_subpath = GATE_STRING_INIT_STATIC("objects.object"); | ||
| 162 | char buffer[1024]; | ||
| 163 | 1 | gate_http_request_t http_request = GATE_INIT_EMPTY; | |
| 164 | 1 | gate_http_response_t http_response = GATE_INIT_EMPTY; | |
| 165 | 1 | gate_httpclient_t http_client = GATE_INIT_EMPTY; | |
| 166 | 1 | gate_strbuilder_t path_builder = GATE_INIT_EMPTY; | |
| 167 | 1 | gate_property_t prop = GATE_INIT_EMPTY; | |
| 168 | 1 | gate_property_t const* subprop = NULL; | |
| 169 | 1 | gate_property_t const* prop_item = NULL; | |
| 170 | 1 | gate_json_result_t json_result = GATE_INIT_EMPTY; | |
| 171 | gate_size_t length; | ||
| 172 | gate_size_t index; | ||
| 173 | gate_property_t const* ptr_prop; | ||
| 174 | gate_property_t const* ptr_attributes; | ||
| 175 | |||
| 176 | GATE_UNUSED_ARG(context); | ||
| 177 | |||
| 178 | do | ||
| 179 | { | ||
| 180 | 1 | gate_strbuilder_create_static(&path_builder, buffer, sizeof(buffer), 0); | |
| 181 | 1 | gate_strbuilder_append_cstr(&path_builder, "/search.json?query-string="); | |
| 182 | 1 | gate_strbuilder_append_string(&path_builder, &request->ip_address); | |
| 183 | |||
| 184 | 1 | ret = gate_http_request_init_str(&http_request, GATE_HTTP_METHOD_GET, gate_strbuilder_ptr(&path_builder, 0)); | |
| 185 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | GATE_BREAK_IF_FAILED(ret); |
| 186 | |||
| 187 | 1 | ret = gate_httpclient_create(&http_client, &server, port, 0); | |
| 188 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | GATE_BREAK_IF_FAILED(ret); |
| 189 | |||
| 190 | 1 | ret = gate_httpclient_send_request(&http_client, &http_request, &http_response); | |
| 191 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | GATE_BREAK_IF_FAILED(ret); |
| 192 | |||
| 193 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (http_response.status_code != 200) |
| 194 | { | ||
| 195 | ✗ | ret = GATE_RESULT_INVALIDSTATE; | |
| 196 | ✗ | break; | |
| 197 | } | ||
| 198 | |||
| 199 | 1 | ret = gate_json_parse(http_response.response_stream, &prop, &json_result); | |
| 200 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | GATE_BREAK_IF_FAILED(ret); |
| 201 | |||
| 202 | 1 | subprop = gate_property_resolve_path(&prop, &objects_subpath); | |
| 203 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (!subprop) |
| 204 | { | ||
| 205 | ✗ | ret = GATE_RESULT_INVALIDOUTPUT; | |
| 206 | ✗ | break; | |
| 207 | } | ||
| 208 | 1 | length = gate_property_array_length(subprop); | |
| 209 | |||
| 210 | 1 | ret = GATE_RESULT_OK; | |
| 211 | |||
| 212 | 1 | gate_string_duplicate(&response->ip_address, &request->ip_address); | |
| 213 | |||
| 214 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
|
3 | for (index = 0; index != length; ++index) |
| 215 | { | ||
| 216 | 2 | prop_item = gate_property_array_get(subprop, index); | |
| 217 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if (prop_item) |
| 218 | { | ||
| 219 | 2 | ptr_prop = gate_property_resolve_path_str(prop_item, "type"); | |
| 220 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
|
2 | if (gate_property_equals_str(ptr_prop, "inetnum")) |
| 221 | { | ||
| 222 | 1 | ptr_attributes = gate_property_resolve_path(prop_item, &attributes_subpath); | |
| 223 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (ptr_attributes) |
| 224 | { | ||
| 225 | 1 | gate_tech_webapi_ipwhois_extract_attribute_values(ptr_attributes, "inetnum", &response->range); | |
| 226 | 1 | gate_tech_webapi_ipwhois_extract_attribute_values(ptr_attributes, "org", &response->inet_org); | |
| 227 | 1 | gate_tech_webapi_ipwhois_extract_attribute_values(ptr_attributes, "netname", &response->inet_netname); | |
| 228 | 1 | gate_tech_webapi_ipwhois_extract_attribute_values(ptr_attributes, "descr", &response->inet_descr); | |
| 229 | 1 | gate_tech_webapi_ipwhois_extract_attribute_values(ptr_attributes, "country", &response->inet_country); | |
| 230 | //gate_tech_webapi_ipwhois_extract_attribute_values(ptr_attributes, "created", &response->inet_created); | ||
| 231 | //gate_tech_webapi_ipwhois_extract_attribute_values(ptr_attributes, "last-modified", &response->inet_modified); | ||
| 232 | } | ||
| 233 | } | ||
| 234 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | if (gate_property_equals_str(ptr_prop, "organisation")) |
| 235 | { | ||
| 236 | ✗ | ptr_attributes = gate_property_resolve_path(prop_item, &attributes_subpath); | |
| 237 | ✗ | if (ptr_attributes) | |
| 238 | { | ||
| 239 | ✗ | gate_tech_webapi_ipwhois_extract_attribute_values(ptr_attributes, "org-name", &response->org_name); | |
| 240 | ✗ | gate_tech_webapi_ipwhois_extract_attribute_values(ptr_attributes, "country", &response->org_country); | |
| 241 | ✗ | gate_tech_webapi_ipwhois_extract_attribute_values(ptr_attributes, "org-type", &response->org_type); | |
| 242 | ✗ | gate_tech_webapi_ipwhois_extract_attribute_values(ptr_attributes, "address", &response->org_address); | |
| 243 | ✗ | gate_tech_webapi_ipwhois_extract_attribute_values(ptr_attributes, "phone", &response->org_phone); | |
| 244 | ✗ | gate_tech_webapi_ipwhois_extract_attribute_values(ptr_attributes, "e-mail", &response->org_mail); | |
| 245 | } | ||
| 246 | } | ||
| 247 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | if (gate_property_equals_str(ptr_prop, "person")) |
| 248 | { | ||
| 249 | ✗ | ptr_attributes = gate_property_resolve_path(prop_item, &attributes_subpath); | |
| 250 | ✗ | if (ptr_attributes) | |
| 251 | { | ||
| 252 | ✗ | gate_tech_webapi_ipwhois_extract_attribute_values(ptr_attributes, "person", &response->org_name); | |
| 253 | ✗ | gate_tech_webapi_ipwhois_extract_attribute_values(ptr_attributes, "country", &response->org_country); | |
| 254 | ✗ | gate_tech_webapi_ipwhois_extract_attribute_values(ptr_attributes, "nic-hdl", &response->org_type); | |
| 255 | ✗ | gate_tech_webapi_ipwhois_extract_attribute_values(ptr_attributes, "address", &response->org_address); | |
| 256 | ✗ | gate_tech_webapi_ipwhois_extract_attribute_values(ptr_attributes, "phone", &response->org_phone); | |
| 257 | ✗ | gate_tech_webapi_ipwhois_extract_attribute_values(ptr_attributes, "e-mail", &response->org_mail); | |
| 258 | } | ||
| 259 | } | ||
| 260 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
|
2 | if (gate_property_equals_str(ptr_prop, "role")) |
| 261 | { | ||
| 262 | 1 | ptr_attributes = gate_property_resolve_path(prop_item, &attributes_subpath); | |
| 263 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (ptr_attributes) |
| 264 | { | ||
| 265 | 1 | gate_tech_webapi_ipwhois_extract_attribute_values(ptr_attributes, "role", &response->role_name); | |
| 266 | 1 | gate_tech_webapi_ipwhois_extract_attribute_values(ptr_attributes, "address", &response->role_address); | |
| 267 | 1 | gate_tech_webapi_ipwhois_extract_attribute_values(ptr_attributes, "e-mail", &response->role_mail); | |
| 268 | 1 | gate_tech_webapi_ipwhois_extract_attribute_values(ptr_attributes, "admin-c", &response->role_admin_c); | |
| 269 | 1 | gate_tech_webapi_ipwhois_extract_attribute_values(ptr_attributes, "tech-c", &response->role_tech_c); | |
| 270 | } | ||
| 271 | } | ||
| 272 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | if (gate_property_equals_str(ptr_prop, "route")) |
| 273 | { | ||
| 274 | ✗ | ptr_attributes = gate_property_resolve_path(prop_item, &attributes_subpath); | |
| 275 | ✗ | if (ptr_attributes) | |
| 276 | { | ||
| 277 | ✗ | gate_tech_webapi_ipwhois_extract_attribute_values(ptr_attributes, "route", &response->route_name); | |
| 278 | ✗ | gate_tech_webapi_ipwhois_extract_attribute_values(ptr_attributes, "descr", &response->route_descr); | |
| 279 | } | ||
| 280 | } | ||
| 281 | } | ||
| 282 | } | ||
| 283 | |||
| 284 | } while (0); | ||
| 285 | |||
| 286 | 1 | gate_property_destroy(&prop); | |
| 287 | 1 | gate_httpclient_release(&http_client); | |
| 288 | 1 | gate_strbuilder_release(&path_builder); | |
| 289 | 1 | gate_http_response_release(&http_response); | |
| 290 | 1 | gate_http_request_release(&http_request); | |
| 291 | |||
| 292 | 1 | return ret; | |
| 293 | } | ||
| 294 |