HTTP Request to Stop or Terminate MJPEG streaming - c++

I have written the MJPEG streaming server on HTTP. My HTTP server receives the request and sends the MJPEG. So far it is working fine. I am using C++ and POCO library.
The problem that I don't know when to stop the streaming. On stopping the browsing from browser (firefox) it sends same request as when requesting the stream. I used fiddler and following is the HTTP request while requesting and stopping the browser.
Requesting the MJPEG from browser (firefox):
GET http://mymjpegserver.com?vms=dvtel&deviceid=1&rgb=true&server=10.8.10.80&userid=admin&password= HTTP/1.1
Host: 10.1.39.7:8081
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:37.0) Gecko/20100101 Firefox/37.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Stopping the streaming from browser (firefox) by clicking on cross "x" button
GET http://mymjpegserver.com?vms=dvtel&deviceid=1&rgb=true&server=10.8.10.80&userid=admin&password= HTTP/1.1
Host: 10.1.39.7:8081
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:37.0) Gecko/20100101 Firefox/37.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
And then after few moments when ever I switch browser tabs or window it sends following request
GET http://mymjpegserver.com?vms=dvtel&deviceid=1&rgb=true&server=10.8.10.80&userid=admin&password= HTTP/1.1
Host: 10.1.39.7:8081
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:37.0) Gecko/20100101 Firefox/37.0
Accept: image/png,image/*;q=0.8,*/*;q=0.5
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
That is only Accept value is changed to "image/png...". But, I can not use this Accept value to differentiate the termination, since this request is only sent when the Tab/Window is switched.
And on closing the Tab, nothing sent to the Http Server.
My question is, how on Web Server I can check the request to stop the streaming?

Related

Blazor Server Side - Frequent 504 errors in AWS environment

After deploying a blazor server side project to an Amazon Web Services environment via AWS Elastic Beanstalk, the website experiences frequent disconnects that I do not understand.
These disconnects do not happen locally when testing.
Errors:
[2020-04-30T16:29:18.326Z] Error: Connection disconnected with error 'Error'.
and
Failed to load resource: the server responded with a status of 504 ()
The request causing the 504 errors has a header like so:
Request URL: https://mywebserver/_blazor?id=UOPQELxzuEcaGbpNUQA01Q&_=1588264098305
Request Method: GET
Status Code: 504
Remote Address: 3.11.236.203:443
Referrer Policy: no-referrer-when-downgrade
content-length: 550
content-type: text/html
date: Thu, 30 Apr 2020 16:29:20 GMT
server: awselb/2.0
status: 504
:authority: mywebserver
:method: GET
:path: /_blazor?id=UOPQELxzuEcaGbpNUQA01Q&_=1588264098305
:scheme: https
accept: */*
accept-encoding: gzip, deflate, br
accept-language: en-GB,en-US;q=0.9,en;q=0.8
content-type: text/plain;charset=UTF-8
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: same-origin
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36
x-requested-with: XMLHttpRequest
This issue seems remarkably similar to a Github issue posted here, that is currently being investigated by Microsoft, although this issue is not AWS-related: https://github.com/dotnet/aspnetcore/issues/19094
Any help would be vastly appreciated!
i managed to fix this in the end.
Apparently the issue was caused by the use of LongPolling. LongPolling issues requests and waits 100 seconds before cancelling the request. By setting the timeout to be greater than the default of 60 seconds in the Elastic Load Balancer in my AWS settings, the disconnects stopped. 110 seconds was recommended as a safe timeout value.
Issue on Asp.NET github that I opened for those interested: https://github.com/dotnet/aspnetcore/issues/21369

QWebSocket can't process the handshake

I have a problem with establishing a WebSocket connection using QWebSocket. I'm using Qt 5.6 and its QWebSocket implementation. I'm sure that server works right and uses WS v13 protocol. It works fine with all browsers. When I try to connect to the server, QWebSocket emits error and stateChanged signals with these messages (I get them using errorString() method):
QWebSocketPrivate::processHandshake: Connection closed while reading header.
Invalid statusline in response: Upgrade: websocket
Invalid statusline in response: Connection: Upgrade
Invalid statusline in response: Sec-WebSocket-Accept: HLaITyncgax+CH7OUIXnsCfFDDY=
Invalid statusline in response: // there's a carriage return symbol
Although it says Connection closed while reading header, connection isn't actually closed (because server sends additional packets through websocket after a while). I've tested my application on websocket.org's echo test and it works fine! But I sniffed the packets on both tries and didn't find any significant differences.
Result of packet sniffing on the server which I try to connect to:
GET / HTTP/1.1
Host: <hostname>:6670
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: WcIsYc1AZ6CKikXFwGXgMg==
Origin: http://<hostname>
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0
Connection: keep-alive, Upgrade
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: 7lfSGmSz/eW1mSzaMnuzOqg00w4=
Result of packet sniffing on connection with echo.websocket.org:
GET / HTTP/1.1
Host: echo.websocket.org:80
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: MUAZoP0Ef4KSWkmtsB5YDw==
Origin: http://<hostname>
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0
Connection: keep-alive, Upgrade
HTTP/1.1 101 Web Socket Protocol Handshake
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: content-type
Access-Control-Allow-Headers: authorization
Access-Control-Allow-Headers: x-websocket-extensions
Access-Control-Allow-Headers: x-websocket-version
Access-Control-Allow-Headers: x-websocket-protocol
Access-Control-Allow-Origin: http://<hostname>
Connection: Upgrade
Date: Thu, 31 Mar 2016 12:05:49 GMT
Sec-WebSocket-Accept: c4yAe+A1VRuhF1LSC/TGgPoa8N4=
Server: Kaazing Gateway
Upgrade: websocket
<data exchange goes here normally>
What should I do to investigate and fix the problem? I have no access to the server.
P.S. Yes, I'm aware of QTBUG-40878. It affects Qt 5.3.1 but I use 5.6.0 and it has been obviously fixed in my Qt setup.
This may be QTBUG-51069 (which is not the one you mentioned):
If there is a delay between status line ("HTTP/1.1 101 Upgrading Protocol") and headers, QWebSocketPrivate::processHandshake erroneously detects server disconnect. The problem is that disconnect condition is checked using QAbstractSocket::atEnd function which just checks if data available and not the actual socket state. This results in multiple error signals:
websocket error: QWebSocket::processHandshake: Connection closed while reading header.
websocket error: Invalid statusline in response: Date: Thu, 11 Feb 2016 20:07:37 GMT^M .
websocket error: Invalid statusline in response: Server: WSGIServer/0.1 Python/2.7.10^M .
websocket error: Invalid statusline in response: Upgrade: websocket^M .
websocket error: Invalid statusline in response: Connection: Upgrade^M .
websocket error: Invalid statusline in response: Sec-WebSocket-Accept: oQ+NK56UdGrsXFisB9chjE3SU+Y=^M .
websocket error: Invalid statusline in response: Sec-WebSocket-Version: 13^M .
websocket error: Invalid statusline in response: Content-Length: 0^M .
websocket error: Invalid statusline in response: ^M .
The fix is in Qt 5.6.2.
For Qt 5.7, judging from the commit history I think it will be in 5.7.1.

WSO2 APIM gateway is setting Host header as host:port

APIM gateway is setting Host header as host:port to call backend, like this:
GET /api/category HTTP/1.1 Accept-Language:
en-US,en;q=0.8,pt;q=0.6 token:
6785ea7b-#######-#######-93f06834660a Accept-Encoding: gzip,
deflate, sdch X-Forwarded-Server: server01 X-Forwarded-For:
172.XX.XXX.XX User-Agent: Mozilla/5.0 (X11; Linux x86_64) Postman-Token: ece4261e-d610-655c-f06c-f24a99f007c8 Accept:
/ X-Forwarded-Host: server01 Cache-Control: no-cache
Host: api.empresa.net:80 Connection: Keep-Alive
This causes problems with Web Application Firewall, how can I change this?
Enviroment: RedHat Linux 6.7, APIM 1.9.1
Thanks
I know your pain. We were running into the same problem with our load balancer. I believe there is a fix coming from WSO2 for this. In the meantime, you will need to create a custom "in" sequence under "/_system/governance/apimgt/customsequences/in" with the following content:
<sequence xmlns="http://ws.apache.org/ns/synapse" name="remove_port_In">
<property name="REQUEST_HOST_HEADER" value="api.empresa.net" scope="axis2"/>
</sequence>
You can then associate this with your API as an inbound custom sequence through the publisher application prior to publishing.
As per the protocol specification,
The Host request-header field specifies the Internet host and port
number of the resource being requested, as obtained from the original
URI given by the user or referring resource.
Host = "Host" ":" host [ ":" port ] ; Section 3.2.2
A "host" without any trailing port information implies the default
port for the service requested (e.g., "80" for an HTTP URL). For
example, a request on the origin server for
http://www.w3.org/pub/WWW/ would properly include:
GET /pub/WWW/ HTTP/1.1
Host: www.w3.org

How to parse USER-AGENT field in http header using regex?

I want to parse some information from the User-Agent: HTTP header. The problem is that I'm getting two User-Agent: HTTP headers in the same HTTP Request:
CONNECT www.facebook.com:443 HTTP/1.1
Host: www.facebook.com
Proxy-Connection: keep-alive
User-Agent: Mozilla/5.0 (http://iim.com/a.jph) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.
CONNECT www.facebook.com:443 HTTP/1.1
Host: www.facebook.com
Proxy-Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.
CONNECT www.facebook.com:443 HTTP/1.1
I want the regex to match the non-http portion e.g Windows NT 6.1; WOW64. The flow analyzer software I'm using java regex engine.
My attempts
User-Agent:\s+.*?\((.*?)\)
Its matching both; I want to skip http portion of it.
Use a negative lookahead to prevent the match of http:
User-Agent:\s+.*?\((?!http)(.*?)\)
Though you might want to change the .*? to negated classes:
User-Agent:[^(]+\((?!http)([^)]+)\)

MS Http Server API (< Win 8) and WebSockets

I try to realize WebSocket protocol at MS Http Server API under win server 2008 (haven't HTTP_SEND_RESPONSE_FLAG_OPAQUE flag).
HTTP_RESPONSE response={0};
const char upgrade_val[]="Websocket";
response.Headers.KnownHeaders[HttpHeaderUpgrade].RawValueLength=strlen(upgrade_val);
response.Headers.KnownHeaders[HttpHeaderUpgrade].pRawValue =upgrade_val;
const char connection_val[]="Upgrade";
response.Headers.KnownHeaders[HttpHeaderConnection].RawValueLength=strlen(connection_val);
response.Headers.KnownHeaders[HttpHeaderConnection].pRawValue =connection_val;
HTTP_UNKNOWN_HEADER unknown[1];
response.Headers.UnknownHeaderCount=1;
response.Headers.pUnknownHeaders =unknown;
const char accept_name[]="Sec-WebSocket-Accept";
unknown[0].NameLength =_countof(accept_name)-1;
unknown[0].pName =accept_name;
unknown[0].RawValueLength=HANDSHAKE_KEY_LENGTH;
unknown[0].pRawValue =base64_key;
response.Version.MajorVersion=1;
response.Version.MinorVersion=1;
response.StatusCode =HTTP_SWITCHING_PROTOCOLS;
const char reason[] ="Switching Protocols";
response.ReasonLength =strlen(reason);
response.pReason =reason;
HttpSendHttpResponse(iocp,RequestId,HTTP_SEND_RESPONSE_FLAG_MORE_DATA,&raw_response,NULL,NULL,NULL,NULL,NULL,NULL);
Browser send header (from Fiddler)
GET http://server.host/ HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: server.host
Origin: null
Pragma: no-cache
Cache-Control: no-cache
Sec-WebSocket-Key: V86c1TFOwWfZqhS42C0arA==
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: x-webkit-deflate-frame
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36
server's response (from Fiddler)
HTTP/1.1 101 Switching Protocols
Upgrade: Websocket
Server: Microsoft-HTTPAPI/2.0
Sec-WebSocket-Accept: 3io2SU7uJIeFlwy0+OFJUDNrA44=
Date: Tue, 28 May 2013 09:27:59 GMT
EndTime: 13:27:59.006
ReceivedBytes: 0
SentBytes: 0
and browser shows 1016 error.
Assuming your Sec-WebSocket-Accept header value is calculated correctly, and assuming your response variable is supposed to be named raw_response instead, then your response is missing the required Connection: Upgrade header despite your code assigning a value for it.
HTTP_SEND_RESPONSE_FLAG_OPAQUE (Windows 8 and later) is required for WebSockets.
WebSocket servers on Windows Server (2011-12-20)
As it stands right now, Server 2008/R2 boxes cannot host WebSockets.
At least, not whilst sharing ports 80 and 443 with IIS web server
Re: [hybi] WebSocket protocol as it stands (2010-11-06)
we need to tweak http.sys to recognize what is really a non-HTTP
request, as an HTTP request