Hello everybody!
When trying to post or update a message whose content exceeds a certain size (the exact size I cannot detemine yet - is there a way to check this?) NGINX refuses to accept the POST or PUT requests and returns Error 414.
Is there a way to change (permanently) the default configuration delivered with the Discourse image, so that a larger payload size (at least matching the default 32000 characters in the admin settings) is accepted via API?
Have you checked the settings for āmax post sizeā? There is also discussion here about increasing it.
If your posts via the API are getting cut off smaller than that, Iād be surprised.
Yep, I did. Itās currently set to the default value of 32000 characters and Iām trying to push via API a payload of about 6000 characters. I think that the error comes from NGINX and not from Discourseā¦
After a bit of searching online I found that the problem might be related to the size of URL of the PUT request performed when I update a post via API.
This is actually rendering ineffective the setting āmax post lengthā in Discourse admin, currently at the default value of 32000 characters.
Would it be possible to change the nginx template matching the web server configuration with the default Discourse configuration?
You can change nginx settings in the yml file. You can look in the discourse_docker/templates
directory for some examples.
I usually edit them in the container to debug and then apply those settings to new containers in app.yml
.
Just to document what I did for future visitors, I have manually added the options suggested in the topics linked in my previous message.
client_header_buffer_size 64k;
large_client_header_buffers 4 64k;
The values might be different for other users, but they look more than enough for my needs.
These options shall be manually added to the /etc/nginx/conf.d/discourse.conf NGINX configuration file, and after having restarted nginx service in the container, the problem will be solved.
Obviously this has to be redone manually at every container rebuild, unless this setting is added to the official web templates.
One last post - the error was caused by me, hence no change to the templates is needed, at all!
Iām placing my API requests using the requests python library, and I was submitting the payload using parameter params=payload rather than data=payload, hence my oversized payload was handled in the āwrongā way.
I changed my call from this
r = requests.put(apiWebsite + '/posts/' + str(apiPost), params=payload)
to this
r = requests.put(apiWebsite + '/posts/' + str(apiPost), data=payload)
Sorry!
[quote=āmarcozambi, post:7, topic:98186, full:falseā][/quote]
We are having a similar problem when creating a post using the POST method.
And when the post is long the 414 error arrises.
We are using the discourse api in python to generate some post using the discourse api.
The create_post function seems to us a POST request using params instead of data.
This is the create_post definition form the discourse api
def create_topic(self, title, raw, category=None, created_at=None):
response = self._request('POST', 'posts.json', params={
'title': title,
'raw': raw,
'category': category,
'created_at': created_at,
})
We have tried to change params by data in the function definition.
We have tried using PUT instead of POST.
But it does not work.
The problem seem to be that the complete post is passed as parameters in the URL instead of an internal payload.
Is this a bug?
How may we create a long post using data payload instead of URL parameters?
Hmmm, itās not very clear to me what kind of module youāre using to submit your POST request. I use requests and I prepare a post request like I show you here below.
The POST method is to create new posts; PUT is to modify existing posts.
Please check the API documentation here: https://docs.discourse.org/
import requests, json
headers = {
'Content-Type': 'application/json',
'Api-key': envDiscourseKey, # API key passed in this variable
'Api-username': envDiscourseUsername # API user passed in this variable
}
tags = ['first-tag','second-tag']
payload = {
'title': 'Sample title',
'category': 123,
'tags': tags,
'raw': 'Raw text of your post'
}
r = requests.post('https://www.yourwebsite.xyz/posts', headers=headers, data=json.dumps(payload))
returnedData = r.json()
status = r.status_code
Also, as I explained here passing the payload through the params parameter was a mistake on my part and shall not be done.
I hope this helps
Thanks a lot for your quick response.
We are using a python warpper to the oficial JavaScript api from discourse:
https://github.com/samamorgan/discourse
It seems a wrapper to the official discourse one.
The problem is that in the definitions it uses params= (as you can see in the extracted function definition from the clients.py file).
It passes the title and raw data in params.
We have changed the definition of the creata_post function to data=
but then it does not work.
I see. Well, it seems that the problem lies in the wrapper implementation.
You donāt need any wrapper, in my opinion. Apart from the requests and json modules, the code I posted is just plain python3.
Try to go with that, maybe defining your own wrapper functions.
I see, you are right.
The problem is that we are not very proficient in python.
But it seems the wrapper implementation is not good.
But even if we have changed params to data in the function definition it does not work
We will try to use this code to create the post instead of the wraper code.
I am not the one who is doing the program, I program in JavaScript and other languages but not python.
I will try to explain the programmer how to do this (he is a bit confused he was using the wrapper thinking it was the official discourse api implementation, and the wrapper uses post as the name of the method to create the post, while the underlying python llibrary request uses post as the name of the method to sen a POST message, I think that is what he is not understanding well).
We have tried your code, but we receive a 403 error as response.
It seems that there is some kind of authoritation problem.
But we are using the same api key and user that we used previously (with the api wrapper) and it workedā¦
do you have any idea?
I will tel the programmer to check in and explain it better.
They are trying to use python though, not curl.
The example they mention above has the correct headers.
Hi Marco,
Iām Fernandoās colleague. Iāve implemented your code and it works fine and problem is solved.
Thanks a lot!
Albert.
Thank you all specially to marco who provided the python code.
Now it works.
we made and error and use api-key instead of Api-key.
we changed that and the code works.
I donāt know what is wrong in the wrapper that we were using (besides using params= instead of url).
We changed params by data and it did not work, but the code seem to do exactly what Marco says (but using params which is not a the correcto way).
Thank you again
Itās not case sensitive on our side, is it @blake?
I am not the programmer, I donāt know python, just helped him to fix the error.
May be python is case sensitive or rhere is an option to activate it?
The program worked just changing that.
Nope. Rails/Rack converts all headers to UPPER CASE for us. There is nothing in our code that is checking for case sensitivity.