ossrs / srs

SRS is a simple, high-efficiency, real-time media server supporting RTMP, WebRTC, HLS, HTTP-FLV, HTTP-TS, SRT, MPEG-DASH, and GB28181.
https://ossrs.io
MIT License
25.37k stars 5.34k forks source link

Malformed HTTP Callback Request HTTP回调请求HTTP协议有问题?' translates to: 'Malformed HTTP Callback Request. Is there an issue with the HTTP protocol? #1610

Closed GammaPi closed 3 years ago

GammaPi commented 4 years ago

Description'

Please ensure that the markdown structure is maintained.

Please describe the issue you encountered here. ' Make sure to maintain the markdown structure.

Python standard library's httpserver prompt: ' Make sure to maintain the markdown structure.

authserver_1  | 172.20.0.2 - - [16/Feb/2020 08:28:26] code 400, message Bad HTTP/0.9 request type ('POST')
authserver_1  | 172.20.0.2 - - [16/Feb/2020 08:28:26] "POST  HTTP/1.1" 400 -

Expected behavior (Expect) ' Make sure to maintain the markdown structure.

It's strange that the HTTP 0.9 standard does not have POST. According to the prompt, SRS used HTTP 0.9, but the type is POST?

TRANS_BY_GPT3

GammaPi commented 4 years ago

https://github.com/ossrs/srs/blob/1583f6cc3f78254ac40da0805051efa837333cf3/trunk/research/api-server/server.py There are available callback implementations that can be modified to run in the Py3.* environment, and the interface is also easily expandable. But why am I experiencing this problem when using the standard library's httpserver?

exp#!/usr/bin/env python

from http.server import     BaseHTTPRequestHandler, HTTPServer
import json

# HTTPRequestHandler class
class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
    protocol_version = 'HTTP/0.9'
    tokenDict={}
    # GET
    def do_GET(self):
        print('GET')
        # Send response status code
        self.send_response(200)

        # Send headers
        self.send_header('Content-type','text/plain')
        self.end_headers()

        # Send message back to client
        message = "SRS Auth Server"
        # Write content as utf-8 data
        self.wfile.write(bytes(message, "utf8"))
        return

    def do_POST(self):
        print('POST')
        contentLen = int(self.headers.get('Content-Length'))
        postBody = self.rfile.read(contentLen)

        jsonData=json.loads(postBody)

        returnCode=0

        try:
            action=jsonData['action']
            print(action,action['client_id'])
            if action=='on_connect':
                passKey=jsonData['tcUrl'].find('?key=')+5

        except BaseException as e:
            returnCode=-1
            print(str(e))

        # Send headers
        self.send_header('Content-type','text/plain')
        self.end_headers()
        # Send message back to client
        message = str(returnCode)
        # Write content as utf-8 data
        self.wfile.write(bytes(message, "utf8"))
        return

def run():
    print('starting server...')

    # Server settings
    # Choose port 8080, for port 80, which is normally used for a http server, you need root access
    server_address = ('0.0.0.0', 80)
    httpd = HTTPServer(server_address, testHTTPServer_RequestHandler)
    print('running server...')
    httpd.serve_forever()

run()

TRANS_BY_GPT3

hashworks commented 3 years ago

Could we re-open this? The issue is still valid. The HTTP Callback sends a malformed request. The server code @GammaPi posted should work just fine.

hashworks commented 3 years ago

@GammaPi The issue appears when one doesn't set an HTTP path like '/'. Also, one has to set a Content-Length.

Working Python3 Callback Server:

#!/bin/env python3

from http.server import HTTPServer, BaseHTTPRequestHandler
import json

class Error:
    success = 0
    failure = 1
    system_parse_json = 100

class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        code = Error.success

        try:
            contentLen = int(self.headers.get('Content-Length'))
            postBody = self.rfile.read(contentLen)
            jsonData=json.loads(postBody)
        except Exception:
            code = Error.system_parse_json

        print(jsonData)

        response = bytes(json.dumps({"code": code, "data": None}), "UTF-8")

        self.send_response(200)
        self.send_header("Content-Type", "application/json")
        self.send_header("Content-Length", len(response))
        self.end_headers()
        self.wfile.write(response);

server = HTTPServer(("", 59354), SimpleHTTPRequestHandler)

print("Serving on port 59354");

server.serve_forever()