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.
Are you saying you've hacked it to support your needs? If so, please attach a patch that others can use if they want it - and that any committer who knows the relevant protocols can evaluate.
Created attachment 13258 [details] mod_proxy_http (from 2.0.52) with my fixes added
btw the version of proxy_http.c file attached to this case also fixes http://nagoya.apache.org/bugzilla/show_bug.cgi?id=29644 issue: Fix details: <!--ap_proxy_http_process_response() function /*...*/ /* try send what we read */ rc = ap_pass_brigade(r->output_filters, bb); /*Changed line follows:*/ if (rc != APR_SUCCESS || r->connection->aborted == 1 || origin->aborted == 1) { /*...*/ -->
Thanks. An actual patch would be preferred, but this is broadly equivalent. Adding PatchAvailable keyword. The point of a patch is to highlight diffs. That way we could evaluate whether it appears likely to have side-effects - such as adversely affecting performance for normal proxying - before considering it for inclusion in the httpd codebase. We're more likely to adopt it if you make it easy for us! But it's useful to have it here anyway.
I would really like to see a fix to this problem. I suspect i'm having the same issue trying to proxy requests to my Darwin Streaming Server. The issue is that DSS says it can accept HTTP requests on TCP port 80 (although the default TCP port 554 behaves no differently) but naturally, that conflics with any HTTPD on the same IP. If you *need* to run DSS on the same IP as Apache, but want your users (who may be firewall restricted to outbound port 80) to still get your streams, then you need to proxy the requests. I have been trying unsucessfully to have mod_proxy/mod_proxy_http handle these requests. It would be great to see either a patch to mod_proxy_http, or a new mod_proxy_rtsp. Any suggestions for how to help with this? Thank you! I have DSS set up to listen on 127.0.0.1:554. Apache is listening on external_ip:80. I have put the following in httpd.conf, to no avail. LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_http_module modules/mod_proxy_http.so ProxyRequests Off <Proxy *> Order deny,allow Allow from all </Proxy> <Location /media/> SetEnv force-proxy-request-1.0 1 SetEnv proxy-nokeepalive 1 ProxyPass http://127.0.0.1:554/ ProxyPassReverse http://127.0.0.1:554/ </Location>
Whay happened when you tried Ilya's patches? They don't look at a glance like something that really belongs in the main codebase, but there's nothing to stop you using them. As for a new module, feel free to write one, or pay someone to write one for you.
Thanks for the quick reply Nick. Wish I were clever/rich enough to solve the problem as you describe. As it is, I'm merely a home user trying to serve up some video of my newborn to my wife's family in the UK. I only have one external IP (hey... it's a fixed IP. That must be worth *some* cred). I guess I hoped using mod_proxy_http to proxy the claimed "RTSP over HTTP" claimed by Darwin Streaming Server would tweak some guru's interest. I'm actually surprised it doesn't already work. I very rarely encounter a web content problem of any kind for which Apache httpd hasn't had a module or directive line to solve it. :) I'm currently digging through the "patch" (actually a modified proxy_http.c file, as you know) but unfortunately it is based on 2.0.52 and I have 2.0.54. The fact that Apache's source repository server is down and the mirrors don't carry older source means I can't get the right version to generate a diff at the moment. It looks like there were a fair number of changes from 2.0.52 to 2.0.54. I'll probably wait to get the 2.0.52 version to help generate a diff. If I do figure it out, I'll post a proper diff for 2.0.54. If it doesn't work... oh well. Doesn't sound like it's a big loss to anyone.
Please help us to refine our list of open and current defects; this is a mass update of old and inactive Bugzilla reports which reflect user error, already resolved defects, and still-existing defects in httpd. As repeatedly announced, the Apache HTTP Server Project has discontinued all development and patch review of the 2.2.x series of releases. The final release 2.2.34 was published in July 2017, and no further evaluation of bug reports or security risks will be considered or published for 2.2.x releases. All reports older than 2.4.x have been updated to status RESOLVED/LATER; no further action is expected unless the report still applies to a current version of httpd. If your report represented a question or confusion about how to use an httpd feature, an unexpected server behavior, problems building or installing httpd, or working with an external component (a third party module, browser etc.) we ask you to start by bringing your question to the User Support and Discussion mailing list, see [https://httpd.apache.org/lists.html#http-users] for details. Include a link to this Bugzilla report for completeness with your question. If your report was clearly a defect in httpd or a feature request, we ask that you retest using a modern httpd release (2.4.33 or later) released in the past year. If it can be reproduced, please reopen this bug and change the Version field above to the httpd version you have reconfirmed with. Your help in identifying defects or enhancements still applicable to the current httpd server software release is greatly appreciated.