Peter Hartley's patch for "extra-headers".

git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@299 119443c7-1b9e-41f8-b6fc-b9c35fce742c
This commit is contained in:
Marcelo Roberto Jimenez 2008-01-25 05:04:36 +00:00
parent c24997917a
commit 77f1cff5d5
3 changed files with 56 additions and 11 deletions

View File

@ -2,6 +2,37 @@
Version 1.6.4
*******************************************************************************
2008-01-23 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* Peter Hartley's patch for "extra-headers". In his words:
Hi there,
The attached patch adds an "extra_headers" field to the libupnp web
server's File_Info structure, allowing VirtualDirCallbacks to, if they
choose, specify extra HTTP headers to be sent back in the response. The
string lifetime strategy is the same as that of the content_type field
in the same structure: caller does ixmlCloneDOMString, callee does
ixmlFreeDOMString.
Again this is aimed at supporting Rio Receiver service as well as UPnP
service in the same web server. The Receiver firmware has an unfortunate
bug whereby it does a case-sensitive comparison looking for a
"Content-Length" header. As libupnp sends "CONTENT-LENGTH", it doesn't
work out of the box. So I thought about changing libupnp to send the
version Receivers expect, but it's a bit inelegant IMO to change
specifics of a general-purpose library for the benefit of one client --
plus, it might break existing clients of libupnp. Instead, I suggest
this patch, which lets the Receiver server (only) choose to send an
additional "Content-Length" header. Other clients/servers are not
impacted, and indeed other users of libupnp might even find the facility
useful for their own purposes.
As the extra_headers field is added at the end of the File_Info
structure, and as (at least in the normal course of events) File_Info
structures are never allocated except by libupnp itself, this hopefully
doesn't count as an ABI or API change.
Peter
2008-01-23 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* Workaround for a problem with the new automake AM_CONDITIONAL macro
from autotools-1.10. Thanks to Ingo Hofmann for helping with debugging

View File

@ -930,9 +930,13 @@ struct File_Info
/** The content type of the file. This string needs to be allocated
* by the caller using {\bf ixmlCloneDOMString}. When finished
* with it, the SDK frees the {\bf DOMString}. */
DOMString content_type;
/** Additional HTTP headers to return. This string needs to be allocated
* by the caller using {\bf ixmlCloneDOMString}. When finished
* with it, the SDK frees the {\bf DOMString}. Each header line should be
* followed by "\r\n". */
DOMString extra_headers;
};
/* The type of handle returned by the web server for open requests. */

View File

@ -1221,6 +1221,7 @@ process_request( IN http_message_t * req,
// init
request_doc = NULL;
finfo.content_type = NULL;
finfo.extra_headers = NULL;
alias_grabbed = FALSE;
err_code = HTTP_INTERNAL_SERVER_ERROR; // default error
using_virtual_dir = FALSE;
@ -1387,18 +1388,22 @@ process_request( IN http_message_t * req,
goto error_handler;
}
const char *extra_headers = finfo.extra_headers ? finfo.extra_headers
: "";
if( RespInstr->IsRangeActive && RespInstr->IsChunkActive ) {
// Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT
// Transfer-Encoding: chunked
if (http_MakeMessage(
headers, resp_major, resp_minor,
"R" "T" "GKD" "s" "tcS" "XcCc",
"R" "T" "GKD" "s" "tcS" "Xc" "sCc",
HTTP_PARTIAL_CONTENT, // status code
finfo.content_type, // content type
RespInstr, // range info
"LAST-MODIFIED: ",
&finfo.last_modified,
X_USER_AGENT) != 0 ) {
X_USER_AGENT,
extra_headers) != 0 ) {
goto error_handler;
}
} else if( RespInstr->IsRangeActive && !RespInstr->IsChunkActive ) {
@ -1407,14 +1412,15 @@ process_request( IN http_message_t * req,
// Transfer-Encoding: chunked
if (http_MakeMessage(
headers, resp_major, resp_minor,
"R" "N" "T" "GD" "s" "tcS" "XcCc",
"R" "N" "T" "GD" "s" "tcS" "Xc" "sCc",
HTTP_PARTIAL_CONTENT, // status code
RespInstr->ReadSendSize, // content length
finfo.content_type, // content type
RespInstr, // range info
"LAST-MODIFIED: ",
&finfo.last_modified,
X_USER_AGENT) != 0 ) {
X_USER_AGENT,
extra_headers) != 0 ) {
goto error_handler;
}
@ -1423,12 +1429,13 @@ process_request( IN http_message_t * req,
// Transfer-Encoding: chunked
if (http_MakeMessage(
headers, resp_major, resp_minor,
"RK" "TD" "s" "tcS" "XcCc",
"RK" "TD" "s" "tcS" "Xc" "sCc",
HTTP_OK, // status code
finfo.content_type, // content type
"LAST-MODIFIED: ",
&finfo.last_modified,
X_USER_AGENT) != 0 ) {
X_USER_AGENT,
extra_headers) != 0 ) {
goto error_handler;
}
@ -1438,13 +1445,14 @@ process_request( IN http_message_t * req,
// Transfer-Encoding: chunked
if (http_MakeMessage(
headers, resp_major, resp_minor,
"R" "N" "TD" "s" "tcS" "XcCc",
"R" "N" "TD" "s" "tcS" "Xc" "sCc",
HTTP_OK, // status code
RespInstr->ReadSendSize, // content length
finfo.content_type, // content type
"LAST-MODIFIED: ",
&finfo.last_modified,
X_USER_AGENT) != 0 ) {
X_USER_AGENT,
extra_headers) != 0 ) {
goto error_handler;
}
} else {
@ -1452,12 +1460,13 @@ process_request( IN http_message_t * req,
// Transfer-Encoding: chunked
if (http_MakeMessage(
headers, resp_major, resp_minor,
"R" "TD" "s" "tcS" "XcCc",
"R" "TD" "s" "tcS" "b" "Xc" "sCc",
HTTP_OK, // status code
finfo.content_type, // content type
"LAST-MODIFIED: ",
&finfo.last_modified,
X_USER_AGENT) != 0 ) {
X_USER_AGENT,
extra_headers) != 0 ) {
goto error_handler;
}
}
@ -1486,6 +1495,7 @@ process_request( IN http_message_t * req,
error_handler:
free( request_doc );
ixmlFreeDOMString( finfo.content_type );
ixmlFreeDOMString( finfo.extra_headers );
if( err_code != UPNP_E_SUCCESS && alias_grabbed ) {
alias_release( alias );
}