Setting a response header in a CQ5 publishing instance - aem

I want to disable caching in a CQ component and I have the following line in my jsp (documentation):
response.setHeader("Dispatcher", "no-cache");
If I insert the component in a page and load the page in an authoring instance everything works as expected and I get an HTTP header named Dispatcher with the content no-cache.
Now if I do the same on a publishing instance (same configuration with CQ_RUNMODE='publish' and same content) the component works but for setting the HTTP header.
Any idea on why the two instances could behave differently?
Update
I tried to set other headers and the instance behaves in the same way: in the authoring mode the headers are generated in the publishing mode not (same configuration but for the CQ_RUNMODE)
Update 2
I was trying to reduce my example by removing everything that is unnecessary from the page (layout, code for headers, footer, ...) and I noticed that after a certain size threshold my header is correctly generated.
In other words by removing stuff from the page (even simple HTML) I reach a certain point where the header appears (if the page is small enough).
Any idea on why CQ is only generating the header for very small pages?

If you're trying to set the header in a component far down on the page, you could be getting the issue that you're trying to write it after the response has been committed.
If you need to flag the page as not cached & you cannot avoid placing the code higher in the buffer, you could instead write in a check for this node type at the start of the JSP (using node.listChildren() for example), or provide a page property that let's the editor control if the page is cached or not.

You didn't indicate which version of CQ5 you're using - I just tested with a minimal JSP script on a CQ 5.5 GA publish instance, and the header is correctly set:
$ curl -u admin:admin http://localhost:4503/tmp/x.tidy.json
{
"sling:resourceType": "x",
...
}
$ curl -u admin:admin http://localhost:4503/apps/x/x.jsp
<%
response.setHeader("Dispatcher","no-cache");
%>
Here's the content.
$ curl -D - -u admin:admin http://localhost:4503/tmp/x.html
HTTP/1.1 200 OK
Connection: Keep-Alive
...
Dispatcher: no-cache
Here's the content.
You might want to start with this minimal test and compare with what you're doing.

Related

wget works fine for some .jpgs but downloads an .html file instead for others

I want to download web images from the command line.
This works fine sometimes, other times it doesn't and I can't figure out why.
Here's an example (Wikimedia Commons picture of the day):
wget https://commons.wikimedia.org/wiki/Main_Page#/media/File:01_Calanche_Piana.jpg
This somehow gets me an .html
HTTP request sent, awaiting response... 200 OK
Length: 185986 (182K) [text/html]
Saving to: 'Main_Page'
The following however (it's the same picture but with explicitly selected resolution) gets me a .jpg (which is what I want)
wget https://upload.wikimedia.org/wikipedia/commons/thumb/0/01/01_Calanche_Piana.jpg/640px-01_Calanche_Piana.jpg
...
HTTP request sent, awaiting response... 200 OK
Length: 118796 (116K) [image/jpeg]
Saving to: '640px-01_Calanche_Piana.jpg'
I tried adding -O test.jpg to the first example, this will still be an .html file though.
Does anyone know why the command works in one case but not in the other?
why the command works in one case but not in the other?
This one
https://commons.wikimedia.org/wiki/Main_Page#/media/File:01_Calanche_Piana.jpg
despite what last letter might suggest is link to HTML page, note that there is # which is used to denote URI fragment, whilst this one
https://upload.wikimedia.org/wikipedia/commons/thumb/0/01/01_Calanche_Piana.jpg/640px-01_Calanche_Piana.jpg
is URL to actual image. If you wondering what type of file is under given URL, but do not want to download that file you might do
wget -S --spider https://www.example.com
It will show you response headers, there might be many of them, but for determining type of resource Content-Type should suffice.

Log HAProxy captured response header in custom format

I have an HAProxy configuration with a custom JSON log-format. I want to capture a specific response header and log it.
However, no matter how I try to capture it, I cannot make it appear in the log.
In my log format I use %[capture.res.hdr(0)] but it only comes up as -. I've also tried %[res.hdr(0)] and %[res.hdr(MyHeader)] but they were not valid configuration and HAProxy failed to start.
I've tried capturing using:
capture response header MyHeader len 50
But it doesn't work. I also tried:
declare capture response len 50
http-response capture res.hdr(MyHeader) id 0
With no success. The %hs format variable works - all the captured headers are logged in a delimited string. But I want to log the headers separately as JSON properties.
What am I doing wrong?
I'm currently using HAProxy 1.8.
It seems like the combination of having capture response header MyHeader len 50 in the frontend section and %[capture.res.hdr(0)] in the log-format actually works. Turns out I had multiple instances of HAProxy running and only reloaded some of them, so the changes only came through for some requests.

TYPO3 7.6: 404 error page: HTML wrapped in numbers

I created my own “404 Page not found” error page on a TYPO3 website and implemented it via the /typo3conf/LocalConfiguration.php as follows, using the page’s Speaking URL path:
return [
...
'FE' => [
...
'pageNotFound_handling' => '/page-not-found/',
]
]
Now when I call a non-existing page, the error page gets displayed but there is a 4-digit alphanumeric number (hexadecimal as far as I’ve seen by now) BEFORE the HTML source code and a “0” AFTER it. Example (the number in the beginning is different after most of the reloads):
37b3
<!DOCTYPE html>
...
</html>
0
When calling the error page URL itself the page is returned correctly without those numbers.
Having the RealURL extension activated or deactivated does not make a difference.
Thanks a lot in advance!
I added the full description from the install tool and I guess we might find the solution there.
How TYPO3 should handle requests for non-existing/accessible pages.
empty (default)
The next visible page upwards in the page tree is shown.
'true' or '1'
An error message is shown.
String
Static HTML file to show (reads content and outputs with correct headers), e.g. notfound.html or http://www.example.org/errors/notfound.html.
Prefix "REDIRECT:"
If prefixed with "REDIRECT:" it will redirect to the URL/script after the prefix.
Prefix "READFILE:"
If prefixed with "READFILE" then it will expect the remaining string to be a HTML file which will be read and outputted directly after having the marker "###CURRENT_URL###" substituted with REQUEST_URI and ###REASON### with reason text, for example: READFILE:fileadmin/notfound.html.
Prefix "USER_FUNCTION:"
If prefixed with "USER_FUNCTION:" a user function is called, e.g. USER_FUNCTION:fileadmin/class.user_notfound.php:user_notFound->pageNotFound where the file must contain a class user_notFound with a method pageNotFound() inside with two parameters $param and $ref.
What you configured:
You're passing a string, thus TYPO3 expects to find a file - which you don't have, because it's more like an URL.
From what you try to achieve I'd go with REDIRECT:/page-not-found/.
Thanks for pointing this one out btw, I will remove the string configuration from the core since it does not make sense to have more people trip into this pitfall.
In short: change the following line in the FE section of your LocalConfiguration.php:
'pageNotFound_handling' => '/your404page.html',
to
'pageNotFound_handling' => 'REDIRECT:/your404page.html',
Cause
The actual cause is a combination of chunked Content-Encoding and the TYPO3 not being able to decode that in some cases. In your case the page not found handler eventually uses GeneralUtility::getUrl() to retrieve the error page.
If you have [SYS][curlUse] enabled it will use cUrl to retrieve the page and there is no problem.
If you don't have [SYS][curlUse] enabled it will open a socket, read the headers and then read the rest of the body. If the webserver uses "chunked" Content-Encoding the body will contain blocks of data and each block starts with a line with the length in hexadecimal format. The content ends with an empty block (with of course a line with the length "0").
cUrl apparently knows how to decode chunked data.
getUrl() itself does not know how to handle chunked data and uses the content as is as the page content.
In TYPO3 8 LTS the guzzle library is used to handle HTTP requests. In the guzzle code I can't find anything about handling chunked data. Guzzle will check if the cUrl PHP extension is present and use that as preferred transport. In most installations cUrl is present and since this decodes chunked data automagically no problem is visible. I have to test guzzle with PHP that has cUrl disabled to see if the issue is also present in v8/master.
Workaround/solution
If the PHP extension cUrl is enabled in your installation you can simply set [SYS][curlUse] in the Install Tool. The numbers around the 404 page content will disappear.

POST that doesn't create a resource

Assume the system manages users. Users are exposed via the following URL - /users. A particular user is exposed via the following URL - /users/{id}. Users have reports exposed via the following URL - /users/{id}/reports.
One operation consists of generating a report. The appropriate HTTP request is a POST on /users/{id}/reports. However, under certain conditions, a generated report would be exactly the same as the last generated report. Therefore, I thought that returning the last generated report in this case is a good approach.
I also know that in such case, no resource will be created.
Is there a correct RESTful way to handle this case? Maybe returning a special code?
Is there a correct RESTful way to handle this case? Maybe returning a special code?
Stepping back for a moment: a perfectly straight forward way to handle the "create" use case looks like
client POSTs a request to /users/1/reports
the origin server creates a new resource and calculates a new identifier for this resource (/users/1/reports/a)
the server returns a response that indicates that a new resource has been created, the location of that resource, and its current representation.
The indication that a new resource has been created is the status-code: 201.
The location of the newly created resource is described by the Location response header.
The location of the content is described by the Content-Location response header
The current representation is the message body of the response (no surprise).
HTTP/1.1 201 Created
Location: /users/1/reports/a
Content-Location: /users/1/reports/a
...
<representation of the report goes here>
In your case, where the resource already exists, then things look pretty much the same. To avoid implying that we have created a new resource, the status-code is changed to 200, and the Location header is dropped.
HTTP/1.1 200 OK
Content-Location: /users/1/reports/a
...
<representation of the report goes here>
If you prefer that the client retrieve the report representation using the identifier of the previously generated report, then you should use 303 See Other
It is primarily used to allow the output of a POST action to redirect the user agent to a selected resource, since doing so provides the information corresponding to the POST response in a form that can be separately identified, bookmarked, and cached, independent of the original request.
HTTP/1.1 303 See Other
Location: /users/1/reports/a
...
This pattern is commonly referred to as Post/Redirect/Get
i'd use 304 Not Modified in cases where the report is not modified. This should tell everyone, that the ressource didn't change since the last export and normally no further content is transmitted. This could also be used to instead refer to your older results if you cache those. Generally the 304 is not used for posts, but the use of a post to jus trigger the creation of a log can be considered a bit exotic as well.
If the client has performed a conditional GET request and access is allowed, but the document has not been modified, the server SHOULD respond with this status code. The 304 response MUST NOT contain a message-body, and thus is always terminated by the first empty line after the header fields.
RFC containing explanation of the 304 Status Code
If the creation worked i'd send a 201 created and use the location header as pointer to the new file.

BigCommerce API Update Order with PUT

I need to update an order which is done via PUT method passing the order id as part of the https url string and a single parameter, the status_id.
https://mystore.mybigcommerce.com/orders/12345.json
I have tried several methods to pass the status_id value but no matter what I try "status_id=12" or formatted as JSON "{"status_id": 12,}" I always get the same response:
[{"status":415,"message":"The specified input content type is not valid."}]
I have also tried as a POST request passing the JSON or XML code as raw data but that method is not supported.
How am I supposed to pass that field=value pair? can I embed it in the url string?
I also tried it but it wouldn't work for me.
Any ideas?
In case you are wondering I am doing it within FileMaker with TROIUrl plugIn, not a very popular technology, but the GET method retrieving orders works like a charm
TURL_Put( ""; $url ;"status_id=12") (I have also tried other FM plugIns to no avail)
Don't get too caught up in the Filemaker part, I don't expect many people out there to be familiar with BigCommerce and Filemaker. I just need a generic answer.
Thanks
Commandline tool curl is worth a try. It supports put and https.
Mac OS X: curl already installed, call from FileMaker via AppleScript do shell script.
Windows: must be installed, call via Powershell.
It works for me using { "status_id": "3" } which means you probably need to put quotes around the actual number.
Also, it is a PUT operation and application/json which is part of the request content.
The error message received by the OP:
[{"status":415,"message":"The specified input content type is not valid."}]
Is saying that he did not supply the 'Content-Type' header in his request or that the header supplied is for a content type that is not allowed. For the OP's case using JSON he would need to include the header:
Content-Type: application/json
in his HTTPS request. This description can be found along with those of the other status codes you may see here:
https://developer.bigcommerce.com/api/status-codes