5

What is Http 400 Bad Request and what causes it to happen?

What is method I can use to know which key in request.form[key] that cause bad request and how can I prevent it?

Updated

As Gerand mentioned in his comment:

This error happens when you are requesting a file through http which doesn't exist [....]

To make it clearer, here my sample code that cause Bad Request:

hello.py

# -*- coding: utf-8 -*-
from flask import *
import re

app = Flask(__name__)


@app.route('/', methods=['GET','POST'])
def checkName():

    return render_template('hello.html')

@app.route('/hello',methods=['GET','POST'])
def printName():
    if request.method=='POST':
        username = request.form['username']
        bad_key = request.form['bad_key'] # this key is not exist
        
        return "Hello, ",username

if __name__ == '__main__':

    app.run(debug=True)

hello.html

<form class="form-horizontal" action='/hello' method='POST' name="frm_submit">
  <div class="form-group">
    <label for="username" class="col-sm-2 control-label">User Name:</label>
    <div class="col-sm-10">
      <input type="text" class="form-control" id="username" name="username" placeholder="username">
    </div>
  </div>
  <div class="form-group">
    <div class="col-sm-offset-2 col-sm-10">
      <button type="submit" class="btn btn-default">Submit</button>
    </div>
  </div>
</form>

From code above, the browser return Bad Request - The browser (or proxy) sent a request that this server could not understand. without giving clue that which key that cause this error.

Therefore, which method I can use to know which key that cause this error, and how can I prevent it?

Thanks.

snakecharmerb
  • 47,570
  • 11
  • 100
  • 153
rean computer
  • 53
  • 1
  • 4
  • what are you trying to do? what libraries are you using... Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. – Kaustubh Kallianpur Sep 21 '17 at 11:57
  • @KaustubhKallianpur, I am trying to know what cause the `Error 400 Bad Request` in python? how can I know the cause and prevent that? thanks. – rean computer Sep 21 '17 at 12:00
  • This error happens when you are requesting a file through http which doesn't exist. It has nothing to do with python. – Gerard Sep 21 '17 at 12:01
  • [This answer](https://stackoverflow.com/questions/8840303/urllib2-http-error-400-bad-request) maybe of some help. If there is something else, we would need some code input. – Kaustubh Kallianpur Sep 21 '17 at 12:02
  • 1
    @Gerard Isn't that "404 - Not found"? 400 refers to a corrupt request –  Sep 21 '17 at 12:02
  • 1
    @lausek totally right, I kind of brainfarted. Usually happens to me – Gerard Sep 21 '17 at 12:03
  • @KaustubhKallianpur, please refer to my updated question. Thanks – rean computer Sep 21 '17 at 12:33

1 Answers1

2

Flask uses the werkzeug library's MultiDict data structure to hold POST data.

If you look at the implementation of MultiDict.__getitem__, you can see that if a key is not found, it will raise BadRequestKeyError with the name of the key as an argument. So you can inspect the exception's args attribute to get the name of the bad key:

from werkzeug.exceptions import BadRequestKeyError

@app.route('/hello', methods=['GET', 'POST'])
def hello():
    if request.method == 'POST':
        username = request.form['username']
        try:
            bad_key = request.form['bad_key']
        except BadRequestKeyError as ex: 
            return 'Unknown key: "{}"'.format(ex.args[0]), 500 

Note that while BadRequestKeyErrors string representation is

400 Bad Request: The browser (or proxy) sent a request that this server could not understand.

the status of the response is actually

500 Internal Server Error

The keys of request.form correspond to the name attributes of the input tags in the form(s) in the HTML page being POSTed. Thus a BadRequestKeyError will often be caused by a mismatch between the name attributes in the HTML and the names expected by request.form['some_name'] in the route.

snakecharmerb
  • 47,570
  • 11
  • 100
  • 153