1

I am working on emulating an embedded device that is being controlled via HTML commands. The controller issues URLs such as

http://192.168.0.10/cgi-bin/aw_cam?cmd=QFT&res=1

And these affect the device in specific ways. My goal is to make an emulator of the device so I need to capture and handle all such requests. I have successfully configured Apache to call my scripts and I can get access to the "cmd=QFT&res=1" control string by reading the value of QUERY_STRING. I am using Apache 2.4.18 on Ubuntu 16.04.5. The scripts are written in C++.

The problem I am running into is that some of the commands issued by the controller are of the following form:

http://192.168.0.10/cgi-bin/aw_ptz?cmd=#P80&res=1
http://192.168.0.10/cgi-bin/aw_ptz?cmd=#T50&res=1  

For whatever reason, whoever designed the command structure decided to use the # character as part of the command. But since the '#' delimits the fragment part of the URL, the information after it never makes it to my script, which only receives "cmd="

Is there any way to force Apache to pass the entire string after the ? to my scripts? I cannot change the client or the protocol, only the server side.

Edit: The apache log shows the entire URL (see portion of log file below), so even though # is supposed to be a fragment delimiter, it makes it into the log file at least but not the cgi script.

192.168.0.9 - - [27/Jan/2019:00:21:10 +0000] "GET /cgi-bin/aw_ptz?cmd=#P53&res=1 HTTP/1.0" 200 151 "-" "-"
192.168.0.9 - - [27/Jan/2019:00:21:11 +0000] "GET /cgi-bin/aw_ptz?cmd=#P66&res=1 HTTP/1.0" 200 151 "-" "-"
192.168.0.9 - - [27/Jan/2019:00:21:11 +0000] "GET /cgi-bin/aw_ptz?cmd=#P99&res=1 HTTP/1.0" 200 151 "-" "-"
192.168.0.9 - - [27/Jan/2019:00:21:11 +0000] "GET /cgi-bin/aw_ptz?cmd=#P76&res=1 HTTP/1.0" 200 151 "-" "-"
Yiannis
  • 111
  • 4
  • https://stackoverflow.com/a/54041024/1145196 – Dusan Bajic Jan 27 '19 at 09:34
  • Thank you @DusanBajic for pointing out a similar question. However, notice that the apache log shows the full URL so clearly apache has received the entire thing on the server side. In addition, the log does not show a 400 error, so it has been 'accepted'. – Yiannis Jan 27 '19 at 12:33
  • Interesting.. I also see the full URL in my logs, but always get 400 error. What exactly version of Apache are you running? – Dusan Bajic Jan 27 '19 at 14:53
  • Running Apache 2.4.18 on Ubunut 16.04.5. Also, my apache configuration has the entry "HttpProtocoloOptions Unsafe" in it, as the controller sends URLs with hard-coded IP numbers and that was the only way to prevent the server from rejecting all messages (even if they don't contain a #) with a 400 error. – Yiannis Jan 28 '19 at 15:27

1 Answers1

0

This seems to work:

RewriteCond %{THE_REQUEST} \s(.*)#(.*)\s
RewriteRule ^ http://localhost:8000%1#%2 [P,NE]
ProxyPass / http://localhost:8000/
ProxyPassReverse / http://localhost:8000/

(I had python simple http server listening on localhost:8000 to verify if hash was passed correctly

Dusan Bajic
  • 10,249
  • 3
  • 33
  • 43
  • Thank you @DusanBajic, but wow, lots of moving parts here. I finally got mod_rewrite installed, verified it worked by using a simple rule and put the python server on port 8000 but my cgi-scripts now don't get called. The error log shows "No protocol handler was valid for the URL /cgi-bin/man_session. If you are using a DSO version of mod_proxy, make sure the proxy submodules are included in the configuration using LoadModule." Working on this next. – Yiannis Jan 29 '19 at 02:01
  • Wait, I used python only to emulate your scripts so I can verify that solutiin is working. All you need is probably just to add mod_rewrite to apache, and replace `localhost:8000` with ip address and port of your emulator – Dusan Bajic Jan 29 '19 at 05:48