ossrs / srs

SRS is a simple, high-efficiency, real-time video server supporting RTMP, WebRTC, HLS, HTTP-FLV, SRT, MPEG-DASH, and GB28181.

Home Page:https://ossrs.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

docker-srs:3 cannot obtain return value when using http-api for authentication with srs, authentication fails

yangxiangzhi opened this issue · comments

Using the latest docker-srs:3, I found that when using http-api for authentication, even though the http request status code is 200 and the returned value is 0, I cannot retrieve the returned value from the logs of srs, it is empty. Therefore, the authentication cannot pass. However, I can successfully retrieve the returned value by using Postman to request my own API!

TRANS_BY_GPT3

I have no problem trying it under srs2

TRANS_BY_GPT3

SRS3 cannot be reproduced, the information you provided is too limited, please kindly describe it again following the bug template.

Make sure to maintain the markdown structure.

Configuration:

Make sure to maintain the markdown structure.

listen              1935;
max_connections     1000;
daemon              off;
srs_log_tank        console;
vhost __defaultVhost__ {
    http_hooks {
        enabled         on;
        on_connect      http://ossrs.net:8085/api/v1/clients;
    }
}

Docker startup:

Make sure to maintain the markdown structure.

docker run -p 1935:1935 -p 1985:1985 -p 8080:8080 \
-v `pwd`/srs.conf:/usr/local/srs/conf/srs.conf ossrs/srs:3

Streaming:

Make sure to maintain the markdown structure.

ffmpeg -re -i doc/source.200kbps.768x320.flv -c copy \
  -f flv -y rtmp://127.0.0.1/live/livestream

Success, the log is as follows:

Make sure to maintain the markdown structure.


[2019-12-11 02:56:58.114][Trace][1][664] http: on_connect ok, 
client_id=664, url=http://ossrs.net:8085/api/v1/clients, 
request={"action":"on_connect","client_id":664,"ip":"172.17.0.2","vhost":"__defaultVhost__",
"app":"live","tcUrl":"rtmp://127.0.0.1:1935/live","pageUrl":""}, 
response={"code": 0, "data": null}

TRANS_BY_GPT3

srs.conf configuration:
Make sure to maintain the markdown structure.

listen              1935;
max_connections     1000;
daemon              off;
srs_log_tank        console;
vhost __defaultVhost__ {
    http_hooks {
        enabled         on;
        on_connect      http://docker-nginx/check/publish;
    }
}

The SRS returns the following results:
Make sure to maintain the markdown structure.

[2019-12-11 03:12:52.842][Error][1][746][11] connect error code=3008 : service cycle : rtmp: stream service : check vhos
t : rtmp: callback on connect : rtmp on_connect http://docker-nginx/check/publish : http: on_connect failed, client_id=746, url=http://docker-ng
inx/check/publish, request={"action":"on_connect","client_id":746,"ip":"172.19.0.3","vhost":"__defaultVhost__","app":"live","tcUrl":"rtmp://127.
0.0.1/live","pageUrl":""}, response=, code=200 : http: empty response

From the results, it can be seen that the interface request was successful, but the response is empty. I used PHP for my interface alarm. Attached is my code.
Make sure to maintain the markdown structure.

public function publish()
{
        return 0;
}

This is the result of the Postman request to my interface.
Make sure to maintain the markdown structure.
image

TRANS_BY_GPT3

Can you please use Wireshark to capture the packets? I want to see the request and response. The problem cannot be reproduced on my end, so I need to reproduce it in order to identify the issue.

TRANS_BY_GPT3

I encountered this problem when the interface you wrote did not include Content-Length in the response header.

TRANS_BY_GPT3

2019-12-19 17:09:38.853][Trace][12687][697] dvr stream livestream to file ./objs/nginx/html/live/livestream.1576746578853.mp4
[2019-12-19 17:09:38.869][Warn][12687][697][11] ignore task failed code=3008 : callback on_dvr http://192.168.1.4:18060/camera/callback : http post on_dvr uri failed, client_id=697, url=http://192.168.1.4:18060/camera/callback, request={"action":"on_dvr","client_id":697,"ip":"127.0.0.1","vhost":"__defaultVhost__","app":"live","stream":"livestream","param":"","cwd":"/opt/srs/srs.oschina/trunk","file":"./objs/nginx/html/live/livestream.1576746566836.mp4"}, response=, code=200 : http: empty response
thread [697]: call() [src/app/srs_app_dvr.cpp:571][errno=11]
thread [697]: on_dvr() [src/app/srs_app_http_hooks.cpp:295][errno=11]
thread [697]: do_post() [src/app/srs_app_http_hooks.cpp:509][errno=11]
[2019-12-19 17:09:48.391][Trace][12687][697] <- CPB time=1090049933, okbps=0,0,0, ikbps=4018,4032,4018, mr=0/350, p1stpt=20000, pnt=5000
[2019-12-19 17:09:50.847][Trace][12687][697] dvr stream livestream to file ./objs/nginx/html/live/livestream.1576746590847.mp4
[2019-12-19 17:09:50.870][Warn][12687][697][11] ignore task failed code=3008 : callback on_dvr http://192.168.1.4:18060/camera/callback : http post on_dvr uri failed, client_id=697, url=http://192.168.1.4:18060/camera/callback, request={"action":"on_dvr","client_id":697,"ip":"127.0.0.1","vhost":"__defaultVhost__","app":"live","stream":"livestream","param":"","cwd":"/opt/srs/srs.oschina/trunk","file":"./objs/nginx/html/live/livestream.1576746578853.mp4"}, response=, code=200 : http: empty response
thread [697]: call() [src/app/srs_app_dvr.cpp:571][errno=11]
thread [697]: on_dvr() [src/app/srs_app_http_hooks.cpp:295][errno=11]
thread [697]: do_post() [src/app/srs_app_http_hooks.cpp:509][errno=11]

加上Content-Length' translates to 'Add Content-Length' in English.
image

[2019-12-19 17:13:03.392][Trace][12687][697] <- CPB time=1285059105, okbps=0,0,0, ikbps=4018,4022,4015, mr=0/350, p1stpt=20000, pnt=5000
[2019-12-19 17:13:13.225][Trace][12687][697] dvr stream livestream to file ./objs/nginx/html/live/livestream.1576746793224.mp4
[2019-12-19 17:13:13.252][Trace][12687][697] http hook on_dvr success. client_id=697, url=http://192.168.1.4:18060/camera/callback, request={"action":"on_dvr","client_id":697,"ip":"127.0.0.1","vhost":"__defaultVhost__","app":"live","stream":"livestream","param":"","cwd":"/opt/srs/srs.oschina/trunk","file":"./objs/nginx/html/live/livestream.1576746782823.mp4"}, response={"code": 0, "data": null}
[2019-12-19 17:13:13.392][Trace][12687][697] <- CPB time=1295059342, okbps=0,0,0, ikbps=4020,4017,4015, mr=0/350, p1stpt=20000, pnt=5000
[2019-12-19 17:13:23.392][Trace][12687][697] <- CPB time=1305059522, okbps=0,0,0, ikbps=4019,4017,4015, mr=0/350, p1stpt=20000, pnt=5000

TRANS_BY_GPT3

What are the details of the headers when there is no Content-Length? What is the data format? Can it be captured using Wireshark? Or can you explain how your server code is written?

TRANS_BY_GPT3

image
image
This is the situation when there is no Content-Length.

image
This is the situation when there is Content-Length.

These two return codes only differ by one line.
image

TRANS_BY_GPT3

👍 Understood, it's chunked encoding. Let me check if SRS3 has any issues with this encoding.

TRANS_BY_GPT3

Thank you very much. It turns out that this is indeed the problem. Adding content-length allows the streaming to be successful, but if the content-length is too large, it will wait for a timeout. Setting it to 1 can pass the validation!

TRANS_BY_GPT3

Already confirmed, SRS3 fails to read chunked response.

The TestCase is as follows:

VOID TEST(ProtocolHTTPTest, ClientRequest)
{
    srs_error_t err;

    // Normal case, with chunked encoding.
    if (true) {
        MockBufferIO io; io.append(mock_http_response2(200, "13\r\nHello, world!0\r\n\r\n"));
        SrsHttpParser hp; HELPER_ASSERT_SUCCESS(hp.initialize(HTTP_RESPONSE, false));
        ISrsHttpMessage* msg = NULL; HELPER_ASSERT_SUCCESS(hp.parse_message(&io, &msg));
        string res; HELPER_ASSERT_SUCCESS(msg->body_read_all(res));
        EXPECT_EQ(200, msg->status_code());
        EXPECT_STREQ("Hello, world!", res.c_str());
        srs_freep(msg);
    }
}

TRANS_BY_GPT3

SRS2 is not a problem because it uses header_parsed, but there is an issue with the assignment of this value. It is necessary to read and parse all the headers before it can be accurate, as referenced in Line#1023. Therefore, in the improved SRS3, parsing starts as soon as a bit is received, and this method cannot be used anymore.

After the header is completed, the actual starting point of the body should be identified.

TRANS_BY_GPT3

3.0.76, please try again. If it doesn't work, you can reopen this issue. If it is resolved, please let me know.

TRANS_BY_GPT3

Hello, I tested it yesterday and as @vinsonws mentioned, adding content-length in the API validation can pass the verification. So, now we can also use it for authentication!

TRANS_BY_GPT3

Okay👍.

Can you please test with the new version to see if it can be validated without content-length?

TRANS_BY_GPT3

Hello, last night I tested the latest version and it still cannot pass the validation without content-length!

TRANS_BY_GPT3

Okay, I will set up an environment and give it a try today.

TRANS_BY_GPT3

I built a Go API server that returns chunked encoding. It has been tested without any issues.

package main

import (
	"encoding/json"
	"fmt"
	"net/http"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Transfer-Encoding", "chunked")
		b, _ := json.Marshal(map[string]interface{}{"code": 0})
		w.Write(b)
		w.(http.Flusher).Flush()
	})

	addr := ":8085"
	fmt.Println(fmt.Sprintf("Listen at %v", addr))
	http.ListenAndServe(addr, nil)
}

During debugging, it was discovered that the response is in chunked encoding and does not have a content-length.

(gdb) p *buffer
 p = 0x7ffff7f1a064 "a\r\n{\"code\":0}\r\n0\r\n\r\n",
buffer = 0x7ffff7f1a010 "HTTP/1.1 200 OK\r\nDate: Tue, 24 Dec 2019 06:59:29 GMT\r\nTransfer-Encoding: chunked\r\n\r\na\r\n{\"code\":0}\r\n0\r\n\r\n"

Could you please try again and see if 3.0.80 is available now?

TRANS_BY_GPT3