<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"><!-- P {margin-top:0;margin-bottom:0;} --></style>
</head>
<body dir="ltr">
<div id="divtagdefaultwrapper" style="font-size:12pt;color:#000000;font-family:Calibri,Helvetica,sans-serif;" dir="ltr">
<p><span style="font-size: 12pt;">Hi Tobias,</span><br>
</p>
<div dir="ltr">
<div id="x_divtagdefaultwrapper" dir="ltr" style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;">
<p><br>
</p>
<p>sorry for the long delay. I was on holiday a few days and did not manage to return earlier to this interesting topic ...</p>
<p><br>
</p>
<p><br>
</p>
<p>> <span style="font-size:12pt">No thats wrong. Curl will only send auth data if you provide it.</span></p>
<div><br>
</div>
<div>> <span style="font-size:12pt">Doing "curl -u user:pw" is the same as using WebClient httpGet:do: and adding the Authorization header manually</span></div>
<div><br>
</div>
<div>> <span style="font-size:12pt">The point is, you instruct Curl to _provide credentials unconditionally_.</span>
<div><br>
</div>
</div>
<p></p>
<div id="x_Signature">
<div id="x_divtagdefaultwrapper" dir="ltr" style="font-size:12pt; color:rgb(0,0,0); font-family:Calibri,Helvetica,sans-serif,EmojiFont,"Apple Color Emoji","Segoe UI Emoji",NotoColorEmoji,"Segoe UI Symbol","Android Emoji",EmojiSymbols">
<div name="x_divtagdefaultwrapper" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:; margin:0">
<div>
<div class="x__rp_T4" id="x_Item.MessagePartBody">
<div class="x__rp_U4 x_ms-font-weight-regular x_ms-font-color-neutralDark x_rpHighlightAllClass x_rpHighlightBodyClass" id="x_Item.MessageUniqueBody" style="font-family:wf_segoe-ui_normal,"Segoe UI","Segoe WP",Tahoma,Arial,sans-serif,serif,EmojiFont">
<div dir="ltr">
<div id="x_divtagdefaultwrapper"><font face="Calibri,Helvetica,sans-serif,EmojiFont,Apple Color Emoji,Segoe UI Emoji,NotoColorEmoji,Segoe UI Symbol,Android Emoji,EmojiSymbols">
<div id="x_Signature">
<div style="margin:0px"><font style="font-family:Calibri,Arial,Helvetica,sans-serif,serif,EmojiFont">
<div><font size="3" color="black"><span style="font-size:12pt"><a href="http://www.hpi.de/" target="_blank" rel="noopener noreferrer" id="LPNoLP"><font size="2"><span id="LPlnk909538"><font color="#757B80"></font></span></font></a></span></font></div>
</font></div>
</div>
</font></div>
</div>
</div>
</div>
<div class="x__rp_T4" id="x_Item.MessagePartBody">I think this is exactly the point. "curl -u user:pw" reads as "Download a resource, 'specify[ing] <span style="font-size:12pt">the user name and password to use for server authenti</span><span style="font-size:12pt">cation"' <span style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:16px">(cited
 from the man)</span>. If I do</span></div>
<div class="x__rp_T4" id="x_Item.MessagePartBody"><span style="font-size:12pt"></span><span style="font-size:12pt">WebClient httpDo: [:client | client username: 'user'; password: 'pw'; get: </span><span style="font-size:12pt">'https://example.com/rest/whoami'],</span></div>
<div class="x__rp_T4" id="x_Item.MessagePartBody"><span style="font-size:12pt">this reads exactly the same for me. Otherwise, #username: and #password: better might be renamed into #optionalUsername/#lazyUsername/#usernameIfAsked etc.</span></div>
<div class="x__rp_T4" id="x_Item.MessagePartBody"><span style="font-size:12pt"><br>
</span></div>
<div class="x__rp_T4" id="x_Item.MessagePartBody"><span style="font-size:12pt">
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 16px;">
Apart from this, I have tested the behavior for Pharo, too, where the default web client is ZnClient: And it works like curl, too, rather than like our WebClient, i.e. the following works without any extra low-level instructions:</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 16px;">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 16px;">
<div>ZnClient new</div>
<div><span style="white-space: pre;"></span>url: 'https://api.github.com/repos/LinqLover/openHAB-configuration/zipball/master';</div>
<div><span style="white-space: pre;"></span>username: 'LinqLover' password: 'mytoken';</div>
<div><span style="white-space: pre;"></span>downloadTo: 'foo.zip'</div>
<div><br>
</div>
</div>
> </span><span style="font-size:12pt">So you always know beforehand which resources need authentication?</span><span style="font-size:12pt">
<div>> Neat, I dont :D</div>
<div><br>
</div>
<div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 16px;">
I suppose we are having different use cases in mind: You are thinking of a generic browser application while I am thinking of a specific API client implementation. Is this correct?</div>
<div><span style="font-size: 12pt;">If I'm developing a REST API client, I do have to know whether a resource requires authentication or whether it doesn't. This is usually specified in the API documentation. Why add another level of uncertainty by using this
 trial-and-error strategy?</span><br>
</div>
</div>
<div><br>
</div>
<div></div>
<div><br>
</div>
<div>In the context of my Metacello PR, the problem is that following your approach of specifying the Authorization header would mess up all the different layers of abstraction that are not aware of web client implementations and headers but only of a URL and
 a username/password pair. I had hoped that I could pass a constant string 'Basic' to the Authorization header for all cases where the WebClient is invoked, but unfortunately, GitHub does not understand this either, the header must contain the password even
 in the first run. It would lead to some portion on unhandsome spaghetti code if I had to implement an edge case for GitHub in the relevant method (MetacelloSqueakPlatform class >> #<span>downloadZipArchive:to:username:pass:)</span>; for this reason, I would
 find it really helpful to turn on preAuth at this place.<span></span></div>
<div>Do you dislike this feature in general, even when turned off by default? I'm not even requiring to make this an opt-out feature, this inbox version only implements it as an opt-in.</div>
<div><br>
</div>
<div>Best,</div>
<div>Christoph</div>
<div><br>
</div>
</span></div>
</div>
<div><font size="2" color="#808080"></font></div>
</div>
</div>
</div>
</div>
<hr tabindex="-1" style="display:inline-block; width:98%">
<div id="x_divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>Von:</b> Squeak-dev <squeak-dev-bounces@lists.squeakfoundation.org> im Auftrag von Tobias Pape <Das.Linux@gmx.de><br>
<b>Gesendet:</b> Dienstag, 13. Oktober 2020 10:04:23<br>
<b>An:</b> The general-purpose Squeak developers list<br>
<b>Betreff:</b> Re: [squeak-dev] The Inbox: WebClient-Core-ct.126.mcz</font>
<div> </div>
</div>
</div>
<font size="2"><span style="font-size:10pt">
<div class="PlainText">Hi<br>
<br>
> On 12.10.2020, at 23:42, Thiede, Christoph <Christoph.Thiede@student.hpi.uni-potsdam.de> wrote:<br>
> <br>
> Hi Tobias,<br>
> <br>
> okay, I see this authorization pattern now, so you mentioned two ways to work around the current limitations:<br>
> First, by GETting <a href="https://api.github.com/authorizations">https://api.github.com/authorizations</a> before, or second, by passing the Authorization header manually.<br>
> Is this correct?<br>
<br>
Yes. However, the second one is the one GitHub "recommends"<br>
<br>
<br>
> <br>
> However, both of these approaches lack of the RESTful-typical simplicity of "making a single HTTP request without dealing with complex call protocols or low-level connectivity code". To give an illustration of my use case, please see this PR on Metacello:
<a href="https://github.com/Metacello/metacello/pull/534">https://github.com/Metacello/metacello/pull/534</a><br>
> IMHO it would be a shame if you could not access a popular REST API like api.github.com in Squeak using a single message send to the WebClient/WebSocket class.<br>
<br>
There is no such thing as simplicity when a REST-Based resource-provider supports both authenticated and unauthenticated access.<br>
If you cannot know beforehand, no single-request stuff is gonna help. No dice.<br>
 <br>
<br>
> <br>
> > > Why not?<br>
> > <br>
> > It leaks credentials unnecessarily.<br>
> <br>
> Ah, good point! But this pattern (EAFP for web connections) is not really state of the art, is it? As mentioned, curl, for example, sends the authentication data in the very first request, which is a tool I would tend to *call* state of the art.<br>
<br>
No thats wrong. Curl will only send auth data if you provide it. <br>
<br>
Doing "curl -u user:pw" is the same as using WebClient httpGet:do: and adding the Authorization header manually<br>
<br>
<br>
The sequence is split manually:<br>
```<br>
$ curl <a href="https://api.github.com/repos/krono/debug/zipball/master">https://api.github.com/repos/krono/debug/zipball/master</a><br>
{<br>
  "message": "Not Found",<br>
  "documentation_url": "<a href="https://docs.github.com/rest/reference/repos#download-a-repository-archive">https://docs.github.com/rest/reference/repos#download-a-repository-archive</a>"<br>
}<br>
# Well, I'm left to guess. Maybe exists, maybe not.<br>
$ curl -u krono <a href="https://api.github.com/repos/krono/debug/zipball/master">
https://api.github.com/repos/krono/debug/zipball/master</a><br>
<br>
```<br>
(In this case, I can't even show what's going on as I use 2FA, which makes single-request REST to _never_ work on private repos.)<br>
<br>
The point is, you instruct Curl to _provide credentials unconditionally_.<br>
The "heavy lifting" of finding out when to do that is not done by curl but by users of curl.<br>
<br>
Look:<br>
<br>
```<br>
$ curl <a href="http://www.hpi.uni-potsdam.de/hirschfeld/squeaksource/xpaware/">http://www.hpi.uni-potsdam.de/hirschfeld/squeaksource/xpaware/</a><br>
$ <br>
# Well, no response?<br>
$ curl  -v <a href="http://www.hpi.uni-potsdam.de/hirschfeld/squeaksource/xpaware/">
http://www.hpi.uni-potsdam.de/hirschfeld/squeaksource/xpaware/</a><br>
*   Trying 2001:638:807:204::8d59:e178...<br>
* TCP_NODELAY set<br>
* Connected to <a href="http://www.hpi.uni-potsdam.de">www.hpi.uni-potsdam.de</a> (2001:638:807:204::8d59:e178) port 80 (#0)<br>
> GET /hirschfeld/squeaksource/xpaware/ HTTP/1.1<br>
> Host: <a href="http://www.hpi.uni-potsdam.de">www.hpi.uni-potsdam.de</a><br>
> User-Agent: curl/7.54.0<br>
> Accept: */*<br>
><br>
< HTTP/1.1 401<br>
< Date: Tue, 13 Oct 2020 07:43:04 GMT<br>
< Server: nginx/1.14.2<br>
< Content-Length: 0<br>
< WWW-Authenticate: Basic realm="SwaSource - XP aware"<br>
<<br>
* Connection #0 to host <a href="http://www.hpi.uni-potsdam.de">www.hpi.uni-potsdam.de</a> left intact<br>
```<br>
<br>
Thats the 401 we're looking for. We have found that the resource needs authentication.<br>
<br>
Sidenote: Curl can do the roundtrip (man curl, search anyauth):<br>
<br>
```<br>
$ curl -u topa --anyauth -v <a href="http://www.hpi.uni-potsdam.de/hirschfeld/squeaksource/xpaware/">
http://www.hpi.uni-potsdam.de/hirschfeld/squeaksource/xpaware/</a><br>
Enter host password for user 'topa':<br>
*   Trying 2001:638:807:204::8d59:e178...<br>
* TCP_NODELAY set<br>
* Connected to <a href="http://www.hpi.uni-potsdam.de">www.hpi.uni-potsdam.de</a> (2001:638:807:204::8d59:e178) port 80 (#0)<br>
> GET /hirschfeld/squeaksource/xpaware/ HTTP/1.1<br>
> Host: <a href="http://www.hpi.uni-potsdam.de">www.hpi.uni-potsdam.de</a><br>
> User-Agent: curl/7.54.0<br>
> Accept: */*<br>
><br>
< HTTP/1.1 401<br>
< Date: Tue, 13 Oct 2020 07:46:05 GMT<br>
< Server: nginx/1.14.2<br>
< Content-Length: 0<br>
< WWW-Authenticate: Basic realm="SwaSource - XP aware"<br>
<<br>
* Connection #0 to host <a href="http://www.hpi.uni-potsdam.de">www.hpi.uni-potsdam.de</a> left intact<br>
* Issue another request to this URL: '<a href="http://www.hpi.uni-potsdam.de/hirschfeld/squeaksource/xpaware/">http://www.hpi.uni-potsdam.de/hirschfeld/squeaksource/xpaware/</a>'<br>
* Found bundle for host <a href="http://www.hpi.uni-potsdam.de:">www.hpi.uni-potsdam.de:</a> 0x7fb8c8c0b1b0 [can pipeline]<br>
* Re-using existing connection! (#0) with host <a href="http://www.hpi.uni-potsdam.de">
www.hpi.uni-potsdam.de</a><br>
* Connected to <a href="http://www.hpi.uni-potsdam.de">www.hpi.uni-potsdam.de</a> (2001:638:807:204::8d59:e178) port 80 (#0)<br>
* Server auth using Basic with user 'topa'<br>
> GET /hirschfeld/squeaksource/xpaware/ HTTP/1.1<br>
> Host: <a href="http://www.hpi.uni-potsdam.de">www.hpi.uni-potsdam.de</a><br>
> Authorization: Basic *******************<br>
> User-Agent: curl/7.54.0<br>
> Accept: */*<br>
><br>
< HTTP/1.1 200<br>
< Date: Tue, 13 Oct 2020 07:46:05 GMT<br>
< Server: nginx/1.14.2<br>
< Content-Type: text/html<br>
< Content-Length: 15131<br>
< Vary: Accept-Encoding<br>
```<br>
<br>
And in this case it does _not_ send auth in the first request but only in the second.<br>
<br>
Sidenote2: If the first request comes back 200, no second one is issued, no credentials leak:<br>
<br>
```<br>
$ curl -u topa --anyauth -v <a href="http://www.hpi.uni-potsdam.de/hirschfeld/squeaksource/xpforums/">
http://www.hpi.uni-potsdam.de/hirschfeld/squeaksource/xpforums/</a><br>
Enter host password for user 'topa':<br>
*   Trying 2001:638:807:204::8d59:e178...<br>
* TCP_NODELAY set<br>
* Connected to <a href="http://www.hpi.uni-potsdam.de">www.hpi.uni-potsdam.de</a> (2001:638:807:204::8d59:e178) port 80 (#0)<br>
> GET /hirschfeld/squeaksource/xpforums/ HTTP/1.1<br>
> Host: <a href="http://www.hpi.uni-potsdam.de">www.hpi.uni-potsdam.de</a><br>
> User-Agent: curl/7.54.0<br>
> Accept: */*<br>
><br>
< HTTP/1.1 200<br>
< Date: Tue, 13 Oct 2020 07:46:56 GMT<br>
< Server: nginx/1.14.2<br>
< Content-Type: text/html<br>
< Content-Length: 75860<br>
< Vary: Accept-Encoding<br>
```<br>
<br>
<br>
<br>
<br>
<br>
> And speed is another point, given the fact that internet connections in Squeak are really slow ...<br>
> Why do you call this behavior a leak? The application developer will not pass authentication data to the web client unless they expect the server to consume these data anyway.<br>
<br>
So you always know beforehand which resources need authentication?<br>
Neat, I dont :D<br>
<br>
> If you deem it necessary, we could turn off the pre-authentication as soon as the client was redirected to another server ...<br>
<br>
What happens here is that we're bending over backwards because github decided to be a bad player.<br>
<br>
I mean, on most sited you visit in browsers, no auth data is sent _unless_ you are asked to (redirect to a login) or you _explicitely_ click on a login link.<br>
<br>
If you want preemtive auth, do it with WebClient httpGet:do:.<br>
<br>
<br>
<br>
> <br>
> > I understand that the method is maybe not the most common style, but I think that functional changes should in such cases not be mixed with style changes.<br>
> <br>
> Alright, please see WebClient-Core-ct.128. But maybe we should consider to use prettyDiff for the mailing list notifications as a default? Just an idea.<br>
<br>
I personally find prettydiffs useless, but that's just me.<br>
<br>
Best regards<br>
        -Tobias<br>
<br>
</div>
</span></font></div>
</body>
</html>