Newbie to k6, receiving 405 Not Allowed errors on POST requests

Hi, I just got into k6 and I’m stuck on trying to successfully complete a post request to a website with a login page. Here’s my code:

import http from 'k6/http';
import {check} from 'k6';

export default function () {
  const url = 'xxxxx';
  const payload = JSON.stringify({
    email: 'xxxxx',
    password: 'xxxxx',
  });

  const params = {
    headers: {
      'Content-Type': 'application/json',
    },
  };

 const res = http.post(url, payload, params);
  check(res, {
    'is status 200': (r) => r.status === 200,
    })
}

I’ve tried running a --http-debug=full and here’s the message I’ve gotten:

INFO[0000] Request:
POST xxxxxx HTTP/1.1
Host: xxxxxxx
User-Agent: k6/0.48.0 (https://k6.io/)
Content-Length: 60
Content-Type: application/json
Accept-Encoding: gzip

{"email":"xxxxx","password":"xxxxx"}  group= iter=0 request_id=3327b6e1-cf22-40fa-7198-11a073c5614c scenario=default source=http-debug vu=1
INFO[0000] Response:
HTTP/2.0 405 Method Not Allowed
Content-Length: 157
Content-Type: text/html
Date: Thu, 04 Jan 2024 16:42:31 GMT
Server: nginx/1.25.2

<html>
<head><title>405 Not Allowed</title></head>
<body>
<center><h1>405 Not Allowed</h1></center>
<hr><center>nginx/1.25.2</center>
</body>
</html>
  group= iter=0 request_id=3327b6e1-cf22-40fa-7198-11a073c5614c scenario=default source=http-debug vu=1       
                                                                                                              
     ✗ is status 200                                                                                          
      ↳  0% — ✓ 0 / ✗ 1                                                                                       

     checks.....................: 0.00%   ✓ 0       ✗ 1
     data_received..............: 5.9 kB  17 kB/s
     data_sent..................: 761 B   2.2 kB/s
     http_req_blocked...........: avg=284.43ms min=284.43ms med=284.43ms max=284.43ms p(90)=284.43ms p(95)=284.43ms
     http_req_connecting........: avg=46.86ms  min=46.86ms  med=46.86ms  max=46.86ms  p(90)=46.86ms  p(95)=46.86ms
     http_req_duration..........: avg=55.05ms  min=55.05ms  med=55.05ms  max=55.05ms  p(90)=55.05ms  p(95)=55.05ms
     http_req_failed............: 100.00% ✓ 1       ✗ 0
     http_req_receiving.........: avg=4.05ms   min=4.05ms   med=4.05ms   max=4.05ms   p(90)=4.05ms   p(95)=4.05ms
     http_req_sending...........: avg=0s       min=0s       med=0s       max=0s       p(90)=0s       p(95)=0s 

     http_req_tls_handshaking...: avg=117.59ms min=117.59ms med=117.59ms max=117.59ms p(90)=117.59ms p(95)=117.59ms
     http_req_waiting...........: avg=50.99ms  min=50.99ms  med=50.99ms  max=50.99ms  p(90)=50.99ms  p(95)=50.99ms
     http_reqs..................: 1       2.91577/s
     iteration_duration.........: avg=342.96ms min=342.96ms med=342.96ms max=342.96ms p(90)=342.96ms p(95)=342.96ms
     iterations.................: 1       2.91577/s

                                                                                                              
running (00m00.3s), 0/1 VUs, 1 complete and 0 interrupted iterations                                          
default ✓ [======================================] 1 VUs  00m00.3s/10m0s  1/1 iters, 1 per VU         

I’ve hidden the url, username and password, however if url and how the POST message displays the url is needed I’m willing to DM someone since it’s not public information. Based off the debugger information I’m getting a 405 ‘Not Allowed’ error message. I’m not sure how to proceed further, would greatly appreciate any help!

Hi @ramenoir, welcome to the community forum!

Are you sure, that the login page uses POST? The tag’s method attribute is POST? Can you call the url with curl using -X POST?

Hi @bandorko! Thanks for your response, the login page uses the GET method, sorry I forgot to mention this in the OP. The login form was also developed using Angular, and the form itself is a mat-form. How can I send the email and password once k6 reaches the login page, so that it can test for the end point after user authentication?

EDIT: I’ve tried calling the url with curl using -X POST and I get the same 405 error:

C:\Users\RSKal>curl -X POST https://xxxxxx
<html>
<head><title>405 Not Allowed</title></head>
<body>
<center><h1>405 Not Allowed</h1></center>
<hr><center>nginx/1.25.2</center>
</body>
</html>

I think you should use:

  http.get('http://whatever.com/action?email=xxxx&password=xxxx')

instead of http.post(url, payload, params)

2 Likes

@bandorko This worked for me as my status 200 check is now passing!

I was wondering what further checks I could add to validate successful login? I’ve thought about using res.body.includes(), however the response body I get when I console log doesn’t seem to provide useful information? Here’s a screenshot of part of it:

I’ve tried using text I can find on the home page, however res.body.includes("text on homepage) returns false.

Is there a way to look for text on the homepage with k6 without using the k6 browser? And if not, is there another way I can validate successful login?

EDIT: Also had another question: I need to test end points between pages which are only public once someone successfully logs in. With k6, for the most part I can test logging in, however, how do I test navigating to the other pages endpoints? Would I need to perform the code in the OP, and then do another GET request? Something like this:

import http from 'k6/http';
import {check} from 'k6';

export const options = {
    vus: 1,
    duration: '2s',
}

export default function () {
    let url = 'https://xxxxxxx/action?email=xxxxx&password=xxxx';

    let res = http.get(url);

    let url2 = 'https://xxxxxx/c3/150/#/main/p1';

    let res2 = http.get(url2);

    check(res2, {
        'is status 200': (r) => r.status === 200,
    })

}