AEM 6.5.18
Problem statement: Trying to save PDF in AEM publish DAM and return a externalized PDF URL.
A post servlet is created to POST data with pdf as blobdata to store PDF in DAM. If directly posted to AEM publish, PDF is stored in DAM successfully.
However, if it is posted via dispatcher, we observe 400 - Bad request error.
Things checked/observed:
Enabled trace logs in dispatcher and ensured filter allows POST for servlet path.
Since it is anonymous POST, no CSRF-TOKEN is generated.
All /clientheaders required are allowed in dispatcher
Tried adding LimitRequestBody LimitRequestFieldSize LimitRequestFields LimitRequestLine to sufficient size
Tried to disable mod_security to see if the multipart data is allowed to be posted to narrow root cause.
Above did not resolve the issue and unable to determine the root cause of 400-bad request in dispatcher alone.
Please let me know if any further inputs I missed to share. Kindly let know any pointers and if the data sent using frontend is incorrect.
Solved! Go to Solution.
Topics help categorize Community content and increase your ability to discover relevant content.
Views
Replies
Total Likes
Hi @nsriram
A "Bad Request" usually has to do something with wrong or missing HTTP headers.
Can you check which headers the request has when it hits the CQ instance (after being processed by the dispatcher)?
Please check : https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/dispatcher-issue/m-p/22941...
Views
Replies
Total Likes
Hi @nsriram ,
It would be great if you can add info like whether Api reaches to code or getting returned from dispatcher itself.
Thanks,
Views
Replies
Total Likes
Hi @MukeshYadav_ ,
Request does not reach the servlet via dispatcher. It is allowed in filter but response is 400 from dispatcher. If directly posted to AEM publish, response status is 200 and PDF is inserted into DAM. Below is what is being tried from frontend
ajax
$.ajax({
url: <servlet_path>,
data: formData,
cache: false,
contentType: false,
processData: false,
type: 'POST',
success: function(response){
// process response
}
});
fetch
const response = await fetch('<servlet_path>', {
method: 'POST',
body: formData
});
Views
Replies
Total Likes
Hi @nsriram
A "Bad Request" usually has to do something with wrong or missing HTTP headers.
Can you check which headers the request has when it hits the CQ instance (after being processed by the dispatcher)?
Please check : https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/dispatcher-issue/m-p/22941...
Views
Replies
Total Likes
Hi @arunpatidar
Trace from dispatcher logs where some request headers seem repeated
[Fri Jun 21 xx:xx:xx 2024] [D] [pid xxxxxx] Found farm publishfarm for ****
[Fri Jun 21 xx:xx:xx 2024] [D] [pid xxxxxx] checking [/bin/<servlet_path>]
[Fri Jun 21 xx:xx:xx 2024] [D] [pid xxxxxx] request URL has no extension: /bin/<servlet_path>
[Fri Jun 21 xx:xx:xx 2024] [D] [pid xxxxxx] cache-action for [/bin/<servlet_path>]: NONE
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] Decomposing URL :
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] uri : /bin/<servlet_path>
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] suffix : No suffix
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] extension : No extension
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] selector : No selectors
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] Decomposing Complete
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] Filter rule entry /000x allowed 'POST /bin/<servlet_path> HTTP/1.1'
[Fri Jun 21 xx:xx:xx 2024] [D] [pid xxxxxx] Creating new connection: x.x.x.x:4503
[Fri Jun 21 xx:xx:xx 2024] [D] [pid xxxxxx] Connected to backend 0 (x.x.x.x:4503)
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.uri = "/bin/<servlet_path>"
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[X-Forwarded-Proto] = "https"
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[referer] = "<domain>"
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[user-agent] = "<useragent_value>"
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[content-type] = "multipart/form-data; boundary=----WebKitFormBoundaryIZt2HmdATCVOIlf5"
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[content-length] = "13645"
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[accept-encoding] = "gzip, deflate, br, zstd"
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[accept-language] = "en-GB,en-US;q=0.9,en;q=0.8"
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[accept] = "*/*"
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[host] = "<domain>"
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[cookie] = "<cookie_values>"
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[Connection] = "keep-alive"
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[Sec-Fetch-Dest] = "empty"
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[Sec-Fetch-Mode] = "cors"
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[Sec-Fetch-Site] = "same-origin"
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[sec-ch-ua] = ""Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126""
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[sec-ch-ua-mobile] = "?0"
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[sec-ch-ua-platform] = ""macOS""
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[x-dtpc] = "1$586353623_54h15vUBJEBRCPUUVAUORFLLUPPHWWTFGCTPTT-0e0"
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[X-Forwarded-Proto] = "https"
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[referer] = "<domain>"
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[user-agent] = "<useragent_value>"
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[content-type] = "multipart/form-data; boundary=----WebKitFormBoundaryIZt2HmdATCVOIlf5"
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[content-length] = "13645"
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[accept-encoding] = "gzip, deflate, br, zstd"
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[accept-language] = "en-GB,en-US;q=0.9,en;q=0.8"
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[accept] = "*/*"
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[host] = "<domain>"
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[cookie] = "
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[Via] = "1.1 <domain> (dispatcher)"
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[X-Forwarded-For] = "IPs"
[Fri Jun 21 xx:xx:xx 2024] [T] [pid xxxxxx] request.headers[Server-Agent] = "Communique-Dispatcher"
[Fri Jun 21 xx:xx:xx 2024] [D] [pid xxxxxx] Sending request body to remote server
[Fri Jun 21 xx:xx:xx 2024] [D] [pid xxxxxx] Request body sent to remote server
[Fri Jun 21 xx:xx:xx 2024] [D] [pid xxxxxx] No socket reuse: neither GET nor HEAD
[Fri Jun 21 xx:xx:xx 2024] [I] [pid xxxxxx] "POST /bin/<servlet_path>" 400 none [publishfarm/0] 3ms
Views
Replies
Total Likes
Hi @arunpatidar
My /clientheaders include all of these in dispatcher. Kindly let me know if you see an issue here
Views
Replies
Total Likes
Hi @arunpatidar ,
Thanks a lot for your pointer. I had included clientheaders like below
/clientheaders {
$include "/etc/httpd/conf.dispatcher.d/clientheaders/ams_common_clientheaders.any"
$include "/etc/httpd/conf.dispatcher.d/clientheaders/<project>_clientheaders.any"
}
with AMS commonly allowed headers copied over to project specific headers. So I had duplicated clientheaders allowed. When I merged the file and only called my project specific clientheader file, it worked! So it is duplicated clientheaders that was causing 400.
Views
Replies
Total Likes
contentType false will remove any content type header which could be a possible cause for dispatcher to block it. Could you try to remove it once from the ajax call just to test ?
Also there should be some clue in Apache's or dispatcher error logs if this is really getting blocked at the dispatcher level.
Views
Replies
Total Likes
Hi @h_kataria
I also tried using fetch as posted above.
When using AJAX to send multipart/form-data (such as for file uploads) with jQuery, you typically need to set the contentType to false. This ensures that the correct content type is set automatically by the browser, including the multipart boundary. Additionally, you need to set processData to false to prevent jQuery from attempting to process the data into a query string, which is not suitable for FormData objects.
Reference:
GenAI, https://api.jquery.com/jQuery.ajax/
Views
Replies
Total Likes
Views
Likes
Replies