I'm using Ktor client to make calls to an API and I didn't find any examples of how to construct a URL with query parameters.
I wanted something like this:
protocol = HTTPS,
host = api.server.com,
path = get/items,
queryParams = List(
Pair("since", "2020-07-17"),
)
I can't find any examples of how to use URL builder for this.
If you want to specify each of this element (protocol, host, path and params) separately you can use a HttpClient.request method to construct your url. Inside this method you have access to HttpRequestBuilder and then you can configure url with usage of UrlBuilder
client.request<Response> {
url {
protocol = URLProtocol.HTTPS
host = "api.server.com"
path("get", "items")
parameters.append("since", "2020-07-17")
}
}
Response type is your response, you can specify there whatever you need
It would also be helpful if someone wants to add a base URL to all their requests :
HttpClient(Android) {
expectSuccess = false
//config Client Serialization
install(JsonFeature) {
serializer = KotlinxSerializer(json)
}
//config client logging
install(Logging) {
level = LogLevel.BODY
}
//Config timeout
install(HttpTimeout) {
requestTimeoutMillis = 30 * 1000L
connectTimeoutMillis = 10 * 1000L
}
//Config Base Url
defaultRequest {
url {
protocol =URLProtocol.HTTPS
host = baseUrl
}
}
}
val json = kotlinx.serialization.json.Json {
ignoreUnknownKeys = true
isLenient = true
encodeDefaults = false
}
Related
I'm facing some issues while dealing with certificates in terraform.
Before writing the code below, i've already made a CSR request.
I need to say that certificate_pem and private_key are both encoded in base64, particularly private_key is encrypted.
In the code below, i would like to use private_key and certificate_pem.
resource "kubernetes_secret" "my-secret" {
data = {
"tls.crt" = data.my_data.my-configuration-secret.data["certificate_pem"]
"tls.key" = data.my_data.my-configuration-secret.data["private_key"]
}
metadata {
name = "my-secret"
namespace = "my-namespace"
}
}
Now, in the Ingress ressource, i use this secret name
resource "kubernetes_ingress" "my-sni" {
metadata {
name = "my-sni"
namespace = "my_namespace"
annotations = {
"kubernetes.io/ingress.class" = "my_namespace"
"kubernetes.io/ingress.allow-http" = "true"
"nginx.ingress.kubernetes.io/ssl-redirect" = "false"
"nginx.ingress.kubernetes.io/force-ssl-redirect" = "false"
"nginx.ingress.kubernetes.io/ssl-passthrough" = "false"
"nginx.ingress.kubernetes.io/secure-backends" = "false"
"nginx.ingress.kubernetes.io/proxy-body-size" = "0"
"nginx.ingress.kubernetes.io/proxy-read-timeout" = "3600000"
"nginx.ingress.kubernetes.io/rewrite-target" = "/$1"
"nginx.ingress.kubernetes.io/proxy-send-timeout" = "400000"
"nginx.ingress.kubernetes.io/backend-protocol" = "HTTP"
}
}
spec {
tls {
hosts = ["my_host"]
secret_name = "my-secret"
}
rule {
host = "my_host"
http {
path {
path = "/?(.*)"
backend {
service_name = "my-service"
service_port = 8080
}
}
}
}
}
}
Everything is fine with terraform apply, but i can't go on the host to check if i can access to the microservice.
Someone told me i've to uncypher the private_key.
I don't know how to do that
reqres.feature
Feature: Reqres api test cases
Background: base url
Given url base_url
* def validateResponse = read('classpath:helpers/common_assertions.js')
Scenario: list single user get request
Given path single_user_path
When method get
Then status 200
* validateResponse()
common_assertion.js
function common_assertions() {
var contentType = karate.get("responseHeaders['Content-Type'][0]");
if (contentType !== 'application/json; charset=utf-8') {
karate.fail('content type is not json');
}
var responseType = karate.get('responseType');
if (responseType !== 'json') {
karate.fail('response type is not json');
}
var responseTime = karate.get('responseTime');
if (responseTime > 5000) {
karate.fail('response is too slow');
}
}
karate-config.js
function fn() {
var env = karate.env; // get system property 'karate.env'
karate.log('karate.env system property was:', env);
if (!env) {
env = 'dev';
}
var config = {
base_url: 'https://reqres.in/api',
single_user_path: '/users/2'
};
if (env == 'dev') {
// customize
// e.g. config.foo = 'bar';
} else if (env == 'e2e') {
// customize
}
return config;
}
I would like to use common_assertions.js file in karate-config.js file rather than using in the background section so that i can reuse * validateResponse() method across all feature files. Is there a way?Please help
The code I use currently on my website
var client = null;
var device_is_on = null;
var hostname = "********";
var port = "8003";
var clientId = "mqtt_js_" + parseInt(Math.random() * 100000, 10);
var device_topic = "stat/Device_001/POWER";
var status_topic = "cmnd/Device_001/power";
function connect(){
client = new Paho.MQTT.Client(hostname, Number(port), clientId);
client.onConnectionLost = onConnectionLost;
client.onMessageArrived = onMessageArrived;
var options = {
useSSL: true,
userName : "***",
password : "********",
onSuccess: onConnect,
onFailure: onFail
};
client.connect(options);
}
function onConnect(context) {
options = {qos:0}
client.subscribe(device_topic, options);
client.subscribe(status_topic, options);
var payloadd = "6";
message = new Paho.MQTT.Message(payloadd);
message.destinationName = status_topic;
message.retained = true;
client.send(message);
}
function onFail(context) {
}
function onConnectionLost(responseObject) {
if (responseObject.errorCode !== 0) {
window.alert("Connection Lost!\nPlease Refresh.");
}
}
function onMessageArrived(message) {
if (message.destinationName == device_topic){
var temperature_heading = document.getElementById("device_display");
temperature_heading.innerHTML = "Air Conditioner: " + message.payloadString;
if (message.payloadString == "ON" || message.payloadString == "o"){
device_is_on = true;
} else {
device_is_on = false;
}
}
}
function device_toggle(){
if (device_is_on){
var payload = "off";
device_is_on = false;
} else {
var payload = "on";
device_is_on = true;
}
message = new Paho.MQTT.Message(payload);
message.destinationName = status_topic;
message.retained = true;
client.send(message);
}
What should I put under the "" var options "" section? currently I am getting the error ERR_CERT_AUTHORITY_INVALID in the console of Google Chrome.
Note 1: This code functions perfectly over http but I am converting to https.
Note 2: I use Mosquitto as my MQTT broker.
Help in much appreciated.
It looks like you are using a self signed certificate. This will not be trusted by your browser so it will not connect, raising the error you have shown.
You have 2 options:
Import the certificate into your browser and mark it as trusted (how you do this will vary depending on what browser you are using). This is only really useful for testing/development because normal users should not be importing random certificates as this opens them up to all kinds of security problems.
Get a real trusted certificate for your website and broker. The simplest/cheapest way to do this will be to use letsencrypt. You can then configure mosquitto to use this certificate.
TLS javascript paho client is available: Github paho.mqtt.javascript/issues/88
I've used IdentityServer4 with asp net core Web, all works fine when debug in localhost:50481, but when I use myipaddress:50481 on the same computer and debug mode, it failed. I do not use a temporary credential, instead, I created a RSA cert:
.AddSigningCredential(Config.GetSigningCertificate())
public static RsaSecurityKey GetSigningCertificate()
{
var filename = Path.Combine(Directory.GetCurrentDirectory(), "certificateKey.rsa");
if (File.Exists(filename))
{
var keyFile = File.ReadAllText(filename);
var tempKey = JsonConvert.DeserializeObject<TemporaryRsaKey>(keyFile, new JsonSerializerSettings() { ContractResolver = new RsaKeyContractResolver() });
return CreateRsaSecurityKey(tempKey.Parameters, tempKey.KeyId);
}
else
{
var key = CreateRsaSecurityKey();
RSAParameters parameters;
if (key.Rsa != null)
parameters = key.Rsa.ExportParameters(includePrivateParameters: true);
else
parameters = key.Parameters;
var tempKey = new TemporaryRsaKey
{
Parameters = parameters,
KeyId = key.KeyId
};
File.WriteAllText(filename, JsonConvert.SerializeObject(tempKey, new JsonSerializerSettings() { ContractResolver = new RsaKeyContractResolver() }));
return CreateRsaSecurityKey(tempKey.Parameters, tempKey.KeyId);
}
}
I also checked the jwks of localhost and ipaddress, they are matched.
When I publish the project to local IIS, localhost does not work too, present a 500 Internal error.
all the url in my app is "http://localhost:50481"
I have to say this is a stupid mistake, I have not notice the authConfig,
let config;
if (window.location.hostname === 'localhost') {
config = configForDevelopment;
} else {
config = configForProduction;
}
when I use ip address, the config is switch to prod, change localhost to my ip address make sense.
hope it could others.
I'm attempting to upload a file from PhoneGap to a server using the FileTransfer method. I need HTTP basic auth to be enabled for this upload.
Here's the relevant code:
var options = new FileUploadOptions({
fileKey: "file",
params: {
id: my_id,
headers: { 'Authorization': _make_authstr() }
}
});
var ft = new FileTransfer();
ft.upload(image, 'http://locahost:8000/api/upload', success, error, options);
Looking over the PhoneGap source code it appears that I can specify the authorization header by including "headers" in the "params" list as I've done above:
JSONObject headers = params.getJSONObject("headers");
for (Iterator iter = headers.keys(); iter.hasNext();)
{
String headerKey = iter.next().toString();
conn.setRequestProperty(headerKey, headers.getString(headerKey));
}
However, this doesn't seem to actually add the header.
So: is there a way to do HTTP basic auth with PhoneGap's FileTransfer, for both iPhone and Android?
You can add custom headers by adding them to the options rather than the params like so:
authHeaderValue = function(username, password) {
var tok = username + ':' + password;
var hash = btoa(tok);
return "Basic " + hash;
};
options.headers = {'Authorization': authHeaderValue('Bob', '1234') };
The correct location for the headers array is as an immediate child of options. options->headers. Not options->params->headers. Here is an example:
//**************************************************************
//Variables used below:
//1 - image_name: contains the actual name of the image file.
//2 - token: contains authorization token. In my case, JWT.
//3 - UPLOAD_URL: URL to which the file will be uploaded.
//4 - image_full_path - Full path for the picture to be uploaded.
//***************************************************************
var options = {
fileKey: "file",
fileName: 'picture',
chunkedMode: false,
mimeType: "multipart/form-data",
params : {'fileName': image_name}
};
var headers = {'Authorization':token};
//Here is the magic!
options.headers = headers;
//NOTE: I creaed a separate object for headers to better exemplify what
// is going on here. Obviously you can simply add the header entry
// directly to options object above.
$cordovaFileTransfer.upload(UPLOAD_URL, image_full_path, options).then(
function(result) {
//do whatever with the result here.
});
Here is the official documentation: https://github.com/apache/cordova-plugin-file-transfer
You can create a authorization header yourself. But you can also enter the credentials in the url like this:
var username = "test", password = "pass";
var uri = encodeURI("http://"+username + ':' + password +"#localhost:8000/api/upload");
See FileTransfer.js for the implementation (line 45):
function getBasicAuthHeader(urlString) {
var header = null;
// This is changed due to MS Windows doesn't support credentials in http uris
// so we detect them by regexp and strip off from result url
// Proof: http://social.msdn.microsoft.com/Forums/windowsapps/en-US/a327cf3c-f033-4a54-8b7f-03c56ba3203f/windows-foundation-uri-security-problem
if (window.btoa) {
var credentials = getUrlCredentials(urlString);
if (credentials) {
var authHeader = "Authorization";
var authHeaderValue = "Basic " + window.btoa(credentials);
header = {
name : authHeader,
value : authHeaderValue
};
}
}
return header;
}