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]
POST 메서드를 사용하여 게시물을 생성할 때 비슷한 문제를 겪고 있습니다.
게시물이 길면 414 오류가 발생합니다.
저희는 Python으로 Discourse API를 사용하여 몇 가지 게시물을 생성하고 있습니다.
create_post 함수는 data 대신 params를 사용하여 POST 요청을 보내는 것으로 보입니다.
Discourse API의 create_post 정의는 다음과 같습니다.
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,
})
함수 정의에서 params를 data로 변경해 보았습니다.
POST 대신 PUT을 사용해보기도 했습니다.
하지만 작동하지 않습니다.
문제는 전체 게시물이 내부 페이로드가 아닌 URL 파라미터로 전달되고 있는 것 같습니다.
이것이 버그인가요?
data 페이로드를 사용하여 긴 게시물을 생성하려면 어떻게 해야 하나요?
음, POST 요청을 제출하는 데 어떤 모듈을 사용 중인지 정확히 파악이 잘 안 됩니다. 저는 requests를 사용하며, 아래에서 보여드리듯 POST 요청을 준비합니다.
POST 메서드는 새 게시글을 생성하는 데 사용하고, PUT은 기존 게시글을 수정하는 데 사용합니다.
API 문서는 여기에서 확인해 주세요: https://docs.discourse.org/
import requests, json
headers = {
'Content-Type': 'application/json',
'Api-key': envDiscourseKey, # 이 변수로 전달되는 API 키
'Api-username': envDiscourseUsername # 이 변수로 전달되는 API 사용자
}
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
또한, 여기에서 설명했듯이 payload를 params 파라미터를 통해 전달하는 것은 제 실수였으며, 그렇게 하지 않아야 합니다.
도움이 되길 바랍니다.
빠른 답변에 감사드립니다.
우리는 Discourse의 공식 JavaScript API에 대한 Python 래퍼를 사용하고 있습니다:
이것은 공식 Discourse API에 대한 래퍼인 것 같습니다.
문제는 정의에서 params=를 사용한다는 것입니다(clients.py 파일에서 추출한 함수 정의를 참고하세요).
제목과 원시 데이터를 params를 통해 전달합니다.
우리는 create_post 함수의 정의를 data=로 변경했지만, 그 후에는 작동하지 않습니다.
알겠습니다. 문제의 원인이 래퍼 구현에 있는 것 같습니다. 제 생각에는 래퍼가 전혀 필요 없습니다. requests 모듈과 json 모듈을 제외하면, 제가 올린 코드는 그냥 순수한 python3입니다. 직접 래퍼 함수를 정의하면서 이 코드를 사용해 보세요.
아, 맞습니다.
문제는 우리가 Python에 대해 아주 능숙하지 않다는 점입니다.
하지만 래퍼 구현이 좋은 것 같지 않습니다.
함수 정의에서 params를 data로 변경해도 여전히 작동하지 않습니다.
우리는 래퍼 코드 대신 이 코드를 사용하여 게시물을 생성해 보려 합니다.
저는 프로그램을 직접 작성하는 사람은 아닙니다. JavaScript와 다른 언어로 프로그래밍을 하지만 Python은 하지 않습니다.
프로그래머에게 어떻게 해야 하는지 설명해 보려 합니다 (그는 조금 혼란스러워하고 있습니다. 그는 래퍼를 공식 discourse API 구현으로 오해하고 있었고, 래퍼에서는 게시물을 생성하는 메서드 이름을 post로 사용하지만, 그 아래에서 사용되는 Python 라이브러리 request에서는 POST 메시지를 보내는 메서드 이름을 post로 사용하기 때문입니다. 이것이 그가 제대로 이해하지 못하는 부분이라고 생각합니다).
코드를 테스트해 보았지만, 응답으로 403 오류를 받고 있습니다.
어떤 종류의 인증 문제인 것 같습니다.
하지만 이전에 (API 래퍼를 사용하여) 사용했던 것과 동일한 API 키와 사용자를 사용하고 있으며, 그때는 정상적으로 작동했습니다…
혹시 원인을 알 수 있을까요?
프로그래머에게 확인을 요청하고 더 자세히 설명하도록 하겠습니다.
그들은 curl이 아니라 Python을 사용하려고 하고 있습니다.
위에서 언급한 예제에는 올바른 헤더가 포함되어 있습니다.
마르코, 안녕하세요.
저는 페르난도의 동료입니다. 당신의 코드를 구현해 봤는데, 잘 작동하며 문제가 해결되었습니다.
감사합니다!
알베르트
모두에게 감사드립니다. 특히 Python 코드를 제공해 주신 marco님께 감사드립니다.
이제 작동합니다.
우리가 실수를 해서 api-key를 Api-key로 사용했습니다.
그 부분을 수정했고, 이제 코드가 작동합니다.
우리가 사용하던 래퍼에 어떤 문제가 있었는지는 모르겠습니다 (params= 대신 url을 사용해야 한다는 점도 제외하고요).
params를 data로 변경했지만 작동하지 않았고, 코드는 Marco가 말한 것과 정확히 같은 일을 하는 것 같지만 (params를 사용했는데, 이는 올바른 방식이 아닙니다).
다시 한번 감사드립니다
우리 쪽에서는 대소문자를 구분하지 않는데, @blake님도 그렇게 맞습니까?
저는 프로그래머가 아니고 파이썬도 잘 몰라서 그냥 그분이 에러를 수정하는 데만 도움을 드렸습니다.
혹시 파이썬이 대소문자를 구분하는 건지, 아니면 대소문자 구분을 활성화할 수 있는 옵션이 있는 건지 궁금합니다.
그 부분만 바꾸니까 프로그램이 잘 동작했습니다.
아니요. Rails/Rack이 모든 헤더를 대문자로 변환해 줍니다. 우리 코드에는 대소문자를 구분하여 확인하는 부분이 없습니다.
Rails는 이제 헤더에 HTTP_ 접두사도 붙이고 모든 문자를 대문자로 변환하므로, 이제 request.headers[“HTTP_CONTENT_TYPE”]가 됩니다.