diff -Naur ../libupnp-1.2.1a/upnp/inc/config.h upnp/inc/config.h --- ../libupnp-1.2.1a/upnp/inc/config.h 2003-02-13 17:19:02.000000000 +0100 +++ upnp/inc/config.h 2005-11-05 20:42:25.000000000 +0100 @@ -56,6 +56,17 @@ #define THREAD_IDLE_TIME 5000 //@} +/** @name X_USER_AGENT + * The {\tt X_USER_AGENT} constant specifies the value of the X-User-Agent: + * HTTP header. The value "redsonic" is needed for the DSM-320. See + * https://sourceforge.net/forum/message.php?msg_id=3166856 for more + * information + */ + +//@{ +#define X_USER_AGENT "redsonic" +//@} + /** @name JOBS_PER_THREAD * The {\tt JOBS_PER_THREAD} constant determines when a new thread will be * allocated to the thread pool inside the SDK. The thread pool will diff -Naur ../libupnp-1.2.1a/upnp/src/gena/gena_device.c upnp/src/gena/gena_device.c --- ../libupnp-1.2.1a/upnp/src/gena/gena_device.c 2003-02-13 17:19:11.000000000 +0100 +++ upnp/src/gena/gena_device.c 2005-11-05 20:18:42.000000000 +0100 @@ -1164,10 +1164,16 @@ membuffer_init( &response ); response.size_inc = 30; +/* - PATCH START - Sergey 'Jin' Bostandzhyan + * added X-User-Agent header + */ if( http_MakeMessage( &response, major, minor, - "R" "D" "S" "ssc" "sc" "c", + "R" "D" "S" "Xc" "ssc" "sc" "c", HTTP_OK, - "SID: ", sub->sid, timeout_str ) != 0 ) { + X_USER_AGENT, + "SID: ", sub->sid, timeout_str ) != 0 ) +/* - PATCH END --- */ + { membuffer_destroy( &response ); error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request ); return UPNP_E_OUTOF_MEMORY; diff -Naur ../libupnp-1.2.1a/upnp/src/genlib/net/http/httpreadwrite.c upnp/src/genlib/net/http/httpreadwrite.c --- ../libupnp-1.2.1a/upnp/src/genlib/net/http/httpreadwrite.c 2003-02-13 17:19:13.000000000 +0100 +++ upnp/src/genlib/net/http/httpreadwrite.c 2005-11-05 20:04:51.000000000 +0100 @@ -1632,6 +1632,9 @@ * appends content-length, content-type and HTML body for given code * 'T': arg = char * content_type; format e.g: "text/html"; * content-type header +* --- PATCH START - Sergey 'Jin' Bostandzhyan +* 'X': arg = const char useragent; "redsonic" HTTP X-User-Agent: useragent +* --- PATCH END --- * * Return : int; * 0 - On Success @@ -1800,6 +1803,24 @@ } } +/* --- PATCH START - Sergey 'Jin' Bostandzhyan */ + if( c == 'X' ) // C string + { + s = ( char * )va_arg( argp, char * ); + + assert( s ); + + if( membuffer_append_str( buf, "X-User-Agent: ") != 0 ) { + goto error_handler; + } + if( membuffer_append( buf, s, strlen( s ) ) != 0 ) { + goto error_handler; + } + } + +/* --- PATCH END --- */ + + else if( c == 'R' ) { // response start line // e.g.: 'HTTP/1.1 200 OK' diff -Naur ../libupnp-1.2.1a/upnp/src/genlib/net/http/webserver.c upnp/src/genlib/net/http/webserver.c --- ../libupnp-1.2.1a/upnp/src/genlib/net/http/webserver.c 2003-02-13 17:19:14.000000000 +0100 +++ upnp/src/genlib/net/http/webserver.c 2005-11-05 20:53:56.000000000 +0100 @@ -1368,16 +1368,22 @@ } if( RespInstr->IsRangeActive && RespInstr->IsChunkActive ) { + +/* - PATCH START - Sergey 'Jin' Bostandzhyan + * added X-User-Agent header + */ + //Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT //Transfer-Encoding: chunked // K means add chunky header ang G means range header. - if( http_MakeMessage( headers, resp_major, resp_minor, "RTGKDstcSCc", HTTP_PARTIAL_CONTENT, // status code + if( http_MakeMessage( headers, resp_major, resp_minor, "RTGKDstcSXcCc", HTTP_PARTIAL_CONTENT, // status code // RespInstr->ReadSendSize,// content length finfo.content_type, // content_type.buf, // content type RespInstr, // Range "LAST-MODIFIED: ", - &finfo.last_modified ) != 0 ) { + &finfo.last_modified, + X_USER_AGENT) != 0 ) { goto error_handler; } } else if( RespInstr->IsRangeActive && !RespInstr->IsChunkActive ) { @@ -1385,13 +1391,14 @@ //Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT //Transfer-Encoding: chunked // K means add chunky header ang G means range header. - if( http_MakeMessage( headers, resp_major, resp_minor, "RNTGDstcSCc", HTTP_PARTIAL_CONTENT, // status code + if( http_MakeMessage( headers, resp_major, resp_minor, "RNTGDstcSXcCc", HTTP_PARTIAL_CONTENT, // status code RespInstr->ReadSendSize, // content length finfo.content_type, //content_type.buf, // content type RespInstr, //Range Info "LAST-MODIFIED: ", - &finfo.last_modified ) != 0 ) { + &finfo.last_modified, + X_USER_AGENT) != 0 ) { goto error_handler; } @@ -1400,12 +1407,13 @@ //Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT //Transfer-Encoding: chunked // K means add chunky header ang G means range header. - if( http_MakeMessage( headers, resp_major, resp_minor, "RKTDstcSCc", HTTP_OK, // status code + if( http_MakeMessage( headers, resp_major, resp_minor, "RKTDstcSXcCc", HTTP_OK, // status code //RespInstr->ReadSendSize,// content length finfo.content_type, // content_type.buf, // content type "LAST-MODIFIED: ", - &finfo.last_modified ) != 0 ) { + &finfo.last_modified, + X_USER_AGENT) != 0 ) { goto error_handler; } @@ -1414,28 +1422,31 @@ //Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT //Transfer-Encoding: chunked // K means add chunky header ang G means range header. - if( http_MakeMessage( headers, resp_major, resp_minor, "RNTDstcSCc", HTTP_OK, // status code + if( http_MakeMessage( headers, resp_major, resp_minor, "RNTDstcSXcCc", HTTP_OK, // status code RespInstr->ReadSendSize, // content length finfo.content_type, //content_type.buf, // content type "LAST-MODIFIED: ", - &finfo.last_modified ) != 0 ) { + &finfo.last_modified, + X_USER_AGENT) != 0 ) { goto error_handler; } } else { //Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT //Transfer-Encoding: chunked // K means add chunky header ang G means range header. - if( http_MakeMessage( headers, resp_major, resp_minor, "RTDstcSCc", HTTP_OK, // status code + if( http_MakeMessage( headers, resp_major, resp_minor, "RTDstcSXcCc", HTTP_OK, // status code //RespInstr->ReadSendSize,// content length finfo.content_type, //content_type.buf, // content type "LAST-MODIFIED: ", - &finfo.last_modified ) != 0 ) { + &finfo.last_modified, + X_USER_AGENT) != 0 ) { goto error_handler; } } } +/* -- PATCH END -- */ if( req->method == HTTPMETHOD_HEAD ) { *rtype = RESP_HEADERS; @@ -1717,8 +1728,14 @@ http_RecvPostMessage( parser, info, filename.buf, &RespInstr ); //Send response. - http_MakeMessage( &headers, 1, 1, "RTDSCc", ret, - "text/html" ); + +/* - PATCH START - Sergey 'Jin' Bostandzhyan + * added X-User-Agent header + */ + http_MakeMessage( &headers, 1, 1, "RTDSXcCc", ret, + "text/html", X_USER_AGENT ); +/* - PATCH END --- */ + http_SendMessage( info, &timeout, "b", headers.buf, headers.length ); break; diff -Naur ../libupnp-1.2.1a/upnp/src/soap/soap_device.c upnp/src/soap/soap_device.c --- ../libupnp-1.2.1a/upnp/src/soap/soap_device.c 2003-02-13 17:19:20.000000000 +0100 +++ upnp/src/soap/soap_device.c 2005-11-05 20:44:41.000000000 +0100 @@ -221,17 +221,20 @@ // make headers membuffer_init( &headers ); +/* -- PATCH START - Sergey 'Jin' Bostandzhyan */ if( http_MakeMessage( &headers, major, minor, - "RNsDsSc" "sssss", + "RNsDsSXc" "sssss", 500, content_length, ContentTypeHeader, "EXT:\r\n", + X_USER_AGENT, start_body, err_code_str, mid_body, err_msg, end_body ) != 0 ) { membuffer_destroy( &headers ); return; // out of mem } +/*-- PATCH END - */ // send err msg http_SendMessage( info, &timeout_secs, "b", headers.buf, headers.length ); @@ -285,16 +288,21 @@ // make headers membuffer_init( &response ); + +/* -- PATCH START - Sergey 'Jin' Bostandzhyan */ if( http_MakeMessage( &response, major, minor, - "RNsDsSc" "sss", + "RNsDsSXcc" "sss", HTTP_OK, content_length, ContentTypeHeader, "EXT:\r\n", + X_USER_AGENT, start_body, var_value, end_body ) != 0 ) { membuffer_destroy( &response ); return; // out of mem } +/* -- PATCH END - */ + // send msg http_SendMessage( info, &timeout_secs, "b", response.buf, response.length ); @@ -704,11 +712,14 @@ strlen( end_body ); // make headers - if( http_MakeMessage( &headers, major, minor, "RNsDsSc", HTTP_OK, // status code - content_length, ContentTypeHeader, "EXT:\r\n" // EXT header +/* -- PATCH START - Sergey 'Jin' Bostandzhyan */ + if( http_MakeMessage( &headers, major, minor, "RNsDsSXcc", HTTP_OK, // status code + content_length, ContentTypeHeader, "EXT:\r\n", X_USER_AGENT // EXT header ) != 0 ) { goto error_handler; } +/* -- PATCH END - */ + // send whole msg ret_code = http_SendMessage( info, &timeout_secs, "bbbb", headers.buf, headers.length, diff -Naur ../libupnp-1.2.1a/upnp/src/ssdp/ssdp_device.c upnp/src/ssdp/ssdp_device.c --- ../libupnp-1.2.1a/upnp/src/ssdp/ssdp_device.c 2003-02-13 17:19:21.000000000 +0100 +++ upnp/src/ssdp/ssdp_device.c 2005-11-05 21:04:52.000000000 +0100 @@ -290,12 +290,16 @@ *packet = NULL; if( msg_type == MSGTYPE_REPLY ) { +/* -- PATCH START - Sergey 'Jin' Bostandzhyan */ ret_code = http_MakeMessage( &buf, 1, 1, - "R" "sdc" "D" "s" "ssc" "S" "ssc" + "R" "sdc" "D" "s" "ssc" "S" "Xc" "ssc" "ssc" "c", HTTP_OK, "CACHE-CONTROL: max-age=", duration, "EXT:\r\n", "LOCATION: ", location, + X_USER_AGENT, "ST: ", nt, "USN: ", usn ); +/* -- PATCH END - */ + if( ret_code != 0 ) { return; } @@ -310,14 +314,16 @@ // NOTE: The CACHE-CONTROL and LOCATION headers are not present in // a shutdown msg, but are present here for MS WinMe interop. - + +/* -- PATCH START - Sergey 'Jin' Bostandzhyan */ ret_code = http_MakeMessage( &buf, 1, 1, "Q" "sssdc" "sdc" "ssc" "ssc" "ssc" - "S" "ssc" "c", HTTPMETHOD_NOTIFY, "*", + "S" "Xc" "ssc" "c", HTTPMETHOD_NOTIFY, "*", 1, "HOST: ", SSDP_IP, ":", SSDP_PORT, "CACHE-CONTROL: max-age=", duration, "LOCATION: ", location, "NT: ", nt, - "NTS: ", nts, "USN: ", usn ); + "NTS: ", nts, X_USER_AGENT, "USN: ", usn ); +/* -- PATCH END - */ if( ret_code != 0 ) { return; }