Giter Site home page Giter Site logo

String conversion issue about goupnp HOT 12 CLOSED

huin avatar huin commented on July 23, 2024
String conversion issue

from goupnp.

Comments (12)

huin avatar huin commented on July 23, 2024

Hm, this is beyond my limited knowledge of UPnP. At a guess I'd say that it looks like the server isn't decoding the XML properly. Could you check what the payload looks like that is sent to the server?

To check this, at this point in your local copy of this library:
https://github.com/huin/goupnp/blob/master/soap/soap.go#L40

Put this code:

fmt.Println(string(requestBytes))

I'm expecting that you will see a part of it looking like this:

...<SearchCriteria>(dc:title contains &#34;star wars&#34;) ...

This is valid, and a correct XML encoding of the query. But if the server doesn't decode it properly then the &#34; are being read literally. If that's the case, then things might be tricky, as I'm not sure how to get the Go XML library to not escape the double quotes. You could try using single quotes instead, but I rather suspect that they would be similarly escaped as well.

from goupnp.

jeromelesaux avatar jeromelesaux commented on July 23, 2024

Hi Huin
you're right the soap envelop convert the quote to " html code.
But when I see the specification, searchCriteria wait for quote or double quote and not html code.
http://upnp.org/specs/av/UPnP-av-ContentDirectory-v1-Service.pdf
Simple quote or double are converted.
How can I bypass the conversion ?

Best regards

Jerome

from goupnp.

huin avatar huin commented on July 23, 2024

As goupnp stands right now, you won't be able to bypass it, the library will have to be changed to make this work. My interpretation of the spec would be that it should accept XML entities (otherwise how would the relOp part of the grammar allow for literal < without breaking the XML it's embedded within.

Looking at https://golang.org/pkg/encoding/xml/#Marshal I'm thinking that it might be possible to tag the outgoing data elements encoded as text in XML as innerxml, and arrange for the value passed to be only escaping <, >, and &, which are the absolute minimum to be escaped and not do dangerous things in XML text elements (but crucially not " or ', which should only need to be escaped within an XML tag). This should still be acceptable and safe XML and meet your immediate needs.

This would affect all the generated code, such as the code here:

https://github.com/huin/goupnp/blob/master/dcps/av1/av1.go#L2423

A quick hack to see if this approach would work for you would be to edit (but not commit) the file above to change the (current) line 2428 from

SearchCriteria string

to

SearchCriteria string `xml:",innerxml"`

(Note that those are backticks, not single quotes, and the comma is not a typo)

See if that solves this specific case you have and let me know. Note that this is not a complete solution, as:

a) We need to change the code generator to do this in future.
b) This will break the XML as soon as a <, >, or & appears in the search criteria (although I wonder how your media server will cope with that case without this change -- I'd be interested in knowing).

from goupnp.

huin avatar huin commented on July 23, 2024

If possible, could you test branch server-xml-workaround? I'm hoping that this is a functional workaround for the problem.

from goupnp.

jeromelesaux avatar jeromelesaux commented on July 23, 2024

Hi Huin,
well, the issue comes from the line 129 of the file soap. The EncodeElement function of the xml encoder escape string.
I see no solution for the moment.
Thanks a lot for the branch, I tested with it, but same result.

Jerome

from goupnp.

jeromelesaux avatar jeromelesaux commented on July 23, 2024

Hi Huin,
I find a workaround, I create my own soap client like this :
`var URN_ContentDirectory_1 = "urn:schemas-upnp-org:service:ContentDirectory:1"

type SoapEnvelope struct {
XMLName xml.Name xml:"http://schemas.xmlsoap.org/soap/envelope/ Envelope"
Body *SoapBody
}

type SoapFault struct {
Faultstring string
Detail string
}

type SoapBody struct {
XMLName xml.Name xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"
Fault *SoapFault
Search *UpnpContentDirectorySearchRequest xml:"urn:schemas-upnp-org:service:ContentDirectory:1 Search"
SearchResponse *UpnpContentDirectorySearchResponse xml:"urn:schemas-upnp-org:service:ContentDirectory:1 SearchResponse"
}

type UpnpContentDirectoryClient struct {
Url *url.URL xml:"-"
}

func NewUpnpContentDirectoryClient(url *url.URL) (*UpnpContentDirectoryClient) {
return &UpnpContentDirectoryClient{Url: url}
}

func (c *UpnpContentDirectoryClient) Search(ContainerID string, SearchCriteria string, Filter string, StartingIndex string, RequestedCount string, SortCriteria string) (Result string, NumberReturned uint32, TotalMatches uint32, UpdateID uint32, err error) {
search := &UpnpContentDirectorySearchRequest{
ContainerID: ContainerID,
SearchCriteria: ""+SearchCriteria+"",
Filter: Filter,
StartingIndex: StartingIndex,
RequestedCount: RequestedCount,
SortCriteria: SortCriteria,
}
env := &SoapEnvelope{Body:&SoapBody{Search:search,Fault:nil}}
w := &bytes.Buffer{}
err = xml.NewEncoder(w).Encode(env)
if err != nil {
fmt.Println(err)
return "",0,0,0,err
}
fmt.Printf("Envelope SOAP:%s",string(w.String()))
httpClient := &http.Client{}
httpRequest,err := http.NewRequest("POST",c.Url.String(),bytes.NewBuffer(w.Bytes()))
if err != nil {
fmt.Printf("%v",err)
return "",0,0,0,err
}
httpRequest.Header.Set("SOAPACTION"," + URN_ContentDirectory_1 + #Search")
httpRequest.Header.Set("CONTENT-TYPE","text/xml; charset="utf-8"")
httpResponse,err := httpClient.Do(httpRequest)
if err != nil {
fmt.Printf("%v",err)
return "",0,0,0,err
}
if httpResponse.StatusCode != 200 {
fmt.Printf("%v",httpResponse)
return "",0,0,0,errors.New("http code "+ httpResponse.Status)
}
defer httpResponse.Body.Close()

response := &SoapEnvelope{}
err = xml.NewDecoder(httpResponse.Body).Decode(response)
if err != nil {
	fmt.Println(err)
	return "",0,0,0,err
}
sr := response.Body.SearchResponse
return sr.Result,sr.NumberReturned,sr.TotalMatches,sr.UpdateID,nil

}

type UpnpContentDirectorySearchRequest struct {
ContainerID string xml:"ContainerID"
SearchCriteria string xml:",innerxml"
Filter string xml:"Filter"
StartingIndex string xml:"StartingIndex"
RequestedCount string xml:"RequestedCount"
SortCriteria string xml:"SortCriteria"
}

type UpnpContentDirectorySearchResponse struct {
Result string
NumberReturned uint32
TotalMatches uint32
UpdateID uint32
}

type DIDLLite struct {
XMLName xml.Name
DC string xml:"xmlns:dc,attr"
UPNP string xml:"xmlns:upnp,attr"
XSI string xml:"xmlns:xsi,attr"
XLOC string xml:"xsi:schemaLocation,attr"
Objects []Object xml:"item"
}

type Object struct {
ID string xml:"id,attr"
Parent string xml:"parentID,attr"
Restricted string xml:"restricted,attr"
Title string xml:"title"
Creator string xml:"creator"
Class string xml:"class"
Date string xml:"date"
Results []Res xml:"res"
}

type Res struct {
Resolution string xml:"resolution,attr"
Size uint64 xml:"size,attr"
ProtocolInfo string xml:"protocolInfo,attr"
Duration string xml:"duration,attr"
Bitrate string xml:"bitrate,attr"
SampleFrequency uint64 xml:"sampleFrequency"
NrAudioChannels uint64 xml:"nrAudioChannels"
Value string xml:",chardata"
}`

and I can get the results from my device media server.
Thanks for your time and your advises.

Jerome

from goupnp.

huin avatar huin commented on July 23, 2024

Ah yes, I'd completely forgotten that I'd written that bit of code. I guess that actually makes things easier, but I'll have to try again later when I get a moment.

from goupnp.

jeromelesaux avatar jeromelesaux commented on July 23, 2024

No problem Huin,
I'll stay tuned ;).

You can close this issue.
Jerome

from goupnp.

huin avatar huin commented on July 23, 2024

I've had another crack at this in branch server-xml-workaround-2. I feel a bit more confident about this as it actually had an existing test.

from goupnp.

jeromelesaux avatar jeromelesaux commented on July 23, 2024

Hi Huin,
I've tested and it works as expected.
You fixed my issue.
Thanks for your time.

Jerome

from goupnp.

huin avatar huin commented on July 23, 2024

Excellent, thanks for the report and confirmation. I'll get this merged into master.

from goupnp.

huin avatar huin commented on July 23, 2024

Fixed in 991e174.

from goupnp.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.