API Returns a HTTP 301 for invalid POST / PATCH requests #1499

Closed
opened 2025-12-29 16:32:29 +01:00 by adam · 2 comments
Owner

Originally created by @woodjme on GitHub (Jan 19, 2018).

Issue type

[X] Bug report

Environment

  • Python version: 2.7.9
  • NetBox version: 2.2.7

Description

API returns HTTP 301 Move Permanently redirect when the trailing / is missing from a URL.

Sending a POST to URL such as https://netbox.co.uk/api/virtualization/virtual-machines/1 results in a 301 redirect to https://netbox.co.uk/api/virtualization/virtual-machines/1/.

This presents a problem when sending a POST or PATCH request as the RFC specification states:

Note: For historical reasons, a user agent MAY change the request method from POST to GET for the subsequent request. If this behavior is undesired, the 307 (Temporary Redirect) status code can be used instead.

Source

The net result is after sending the POST request you end up receiving an HTTP 200 for a GET request returning the unmodified object. I'd make the case that this 301 should be changed to a 308 as the RFC specifications states:

A 308 response is cacheable by default; i.e., unless otherwise indicated by the method definition or explicit cache controls (see RFC7234], Section 4.2.2). Note: This status code is similar to 301 (Moved Permanently) ([RFC7231], Section 6.4.2), except that it does not allow changing the request method from POST to GET

Source

Originally created by @woodjme on GitHub (Jan 19, 2018). ### Issue type [X] Bug report ### Environment * Python version: `2.7.9` * NetBox version: `2.2.7` ### Description API returns `HTTP 301 Move Permanently` redirect when the trailing `/` is missing from a URL. Sending a POST to URL such as https://netbox.co.uk/api/virtualization/virtual-machines/1 results in a `301` redirect to https://netbox.co.uk/api/virtualization/virtual-machines/1/. This presents a problem when sending a `POST` or `PATCH` request as the RFC specification states: > Note: For historical reasons, a user agent MAY change the request method from POST to GET for the subsequent request. If this behavior is undesired, the 307 (Temporary Redirect) status code can be used instead. [Source](https://tools.ietf.org/html/rfc7231#section-6.4.2) The net result is after sending the `POST` request you end up receiving an `HTTP 200` for a `GET` request returning the unmodified object. I'd make the case that this `301` should be changed to a `308` as the RFC specifications states: > A 308 response is cacheable by default; i.e., unless otherwise indicated by the method definition or explicit cache controls (see RFC7234], Section 4.2.2). Note: This status code is similar to 301 (Moved Permanently) ([RFC7231], Section 6.4.2), except that it does not allow changing the request method from POST to GET [Source](https://tools.ietf.org/html/rfc7538)
adam added the type: feature label 2025-12-29 16:32:29 +01:00
adam closed this issue 2025-12-29 16:32:29 +01:00
Author
Owner

@jeremystretch commented on GitHub (Jan 19, 2018):

This behavior is a convenience function provided by the Django framework. We could set APPEND_SLASH=False to simply return a 404 for URLs given without the trailing slash, but this will likely confuse users who on occasion hand-type a URL and forget the slash.

To be clear, the only correct URL is the form with the trailing slash. (The redirect is merely a hint.) To avoid this problem entirely, just use the correct form.

@jeremystretch commented on GitHub (Jan 19, 2018): This behavior is a convenience function [provided by the Django framework](https://docs.djangoproject.com/en/1.11/ref/settings/#append-slash). We could set `APPEND_SLASH=False` to simply return a 404 for URLs given without the trailing slash, but this will likely confuse users who on occasion hand-type a URL and forget the slash. To be clear, the only _correct_ URL is the form with the trailing slash. (The redirect is merely a hint.) To avoid this problem entirely, just use the correct form.
Author
Owner

@jeremystretch commented on GitHub (Jan 30, 2018):

This was discussed briefly in the #netbox channel on the NetworkToCode Slack. It's probably best to leave this as is to avoid breaking other things. While I understand your point, I think it's reasonable to assert that an API consumer must always use the canonically appropriate URL form.

@jeremystretch commented on GitHub (Jan 30, 2018): This was discussed briefly in the #netbox channel on the NetworkToCode Slack. It's probably best to leave this as is to avoid breaking other things. While I understand your point, I think it's reasonable to assert that an API consumer must always use the canonically appropriate URL form.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#1499