SF Tracker [ 1634922 ] Support for large files (>= 2 GiB), part 2

Submitted By: Jonathan - no_dice
Summary: This patch hopefully fixes the remaining types and related
code to enable files >= 2 GiB to be streamed. Jonathan claims to have
tested this with a patched version of ushare-0.9.8 and a D-Link DSM-520.



git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@121 119443c7-1b9e-41f8-b6fc-b9c35fce742c
This commit is contained in:
Marcelo Roberto Jimenez
2007-01-23 13:22:52 +00:00
parent cab8e4f799
commit f64c539395
4 changed files with 138 additions and 105 deletions

View File

@@ -2,6 +2,52 @@
Trunk Trunk
************************************************************************* *************************************************************************
2007-01-23 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* SF Tracker [ 1634922 ] Support for large files (>= 2 GiB), part 2
Submitted By: Jonathan - no_dice
Summary: This patch hopefully fixes the remaining types and related
code to enable files >= 2 GiB to be streamed. Jonathan claims to have
tested this with a patched version of ushare-0.9.8 and a D-Link DSM-520.
2007-01-09 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* SF Tracker [ 1628629 ] Multicast interface patch
Submitted By: Fredrik Svensson - svefredrik
This patch fixes two problems:
1) Specify the IP address for the interface when we do
setsockopt IP_ADD_MEMBERSHIP. This makes it possible to run
when no default router has been configured.
2) Explicitly set the multicast interface through setsockopt
IP_MULTICAST_IF. Avoids socket error -207 in some cases.
* SF Tracker [ 1628590 ] XML parsing segfault patch
Submitted By: Fredrik Svensson - svefredrik
This patch fixes a segmentation fault problem that occurrs
when parsing XML code than some routers produce.
2007-01-06 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* SF Tracker [ 1628552 ] XML white space patch
Submitted By: Fredrik Svensson - svefredrik
* SF Tracker [ 1628562 ] Maximum total jobs patch
Submitted By: Fredrik Svensson - svefredrik
Also, I incremented the libray versions and included some
comments in the file configure.ac so that we do not bump
the library version excessively, only the necessary numbers
on the next release.
* SF Tracker [ 1628575 ] Linksys WRT54G patch
Submitted By: Fredrik Svensson - svefredrik
* SF Tracker [ 1628636 ] SSDP packet copy patch
Submitted By: Fredrik Svensson - svefredrik
Changed NUM_COPY to 1 since, according to section 9.2 of the
HTTPU/MU spec, we should never send more than one copy of a
reply to an SSDP request. Ref. section 9.2 of
http://www.upnp.org/download/draft-goland-http-udp-04.txt
2006-12-23 Marcelo Jimenez <mroberto(at)users.sourceforge.net> 2006-12-23 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* Thorough revision of every call of http_MakeMessage() due to a * Thorough revision of every call of http_MakeMessage() due to a
@@ -10,40 +56,34 @@ Trunk
interface. In rev.79, the "N" format parameter must be an off_t. interface. In rev.79, the "N" format parameter must be an off_t.
Every call of this function with an "N" format parameter and an Every call of this function with an "N" format parameter and an
int passed on the stack would fail terribly. int passed on the stack would fail terribly.
* SF Bug tracker [ 1590469 ]
Typo in ixmlparser.c
Submitted By: Erik Johansson - erijo
* SF Bug Tracker [ 1590466 ] Invalid xml output
Submitted By: Erik Johansson - erijo
* SF Patch tracker [ 1581161 ] VStudio2005 patch
Submitted By: David Maass - darkservant
* SF Patch tracker [ 1587272 ] const-ified ixml
Submitted By: Erik Johansson
* Finished const-ifications as suggested by Erik Johansson in
SF Patch tracker [ 1587272 ].
2006-07-05 Nektarios K. Papadopoulos <npapadop(at)inaccessnetworks.com>
* [bug-id] 1580440
[submitted-by] Erik Johansson - erijo
[patched-by] Erik Johansson - erijo
The SOAP HTTP message that's generated on upnp errors
is missing a \r\n\ between header and body.
2006-07-07 Oxy <virtual_worlds(at)gmx.de> 2006-07-07 Oxy <virtual_worlds(at)gmx.de>
* support for large files (>2 GBytes) added * support for large files (>2 GBytes) added
*************************************************************************
Version 1.4.2
*************************************************************************
2006-12-23 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* Finished const-ifications as suggested by Erik Johansson in
SF Patch tracker [ 1587272 ].
2006-12-23 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* Erik Johansson's patch for const-ified ixml
SF Patch tracker [ 1587272 ].
2006-12-23 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* David Maass's patch for VStudio2005 compilation failure.
SF Patch tracker [ 1581161 ].
2006-12-23 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* Erik Johansson's patch for invalid xml output.
SF Bug Tracker [ 1590466 ].
2006-12-23 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* Erik Johansson's patch for typo in ixmlparser.c.
SF Bug tracker [ 1590469 ].
************************************************************************* *************************************************************************
Version 1.4.1 Version 1.4.1
@@ -97,10 +137,13 @@ Version 1.4.0
2006-05-18 Oxy <virtual_worlds(at)gmx.de> 2006-05-18 Oxy <virtual_worlds(at)gmx.de>
* DSM-320 patch added (fetched from project MediaTomb) * DSM-320 patch added (fetched from project MediaTomb)
* httpGet additons atch added, Added proxy support by introducing * httpGet additons atch added, Added proxy support by introducing
UpnpOpenHttpGetProxy. UpnpOpenHttpGet now just calls UpnpOpenHttpGetProxy. UpnpOpenHttpGet now just calls
UpnpOpenHttpGetProxy with the proxy url set to NULL. UpnpOpenHttpGetProxy with the proxy url set to NULL.
* Bugfix for typo ("\0" / "0") in ixmlparser.c * Bugfix for typo ("\0" / "0") in ixmlparser.c
* Bugfix for M-Search packet * Bugfix for M-Search packet
************************************************************************* *************************************************************************

3
THANKS
View File

@@ -15,13 +15,14 @@ exempt of errors.
- Fredrik Svensson - Fredrik Svensson
- Jiri Zouhar - Jiri Zouhar
- John Dennis - John Dennis
- Jonathan (no_dice)
- Leuk_He - Leuk_He
- Loigu - Loigu
- Marcelo Roberto Jimenez - Marcelo Roberto Jimenez
- Markus Strobl - Markus Strobl
- Nektarios K. Papadopoulos - Nektarios K. Papadopoulos
- Oskar Liljeblad - Oskar Liljeblad
- Oxy - Michael (Oxy)
- Paul Vixie - Paul Vixie
- Siva Chandran - Siva Chandran

View File

@@ -306,8 +306,8 @@ http_SendMessage( IN SOCKINFO * info,
char *filename = NULL; char *filename = NULL;
FILE *Fp; FILE *Fp;
int num_read, int num_read,
num_written, num_written;
amount_to_be_read = 0; off_t amount_to_be_read = 0;
va_list argp; va_list argp;
char *file_buf = NULL, char *file_buf = NULL,
*ChunkBuf = NULL; *ChunkBuf = NULL;
@@ -1769,27 +1769,29 @@ http_SendStatusResponse( IN SOCKINFO * info,
* specified in the input parameters. * specified in the input parameters.
* *
* fmt types: * fmt types:
* 's': arg = const char* C_string * 'B': arg = int status_code
* appends content-length, content-type and HTML body for given code
* 'b': arg1 = const char* buf; arg2 = size_t buf_length * 'b': arg1 = const char* buf; arg2 = size_t buf_length
* memory ptr * memory ptr
* 'c': (no args) appends CRLF "\r\n"
* 'd': arg = int number // appends decimal number
* 'h': arg = off_t number // appends off_t number
* 't': arg = time_t * gmt_time // appends time in RFC 1123 fmt
* 'D': (no args) appends HTTP DATE: header
* 'S': (no args) appends HTTP SERVER: header
* 'U': (no args) appends HTTP USER-AGENT: header
* 'C': (no args) appends a HTTP CONNECTION: close header * 'C': (no args) appends a HTTP CONNECTION: close header
* depending on major,minor version * depending on major,minor version
* 'c': (no args) appends CRLF "\r\n"
* 'D': (no args) appends HTTP DATE: header
* 'd': arg = int number // appends decimal number
* 'G': arg = range information // add range header
* 'h': arg = off_t number // appends off_t number
* 'K': (no args) // add chunky header
* 'N': arg1 = int content_length // content-length header * 'N': arg1 = int content_length // content-length header
* 'q': arg1 = http_method_t, arg2 = (uri_type *) // request start line and HOST header * 'q': arg1 = http_method_t, arg2 = (uri_type *) // request start line and HOST header
* 'Q': arg1 = http_method_t; arg2 = char* url; * 'Q': arg1 = http_method_t; arg2 = char* url;
* arg3 = int url_length // start line of request * arg3 = int url_length // start line of request
* 'R': arg = int status_code // adds a response start line * 'R': arg = int status_code // adds a response start line
* 'B': arg = int status_code * 'S': (no args) appends HTTP SERVER: header
* appends content-length, content-type and HTML body for given code * 's': arg = const char* C_string
* 'T': arg = char * content_type; format e.g: "text/html"; * 'T': arg = char * content_type; format e.g: "text/html";
* content-type header * content-type header
* 't': arg = time_t * gmt_time // appends time in RFC 1123 fmt
* 'U': (no args) appends HTTP USER-AGENT: header
* 'X': arg = const char useragent; "redsonic" HTTP X-User-Agent: useragent * 'X': arg = const char useragent; "redsonic" HTTP X-User-Agent: useragent
* *
* Return : int; * Return : int;

View File

@@ -871,8 +871,8 @@ StrTok( char **Src,
************************************************************************/ ************************************************************************/
int int
GetNextRange( char **SrcRangeStr, GetNextRange( char **SrcRangeStr,
int *FirstByte, off_t *FirstByte,
int *LastByte ) off_t *LastByte )
{ {
char *Ptr, char *Ptr,
*Tok; *Tok;
@@ -936,11 +936,11 @@ GetNextRange( char **SrcRangeStr,
************************************************************************/ ************************************************************************/
int int
CreateHTTPRangeResponseHeader( char *ByteRangeSpecifier, CreateHTTPRangeResponseHeader( char *ByteRangeSpecifier,
long FileLength, off_t FileLength,
OUT struct SendInstruction *Instr ) OUT struct SendInstruction *Instr )
{ {
int FirstByte, off_t FirstByte,
LastByte; LastByte;
char *RangeInput, char *RangeInput,
*Ptr; *Ptr;
@@ -984,26 +984,26 @@ CreateHTTPRangeResponseHeader( char *ByteRangeSpecifier,
Instr->RangeOffset = FirstByte; Instr->RangeOffset = FirstByte;
Instr->ReadSendSize = LastByte - FirstByte + 1; Instr->ReadSendSize = LastByte - FirstByte + 1;
sprintf( Instr->RangeHeader, "CONTENT-RANGE: bytes %d-%d/%ld\r\n", FirstByte, LastByte, FileLength ); //Data between two range. sprintf( Instr->RangeHeader, "CONTENT-RANGE: bytes %lld-%lld/%lld\r\n", FirstByte, LastByte, FileLength ); //Data between two range.
} else if( FirstByte >= 0 && LastByte == -1 } else if( FirstByte >= 0 && LastByte == -1
&& FirstByte < FileLength ) { && FirstByte < FileLength ) {
Instr->RangeOffset = FirstByte; Instr->RangeOffset = FirstByte;
Instr->ReadSendSize = FileLength - FirstByte; Instr->ReadSendSize = FileLength - FirstByte;
sprintf( Instr->RangeHeader, sprintf( Instr->RangeHeader,
"CONTENT-RANGE: bytes %d-%ld/%ld\r\n", FirstByte, "CONTENT-RANGE: bytes %lld-%lld/%lld\r\n", FirstByte,
FileLength - 1, FileLength ); FileLength - 1, FileLength );
} else if( FirstByte == -1 && LastByte > 0 ) { } else if( FirstByte == -1 && LastByte > 0 ) {
if( LastByte >= FileLength ) { if( LastByte >= FileLength ) {
Instr->RangeOffset = 0; Instr->RangeOffset = 0;
Instr->ReadSendSize = FileLength; Instr->ReadSendSize = FileLength;
sprintf( Instr->RangeHeader, sprintf( Instr->RangeHeader,
"CONTENT-RANGE: bytes 0-%ld/%ld\r\n", "CONTENT-RANGE: bytes 0-%lld/%lld\r\n",
FileLength - 1, FileLength ); FileLength - 1, FileLength );
} else { } else {
Instr->RangeOffset = FileLength - LastByte; Instr->RangeOffset = FileLength - LastByte;
Instr->ReadSendSize = LastByte; Instr->ReadSendSize = LastByte;
sprintf( Instr->RangeHeader, sprintf( Instr->RangeHeader,
"CONTENT-RANGE: bytes %ld-%ld/%ld\r\n", "CONTENT-RANGE: bytes %lld-%lld/%lld\r\n",
FileLength - LastByte + 1, FileLength, FileLength - LastByte + 1, FileLength,
FileLength ); FileLength );
} }
@@ -1042,7 +1042,7 @@ CreateHTTPRangeResponseHeader( char *ByteRangeSpecifier,
int int
CheckOtherHTTPHeaders( IN http_message_t * Req, CheckOtherHTTPHeaders( IN http_message_t * Req,
OUT struct SendInstruction *RespInstr, OUT struct SendInstruction *RespInstr,
int FileSize ) off_t FileSize )
{ {
http_header_t *header; http_header_t *header;
ListNode *node; ListNode *node;
@@ -1184,7 +1184,6 @@ process_request( IN http_message_t * req,
int code; int code;
int err_code; int err_code;
//membuffer content_type;
char *request_doc; char *request_doc;
struct File_Info finfo; struct File_Info finfo;
xboolean using_alias; xboolean using_alias;
@@ -1208,7 +1207,6 @@ process_request( IN http_message_t * req,
// init // init
request_doc = NULL; request_doc = NULL;
finfo.content_type = NULL; finfo.content_type = NULL;
//membuffer_init( &content_type );
alias_grabbed = FALSE; alias_grabbed = FALSE;
err_code = HTTP_INTERNAL_SERVER_ERROR; // default error err_code = HTTP_INTERNAL_SERVER_ERROR; // default error
using_virtual_dir = FALSE; using_virtual_dir = FALSE;
@@ -1362,7 +1360,7 @@ process_request( IN http_message_t * req,
RespInstr->ReadSendSize = finfo.file_length; RespInstr->ReadSendSize = finfo.file_length;
//Check other header field. // Check other header field.
if( ( err_code = if( ( err_code =
CheckOtherHTTPHeaders( req, RespInstr, CheckOtherHTTPHeaders( req, RespInstr,
finfo.file_length ) ) != HTTP_OK ) { finfo.file_length ) ) != HTTP_OK ) {
@@ -1376,85 +1374,75 @@ process_request( IN http_message_t * req,
} }
if( RespInstr->IsRangeActive && RespInstr->IsChunkActive ) { if( RespInstr->IsRangeActive && RespInstr->IsChunkActive ) {
// Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT
//Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT // Transfer-Encoding: chunked
//Transfer-Encoding: chunked
// K means add chunky header ang G means range header.
if (http_MakeMessage( if (http_MakeMessage(
headers, resp_major, resp_minor, headers, resp_major, resp_minor,
"RTGKDstcSXcCc", "R" "T" "GKD" "s" "tcS" "XcCc",
HTTP_PARTIAL_CONTENT, // status code HTTP_PARTIAL_CONTENT, // status code
// RespInstr->ReadSendSize,// content length finfo.content_type, // content type
finfo.content_type, RespInstr, // range info
// content_type.buf, // content type "LAST-MODIFIED: ",
RespInstr, // Range &finfo.last_modified,
"LAST-MODIFIED: ", &finfo.last_modified,
X_USER_AGENT) != 0 ) { X_USER_AGENT) != 0 ) {
goto error_handler; goto error_handler;
} }
} else if( RespInstr->IsRangeActive && !RespInstr->IsChunkActive ) { } else if( RespInstr->IsRangeActive && !RespInstr->IsChunkActive ) {
//Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT // Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT
//Transfer-Encoding: chunked // Transfer-Encoding: chunked
// K means add chunky header ang G means range header.
if (http_MakeMessage( if (http_MakeMessage(
headers, resp_major, resp_minor, headers, resp_major, resp_minor,
"RNTGDstcSXcCc", "R" "N" "T" "GD" "s" "tcS" "XcCc",
HTTP_PARTIAL_CONTENT, // status code HTTP_PARTIAL_CONTENT, // status code
(off_t)RespInstr->ReadSendSize, // content length RespInstr->ReadSendSize, // content length
finfo.content_type, finfo.content_type, // content type
//content_type.buf, // content type RespInstr, // range info
RespInstr, //Range Info "LAST-MODIFIED: ",
"LAST-MODIFIED: ", &finfo.last_modified, &finfo.last_modified,
X_USER_AGENT) != 0 ) { X_USER_AGENT) != 0 ) {
goto error_handler; goto error_handler;
} }
} else if( !RespInstr->IsRangeActive && RespInstr->IsChunkActive ) { } else if( !RespInstr->IsRangeActive && RespInstr->IsChunkActive ) {
// Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT
//Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT // Transfer-Encoding: chunked
//Transfer-Encoding: chunked
// K means add chunky header ang G means range header.
if (http_MakeMessage( if (http_MakeMessage(
headers, resp_major, resp_minor, headers, resp_major, resp_minor,
"RKTDstcSXcCc", "RK" "TD" "s" "tcS" "XcCc",
HTTP_OK, // status code HTTP_OK, // status code
//RespInstr->ReadSendSize, // content length finfo.content_type, // content type
finfo.content_type, "LAST-MODIFIED: ",
// content_type.buf, // content type &finfo.last_modified,
"LAST-MODIFIED: ", &finfo.last_modified,
X_USER_AGENT) != 0 ) { X_USER_AGENT) != 0 ) {
goto error_handler; goto error_handler;
} }
} else { } else { // !RespInstr->IsRangeActive && !RespInstr->IsChunkActive
if (RespInstr->ReadSendSize >= 0) { if (RespInstr->ReadSendSize >= 0) {
//Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT // Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT
//Transfer-Encoding: chunked // Transfer-Encoding: chunked
// K means add chunky header ang G means range header.
if (http_MakeMessage( if (http_MakeMessage(
headers, resp_major, resp_minor, headers, resp_major, resp_minor,
"RNTDstcSXcCc", "R" "N" "TD" "s" "tcS" "XcCc",
HTTP_OK, // status code HTTP_OK, // status code
(off_t)RespInstr->ReadSendSize, // content length RespInstr->ReadSendSize, // content length
finfo.content_type, finfo.content_type, // content type
//content_type.buf, // content type "LAST-MODIFIED: ",
"LAST-MODIFIED: ", &finfo.last_modified, &finfo.last_modified,
X_USER_AGENT) != 0 ) { X_USER_AGENT) != 0 ) {
goto error_handler; goto error_handler;
} }
} else { } else {
//Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT // Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT
//Transfer-Encoding: chunked // Transfer-Encoding: chunked
// K means add chunky header ang G means range header.
if (http_MakeMessage( if (http_MakeMessage(
headers, resp_major, resp_minor, headers, resp_major, resp_minor,
"RTDstcSXcCc", "R" "TD" "s" "tcS" "XcCc",
HTTP_OK, // status code HTTP_OK, // status code
//RespInstr->ReadSendSize,// content length finfo.content_type, // content type
finfo.content_type, "LAST-MODIFIED: ",
//content_type.buf, // content type &finfo.last_modified,
"LAST-MODIFIED: ", &finfo.last_modified,
X_USER_AGENT) != 0 ) { X_USER_AGENT) != 0 ) {
goto error_handler; goto error_handler;
} }
@@ -1473,8 +1461,8 @@ process_request( IN http_message_t * req,
*rtype = RESP_FILEDOC; *rtype = RESP_FILEDOC;
} }
//simple get http 0.9 as specified in http 1.0 // simple get http 0.9 as specified in http 1.0
//don't send headers // don't send headers
if( req->method == HTTPMETHOD_SIMPLEGET ) { if( req->method == HTTPMETHOD_SIMPLEGET ) {
membuffer_destroy( headers ); membuffer_destroy( headers );
} }
@@ -1484,7 +1472,6 @@ process_request( IN http_message_t * req,
error_handler: error_handler:
free( request_doc ); free( request_doc );
ixmlFreeDOMString( finfo.content_type ); ixmlFreeDOMString( finfo.content_type );
// membuffer_destroy( &content_type );
if( err_code != UPNP_E_SUCCESS && alias_grabbed ) { if( err_code != UPNP_E_SUCCESS && alias_grabbed ) {
alias_release( alias ); alias_release( alias );
} }