[squeak-dev] The Inbox: Monticello-ct.785.mcz
commits at source.squeak.org
commits at source.squeak.org
Thu Sep 8 13:19:14 UTC 2022
A new version of Monticello was added to project The Inbox:
http://source.squeak.org/inbox/Monticello-ct.785.mcz
==================== Summary ====================
Name: Monticello-ct.785
Author: ct
Time: 8 September 2022, 3:19:07.385836 pm
UUID: 9c69102f-1dd8-294a-acde-d8a3052b4e82
Ancestors: Monticello-mt.782
Proposal: When loading/saving a HTTP repository with insufficient authorization (no credentials/wrong password), allow the user to re-authenticate through a dialog window instead of displaying an unhandled NetworkError (401). Also adds support for nil as username/password.
Details: Slightly refactor #webClientDo: and senders. Only create authorization header if any credentials have been specified, which avoids two useless re-attempts for each insufficiently authorized requests. Handle WebAuthRequired exceptions by asking for the credentials again. Slightly improves multilingual support.
=============== Diff against Monticello-mt.782 ===============
Item was added:
+ ----- Method: MCHttpRepository>>authorizeRequest:forClient: (in category 'private') -----
+ authorizeRequest: aWebRequest forClient: aWebClient
+
+ (aWebClient username isNil and: [aWebClient password isNil]) ifFalse: [
+ aWebRequest headerAt: 'Authorization' put: 'Basic ',
+ ((aWebClient username ifNil: ['']), ':', (aWebClient password ifNil: [''])) base64Encoded].!
Item was changed:
----- Method: MCHttpRepository>>httpGet:arguments: (in category 'private') -----
httpGet: url arguments: arguments
| urlString |
urlString := arguments
ifNil: [ url ]
ifNotNil: [
| queryString |
queryString := WebUtils encodeUrlEncodedForm: arguments.
(url includes: $?)
ifTrue: [ url, '&', queryString ]
ifFalse: [ url, '?', queryString ] ].
urlString := self class rewriteUrl: urlString forDownload: true.
+ ^self webClientDo: [ :client :requestBlock |
+ client httpGet: urlString do: requestBlock ]!
- ^self webClientDo: [ :client |
- client
- username: self user;
- password: self password;
- httpGet: urlString do: [ :request |
- request
- headerAt: 'Authorization' put: 'Basic ', (self user, ':', self password) base64Encoded;
- headerAt: 'Connection' put: 'Keep-Alive';
- headerAt: 'Accept' put: '*/*' ] ]!
Item was changed:
----- Method: MCHttpRepository>>password (in category 'accessing') -----
password
self userAndPasswordFromSettingsDo: [:usr :pwd | ^pwd].
+ self user isEmptyOrNil ifTrue: [^password].
- self user isEmpty ifTrue: [^password ifNil: ['']].
password isEmptyOrNil ifTrue: [
+ self requestUserAndPassword].
- | answer |
- "Give the user a chance to change the login"
- answer := UIManager default request: 'User name for ', String cr, location
- initialAnswer: self user.
- answer isEmpty
- ifTrue: [^password]
- ifFalse: [self user: answer].
-
- password := UIManager default requestPassword: 'Password for "', self user, '" at ', String cr, location.
- ].
^ password!
Item was added:
+ ----- Method: MCHttpRepository>>requestUserAndPassword (in category 'accessing') -----
+ requestUserAndPassword
+ "Give the user a chance to change the login"
+
+ | answer |
+ answer := Project uiManager
+ request: ('User name for\{1}' withCRs translated format: {location})
+ initialAnswer: (self user ifNil: ['']).
+ answer isEmpty
+ ifTrue: [^ false]
+ ifFalse: [self user: answer].
+
+ password := Project uiManager
+ requestPassword: ('Password for "{1}" at\{2}' withCRs translated format: {self user. location}).
+ ^ true!
Item was changed:
----- Method: MCHttpRepository>>user (in category 'accessing') -----
+ user
- user
self userAndPasswordFromSettingsDo: [:usr :pwd | ^usr].
"not in settings"
+ ^user!
- ^user ifNil: ['']!
Item was changed:
----- Method: MCHttpRepository>>webClientDo: (in category 'private') -----
webClientDo: aBlock
| client attemptsLeft response result |
self class useSharedWebClientInstance ifTrue: [
"Acquire webClient by atomically storing it in the client variable and setting its value to nil."
client := webClient.
webClient := nil ].
client
ifNil: [ client := WebClient new ]
ifNotNil: [
"Attempt to avoid an error by recreating the underlying stream."
client isConnected ifFalse: [ client close ] ].
attemptsLeft := 3.
response := nil.
[ response isNil and: [ attemptsLeft > 0 ] ] whileTrue: [
+ client
+ username: self user;
+ password: self password.
+ response := [ aBlock value: client value: [:request |
+ self authorizeRequest: request forClient: client.
+ request
+ headerAt: 'Connection' put: 'Keep-Alive';
+ headerAt: 'Accept' put: '*/*' ] ]
+ on: WebAuthRequired do: [ :ex |
+ self requestUserAndPassword ifTrue: [
+ ex client
+ username: self user;
+ password: self password.
+ self authorizeRequest: ex request forClient: ex client.
+ ex resume: true ].
+ ex pass ]
+ on: NetworkError do: [ :error |
- response := [ aBlock value: client ]
- on: NetworkError
- do: [ :error |
attemptsLeft = 0 ifTrue: [ error pass ].
(3 - attemptsLeft) seconds asDelay wait.
attemptsLeft := attemptsLeft - 1.
nil "The response" ] ].
result := (response code between: 200 and: 299)
ifFalse: [
response content. "Make sure content is read."
nil ]
ifTrue: [
(RWBinaryOrTextStream with: (
response contentWithProgress: [ :total :amount |
HTTPProgress new
total: total;
amount: amount;
signal ])) reset ].
self class useSharedWebClientInstance
ifTrue: [
"Save the WebClient instance for reuse, but only if there is no client cached."
webClient
ifNil: [ webClient := client ]
ifNotNil: [ client close ] ]
ifFalse: [ client close ].
(response code = 404 "Not Found" or: [response code = 410 "Gone"]) ifTrue: [
"Need to distinguish between lookup errors and connection errors. Lookup errors will be handled by some senders following the EAFP principle. See #versionNamed:."
(NotFound object: response url) signal ].
result ifNil: [ NetworkError signal: 'Could not access ', location ].
^result!
Item was changed:
----- Method: MCHttpRepository>>writeStreamForFileNamed:replace:do: (in category 'private') -----
writeStreamForFileNamed: aString replace: ignoreBoolean do: aBlock
| stream urlString |
stream := RWBinaryOrTextStream on: String new.
aBlock value: stream.
urlString := self urlForFileNamed: aString.
urlString := self class rewriteUrl: urlString forDownload: false.
+ ^self displayProgress: ('Uploading {1}' translated format: {aString}) during: [
+ self webClientDo: [ :client :requestBlock |
+ client httpPut: urlString
+ content: stream contents
+ type: nil
+ do: requestBlock ] ]!
- ^self displayProgress: 'Uploading ', aString during: [
- self webClientDo: [ :client |
- client
- username: self user;
- password: self password;
- httpPut: urlString
- content: stream contents
- type: nil
- do: [ :request |
- request
- headerAt: 'Authorization' put: 'Basic ', (self user, ':', self password) base64Encoded;
- headerAt: 'Connection' put: 'Keep-Alive';
- headerAt: 'Accept' put: '*/*' ] ] ]!
More information about the Squeak-dev
mailing list
|