Http HEAD method

Hello everyone,

I have a CPE model which for the Firmware download does an http HEAD before the http GET.
The http HEAd method is regeted by the nginx server.
How to authorize the http HEAD on the server?

I tried to add this in the default of nginx:

add_header Allow "GET, POST, HEAD" always;
if ( $request_method !~ ^(GET|POST|HEAD)$ ) {
	return 405;
}

but it still doesn’t work.


####
T CPE_IP:42358 -> ACS_IP:7567 [AP] #74
  HEAD /firmware.image HTTP/1.1..Host: ACS_IP:7567..User-Agent: curl/7.66.0..Accept: */*....                                                                                                                                         
##
T ACS_IP:7567 -> CPE_IP:42358 [AP] #76
  HTTP/1.1 405 Method Not Allowed..Allow: GET..Date: Fri, 09 Jun 2023 08:16:44 GMT..Connection: keep-alive..Keep-Alive: timeout=5....                                                                                                                        
####

Thank you in advance for your help.

Laurent

Hello,

Does anyone have an idea ?

Many thanks,

Laurent

Hi fernan06,

I just came across the exact same problem today! I don’t have an ngnix in front of the genieacs-fs. I don’t think it’s your ngnix. I have to investigate further, but now you know, you’re not alone :slight_smile:

There’s your answer:

 % grep -n GET lib/fs.ts
67:  if (request.method !== "GET") {
68:    response.writeHead(405, { Allow: "GET" });

Any chance you’re having FritzBox recently upgraded to 7.50 ?

Hi Spale,

Thank you for your feedback, I’m trying to find a workaround.

Sure enough, I saw if (request.method !== "GET") { in lib/fs.ts
But I didn’t dare to change in the lib.

I thought of mounting a Vhost for the downloads, and the value on GENIEACS_FS_URL_PREFIX=

Final edit :slight_smile:

I was able to patch and test and it works now!

To apply the patch against master:

git clone https://github.com/genieacs/genieacs.git
cd genieacs
git apply ../http-head-patch.diff

To apply the patch against v.1.2.9 tag

git clone https://github.com/genieacs/genieacs.git
cd genieacs
git checkout tags/v1.2.9
git apply ../http-head-patch-1.2.9.diff

PATCH against master branch

diff --git a/lib/fs.ts b/lib/fs.ts
index e1cc5a1..5a6cc1e 100644
--- a/lib/fs.ts
+++ b/lib/fs.ts
@@ -64,8 +64,8 @@ export async function listener(
   request: IncomingMessage,
   response: ServerResponse
 ): Promise<void> {
-  if (request.method !== "GET") {
-    response.writeHead(405, { Allow: "GET" });
+  if (request.method !== "GET" && request.method !== "HEAD") {
+    response.writeHead(405, { Allow: "GET, HEAD" });
     response.end("405 Method Not Allowed");
     return;
   }
@@ -74,7 +74,7 @@ export async function listener(
   const filename = decodeURIComponent(urlParts.pathname.substring(1));

   const log = {
-    message: "Fetch file",
+    message: "Fetch file (" + request.method + ")",
     filename: filename,
     remoteAddress: getRequestOrigin(request).remoteAddress,
   };
@@ -100,9 +100,13 @@ export async function listener(
     "Content-Length": file.length,
   });

-  pipeline(Readable.from(chunks), response, () => {
-    // Ignore errors resulting from client disconnecting
-  });
+  if (request.method === "GET") {
+    pipeline(Readable.from(chunks), response, () => {
+      // Ignore errors resulting from client disconnecting
+    });
+  } else {
+    response.end();
+  }

   logger.accessInfo(log);
 }
 }

PATCH against v.1.2.9 tag

diff --git a/lib/fs.ts b/lib/fs.ts
index f1bf1fb..f662784 100644
--- a/lib/fs.ts
+++ b/lib/fs.ts
@@ -56,8 +56,8 @@ export async function listener(
   request: IncomingMessage,
   response: ServerResponse
 ): Promise<void> {
-  if (request.method !== "GET") {
-    response.writeHead(405, { Allow: "GET" });
+  if (request.method !== "GET" && request.method !== "HEAD") {
+    response.writeHead(405, { Allow: "GET, HEAD" });
     response.end("405 Method Not Allowed");
     return;
   }
@@ -92,6 +92,11 @@ export async function listener(
     "Content-Length": file.length,
   });

-  response.end(buffer);
+  if (request.method === "HEAD") {
+    response.end();
+  }
+  else {
+    response.end(buffer);
+  }
   logger.accessInfo(log);
 }
root@acs:~/genieacs# HEAD http://127.0.0.1:7567/FRITZ.Box_5530-07.50.image
200 OK
Connection: close
Date: Wed, 14 Jun 2023 09:25:50 GMT
Content-Length: 34467840
Content-Type: application/octet-stream
Client-Date: Wed, 14 Jun 2023 09:25:50 GMT
Client-Peer: 127.0.0.1:7567
Client-Response-Num: 1

Hi Spale,

Good news !!!
Thank you very much for your help.

Laurent

Hi Hi,

I’ve created a pull request on the main branch here: Support HEAD requests on fs endpoint by CypressXt · Pull Request #388 · genieacs/genieacs · GitHub.
The backport for the v1.2.9 tag is as well mentioned in the pull request comment.

Let us know how it goes, thanks a lot :smiling_face:

Hello everyone,

Sorry for the late feedback, thanks again to Spale and CypressXt for your help.

Our System team is not available today, I will try to apply the path.
I’m not too comfortable with GIT cmd.

Currently I’m on v1.2.8, GenieACS is installed in /opt/genieacs.
How do I apply the patch (on my production server)?
I don’t want to make big mistakes :sweat_smile:
Thank you in advance for your help.

Good day to you.

Laurent

Hey @fernan06,

You have to build the GenieACS from v1.2.8 again and then deploy it on your prod env.
To do so, the steps are the following: pull the current tag that you’re using, then apply the patch we discussed here and then deploy it on your production server. As a little hint:

git clone https://github.com/genieacs/genieacs
cd genieacs
git checkout -b v1.2.8
## Apply the patch here by editing the proper file
npm install
npm run build

Your patched build will then be found under ./dist/bin/ in the genieacs folder. To deploy on prod copy those “bin” files on your production server and run them.

Regards

Thanks so much, I will try