Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option to set default HTTP configuration globally #761

Open
na-- opened this issue Sep 11, 2018 · 7 comments
Open

Option to set default HTTP configuration globally #761

na-- opened this issue Sep 11, 2018 · 7 comments
Labels
evaluation needed proposal needs to be validated or tested before fully implementing it in k6 feature new-http issues that would require (or benefit from) a new HTTP API ux

Comments

@na--
Copy link
Member

na-- commented Sep 11, 2018

Currently users can specify the userAgent that would be used by k6 by default when it makes HTTP requests. I'd be useful if we can generalize that and allow users to specify the default value of any header they want globally. Use cases that I can think of:

  • custom headers that should be in every request (people have asked for this on slack)
  • Accept-Encoding and Accept-Language headers are pretty much the same for all requests, if you want your test to look like a browser. It might also make some sense to manually set the Connection header as well.
  • connected to the previous point, it would help with making the HAR converter produce much more readable scripts
  • we can optionally gently deprecate the --user-agent flag, suggesting instead the usage of --header User-Agent="my-custom-useragent-value", to avoid CLI interface clutter
@na--
Copy link
Member Author

na-- commented Nov 23, 2018

It seems worth it to also allow other request options (https://docs.k6.io/docs/params-k6http) to be specified globally. It'd be especially useful to be able add cookies or to change the global default timeout...

@na-- na-- changed the title Option to set default HTTP headers globally Option to set default HTTP configuration globally Nov 23, 2018
@marklagendijk
Copy link
Contributor

I agree that it would be useful to be able to set defaults for all (or most) request options.
Now I don't think that all of these would also need a cli option. For most it would be enough to be able to specify them in the script.

@na-- na-- added the evaluation needed proposal needs to be validated or tested before fully implementing it in k6 label Aug 27, 2019
@simskij
Copy link
Contributor

simskij commented Sep 28, 2020

Being able to set a global timeout would definitely be a good addition.

@na--
Copy link
Member Author

na-- commented Feb 19, 2021

#1865 is a request to be able to specify the Content-Type header globally, which I'll close in favor of this issue.

In general, it's not certain if we'll implement this issue at all. It's more likely we'll go for a whole new version of the HTTP API where you are able to create multiple HTTP clients, each with different default properties (headers, connection reuse and proxy settings, timeouts, etc.). We've delayed even writing an issue for that new and better HTTP API for probably close to 2 years now, due to the many other things that have had higher priority... 😞 So I can't give any ETAs, but it will happen eventually, we're slowly running out of more important things... 😅

It will probably be done as an xk6 (https://github.com/k6io/xk6) extension initially, and adopted in the k6 core when it's good enough and stable. If someone wants to take an early stab at it, here is some more info on how extensions are made: https://k6.io/blog/extending-k6-with-xk6

Until then, it's worth pointing out that we already have a pure JavaScript wrapper around k6/http that does some of the things described in this issue, hosted on https://jslib.k6.io/: https://jslib.k6.io/httpx/0.0.3/index.js

We haven't documented it well yet, and it's still a very early prototype, but the code is short enough to be understandable... You can create something like an HTTP client and set headers and tags that are applied to every HTTP request. We also always accept PRs at https://github.com/k6io/jslib.k6.io/ and https://k6.io/docs/ with improvements 😅

@sniku
Copy link
Collaborator

sniku commented Feb 19, 2021

I encountered the same problem during the implementation of the "functional.js" library for k6.

It's handy to be able to specify default headers, baseURL, tags and other parameters. I implemented a httpx wrapper around the built-in http library to accomplish this.
While I have not documented all the functionality, I think the code is self-explanatory, so anyone who finds this issue can consider using it.

import { test } from 'https://jslib.k6.io/functional/0.0.1/index.js';
import { Httpx } from 'https://jslib.k6.io/httpx/0.0.3/index.js';

import { randomIntBetween, randomItem } from "https://jslib.k6.io/k6-utils/1.0.0/index.js";

export let options = {
  thresholds: {
    'http_req_duration{name:PublicCrocs}': ['p(90)<200'],
    checks: [{threshold: 'rate == 1.00', abortOnFail: true}],
  },
};

const USERNAME = `user${randomIntBetween(1, 100000)}@example.com`;  // Set your own email;
const PASSWORD = 'superCroc2019';

let session = new Httpx({
    baseURL: 'https://test-api.k6.io', 
    headers: {
        'User-Agent': "My custom user agent",
        "Content-Type": 'application/x-www-form-urlencoded' // or 'MyDefaultContentType'
    },
    timeout: 20000 // 20s timeout.
});

export default function testSuite() {

  test(`Create a test user ${USERNAME}`, (t) => {

    let resp = session.post(`/user/register/`, {
      first_name: 'Crocodile',
      last_name: 'Owner',
      username: USERNAME,
      password: PASSWORD,
    });

    t.expect(resp.status).as("status").toEqual(201)
      .and(resp).toHaveValidJson();
  })

  &&

  test(`Authenticate the new user ${USERNAME}`, (t) => {

    let resp = session.post(`/auth/token/login/`, {
      username: USERNAME,
      password: PASSWORD
    });

    t.expect(resp.status).as("Auth status").toBeBetween(200, 204)
      .and(resp).toHaveValidJson()
      .and(resp.json('access')).as("auth token").toBeTruthy();

    let authToken = resp.json('access');
    // set the authorization header on the session for the subsequent requests.
    session.addHeader('Authorization', `Bearer ${authToken}`);

  })

  &&

  test('04. Create a new crocodile', (t) => {
    let payload = {
      name: `Croc Name`,
      sex: randomItem(["M", "F"]),
      date_of_birth: '2019-01-01',
    };

    let resp = session.post(`/my/crocodiles/`, payload);

    t.expect(resp.status).as("Croc creation status").toEqual(201)
      .and(resp).toHaveValidJson();
  })

}

Note, I'm defining an http client called session outside of the default function. All requests that use session, get default parameters defined in the constructor. Session parameters can also be updated in the default function.
See line

session.addHeader('Authorization', `Bearer ${authToken}`);

which adds a new default header to the existing session. Subsequent requests will get this header by default.

Note: both the functional.js and httpx.js libraries are in active development, so you may want to check https://jslib.k6.io/ to see if there are newer releases.

@testn
Copy link

testn commented Jun 1, 2022

Where are we with this?

imiric pushed a commit that referenced this issue Apr 13, 2023
imiric pushed a commit that referenced this issue Apr 21, 2023
* Add design document for the new HTTP API

* Add design details about Sockets, Client and other APIs

Also, move examples to their specific section.

* Slightly reword Go net/http section

* Add socket done blocking call to TCP example

* Update IPC example to match the network API

* Apply suggestions from Mihail

Co-authored-by: Mihail Stoykov <312246+mstoykov@users.noreply.github.com>

* Add introduction to Design section

* Reference Streams API issue

* Remove mention of replacing k6/http

* Suggest merging into k6 core as experimental earlier, remove phase 6

Resolves #2971 (comment)

* Add mockup for an Event system

This could be a way to address features like 2667 and 1716.

* Replace dial* functions with <protocol>.open()

Resolves #2971 (comment)

* Remove sleep from example

* Add note about the WIP state of the proposal

* Rework phase 1 section, prioritize #761

Addresses #2971 (comment)

* Add TLS and HTTP/2 examples, remove HTTP/3 example

This changes the way the HTTP client obtains the socket, following this
discussion[1]. Instead of passing one socket, a dial function can be set
to control how the client creates the socket.

The HTTP/3 example was removed since it's too early to determine that API.

[1]: #2971 (comment)

---------

Co-authored-by: Mihail Stoykov <312246+mstoykov@users.noreply.github.com>
@ppcano
Copy link
Contributor

ppcano commented Apr 15, 2024

custom headers that should be in every request

Some tests interact with different systems (domains), requiring distinct headers.

Perhaps, it is useful to also allow configuring "global" headers for each specific (sub)domains.

@olegbespalov olegbespalov removed their assignment Apr 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
evaluation needed proposal needs to be validated or tested before fully implementing it in k6 feature new-http issues that would require (or benefit from) a new HTTP API ux
Projects
None yet
Development

No branches or pull requests

7 participants