Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.Sign up
Using CURLOPT_CURLU with CURLOPT_PORT overwrites port from url... #3753
I'm using the new CURLOPT_CURLU feature to take advantage of curl's 'accumulative', relative url capabilities, but it appears that when also using CURLOPT_PORT, curl overwrites the port portion of the url in 'my' CURLU handle set by CURLOPT_CURLU. If I later use CURLOPT_PORT passing 0L to go back to the original port, curl instead remembers the port set by the previous CURLOPT_PORT call!
This behavior is different from using the classic 'CURLOPT_URL' way of passing the url to curl, where it correctly reverts back to the port indicated in the orginal url.
I figure the problem has to do with the way curl treats its internal CURLU handle as a 'scratch' area which is fine when used with a CURLOPT_URL url, which, I assume, resets the CURLU handle before every new transaction, but with CURLOPT_CURLU it clashes with 'my' CURLU handle, which I expect curl should leave alone and treat as read-only.
The following code illustrates the problem :
It generates the following output, note how it appears stuck on port 1234:
7.64.1 and 7.65.0-DEV (github master (as of April 8th 2019))
CentOS 7, but probably not OS specific
I can reproduce that here. CURLOPT_CURLU doc says "libcurl will use this handle and its contents read-only and will not change its contents."
and in curl_url_set
Perhaps we should copy it internally before each transfer to avoid potential problems like this.
Also as a separate issue shouldn't curl_url_set(uh, CURLUPART_PORT, "0", 0); set the port to 0?
Probably, yes. We should start with writing up a test case that reproduces this, to avoid future regressions. Then fix it. Possible we should "copy-on-write" to avoid a lot of extra copies when no "write" is necessary, but perhaps that's just complicating matters further...
Perhaps. Port zero is hardly ever actually used as a "real" port anyway so I'm not sure exactly what a user would expect such an invocation to do...
I lean towards "0" but the second option is quite OK too, provided that it's documented.
The kernel doesn't treat zero as random, but several APIs provided for applications do. Port number zero is actually not special-cased in TCP so it can in theory be used, but due to how many APIs are done it is next to impossible.
I'm in favor of sticking to the current behavior for this: setting
I meant it should set the port to 0 internally (ie clear the port) because that seems like a bug. Setting it to actual port 0 (eg 220.127.116.11:0) may be technically correct. Anyway I'm having second thoughts. I will follow up with some comments in #3762.