You are viewing a plain text version of this content. The canonical link for it is here.
Posted to bugs@httpd.apache.org by bu...@apache.org on 2004/10/29 10:57:26 UTC

DO NOT REPLY [Bug 31952] New: - mod_proxy and RealPlayer: audio content streaming does not work

DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://issues.apache.org/bugzilla/show_bug.cgi?id=31952>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://issues.apache.org/bugzilla/show_bug.cgi?id=31952

mod_proxy and RealPlayer: audio content streaming does not work

           Summary: mod_proxy and RealPlayer: audio content streaming does
                    not work
           Product: Apache httpd-2.0
           Version: 2.0.52
          Platform: All
        OS/Version: Windows NT/2K
            Status: NEW
          Severity: Normal
          Priority: Other
         Component: mod_proxy
        AssignedTo: bugs@httpd.apache.org
        ReportedBy: ilya_dogadaev@mail.ru


1. Install and configure Apache to act as HTTP proxy
2. Install RealPlayer 10.0
3. Configure RealPlayer to use HTTP proxy installed in 1 (Menu->Tools-
>Preferences->Connection->Proxy->HTTP)
4. Try listening to the e.g. following sites:
http://www.liveireland.com/live.ram
http://www.wksu.org/listen/wksu-rm.ram
5. Content is not delivered to RealPlayer, radio doesn't work

Details:
ICY-over-HTTP
-------------
First site is using ICY-over-HTTP protocol and replies "ICY 200 OK" to apache 
that mod_proxy_http.c fails to understand. The fix follows:
<!--ap_proxy_http_process_response function
if (apr_date_checkmask(buffer, "HTTP/#.# ###*")) {
  //no changes here
}
else if (apr_date_checkmask(buffer, "ICY ###*")) {//FIX FIX FIX
{
  /*this fixes the problem for RP 10.0*/
  /*RP 8.0 still doesn't work because it expects ICY/1.0 reply*/
  /*instead of HTTP/1.x apache provides it with*/
  int ind = 7;
  ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server,
    "proxy: tid=%d ICY response!!!", myGetCurrentThreadId());
  keepchar = buffer[ind];
  buffer[ind] = '\0';
  r->status = atoi(&buffer[ind-3]);
  buffer[ind] = keepchar;
  r->status_line = apr_pstrdup(p, &buffer[ind-3]);
  r->headers_out = ap_proxy_read_headers(r, rp, buffer,
     sizeof(buffer), origin);
  backasswards = 1;
  r->status = 200;
  r->status_line = "200 OK";
}

-->

RTSP-over-HTTP
--------------
Second site is using RTSP-over-HTTP protocol.
The changes required to mod_proxy_http to support this protocol are minimal and 
include the following:
1. POST requests
================
http://developer.apple.com/quicktime/icefloe/dispatch028.html says that POST 
requests specify bogus Content-Length: 32767 while in fact such tunneled RTSP-
over-HTTP POSTS request are not going to end at all, client/proxy should be 
prepared that connection will be just closed after a while, and it MUST NOT 
expect any response from remote server, as this is one-way communication 
channel. So ap_proxy_http_process_response() should not be called for RTSP 
requests:
<!--ap_proxy_http_request
/*...*/
/* send request headers */
const char * ct = apr_table_get(r->headers_in, "Content-Type");
if (r->method_number == M_POST)	{
  if ((ct != NULL) && (stricmp(ct, "application/x-pncmd") == 0)) {
    r->connection->keepalive = AP_CONN_CLOSE;
    /*this is RTSP POST request, remember that!*/
    /*Q: is there any better/more reliable way to*/
    apr_table_set(r->notes, "mod_proxy_http::rtsp_post_request", "1");
  }
}
-->
and then in the beginning of ap_proxy_http_process_response:
<!--ap_proxy_http_process_response
const char * rtsp_post = apr_table_get(
           r->notes, "mod_proxy_http::rtsp_post_request");
if ((rtsp_post != NULL) && ((*rtsp_post) == '1'))
{
  ap_log_error(APLOG_MARK, APLOG_INFO, APR_SUCCESS, r->server,
     "proxy: rtsp post request, no response is expected");
  r->status = HTTP_OK;
  r->status_line = "200 OK";
  p_conn->close += 1;
  return OK;
}
/*...*/
-->

2. GET requests
===============
The problem with mod_proxy is that it tries to buffer the content, while in 
case of audio/video streaming, you have to release the content to destination 
as soon as it's possible, regardless of how small amount of data you got from 
network. The problem was that apache was getting 4 bytes of data, and tried to 
accumulate them instead of sending over to RealPlayer... The fix is to add 
FLUSH bucket to the brigade to make apache send it:
ap_proxy_http_process_response function,
<!--
const char * ct = NULL;
/*...*/
/* send body - but only if a body is expected */
...
if ((!r->header_only) &&                   /* not HEAD request */
  (r->status > 199) &&...)                 /* not any 1xx response */
{
  /*...*/
  ct = apr_table_get(r->headers_out, "Content-Type");
  if ((ct != NULL) && ((stricmp(ct, "audio/x-pn-realaudio") == 0) || 
    (stricmp(ct, "application/x-pncmd") == 0)) {
    flush_rtsp_request = 1;
  }
  /*...*/
}
/*...*/
while (ap_get_brigade(rp->input_filters, ...) == APR_SUCCESS) {
  /*...*/
  /* found the last brigade? */
  if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) {
  /*no changes*/
  }
  else {
    if (flush_rtsp_request == 1) {
      ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
    	"proxy: adding FLUSH bucket, rc=%d", rc);
      e = apr_bucket_flush_create(c->bucket_alloc);
      APR_BRIGADE_INSERT_TAIL(bb, e);
    }
  }
  /* try send what we read */
  rc = ap_pass_brigade(r->output_filters, bb);
  /*...*/
}
						}

3. HTTP protocol should be downgraded to 1.0 as RTSP-over-HTTP is using 
HTTP/1.0.

---------------------------------------------------------------------
To unsubscribe, e-mail: bugs-unsubscribe@httpd.apache.org
For additional commands, e-mail: bugs-help@httpd.apache.org