[squeak-dev] The Inbox: WebClient-Core-ct.128.mcz
commits at source.squeak.org
commits at source.squeak.org
Mon Oct 12 21:39:12 UTC 2020
A new version of WebClient-Core was added to project The Inbox:
http://source.squeak.org/inbox/WebClient-Core-ct.128.mcz
==================== Summary ====================
Name: WebClient-Core-ct.128
Author: ct
Time: 12 October 2020, 11:39:11.062253 pm
UUID: 4766db7d-349a-8643-b64a-c843f49ef71c
Ancestors: WebClient-Core-mt.126
Reupload #2 of WebClient-Core-ct.126. Reverted reformatting, which will go into another version later.
=============== Diff against WebClient-Core-mt.126 ===============
Item was changed:
Object subclass: #WebClient
+ instanceVariableNames: 'flags server scheme timeout stream cookies proxyServer lastScheme lastServer lastPort maxRedirect redirections userAgent authParams proxyParams accessLog debugLog preAuthenticationMethod'
- instanceVariableNames: 'flags server scheme timeout stream cookies proxyServer lastScheme lastServer lastPort maxRedirect redirections userAgent authParams proxyParams accessLog debugLog'
classVariableNames: 'DebugLog FlagAcceptCookies FlagAllowAuth FlagAllowRedirect ProxyHandler'
poolDictionaries: ''
category: 'WebClient-Core'!
!WebClient commentStamp: 'ar 5/4/2010 13:17' prior: 0!
WebClient provides a simple yet complete HTTP client implementation.
To view the documentation evaluate:
HelpBrowser openOn: WebClientHelp.
!
Item was added:
+ ----- Method: WebClient>>authProcess:from:header:params: (in category 'authentication') -----
+ authProcess: request from: response header: authHeader params: params
+ "Process an authentication header.
+ Answer true if an authentication response could be generated; otherwise, false."
+
+ self
+ authDispatch: request
+ from: response
+ header: authHeader
+ params: params.
+
+ params at: #authResponse ifAbsent: [^ false].
+
+ "If we generated an authentication response for the header use it"
+ request
+ headerAt: ((response ifNotNil: [response code = 401] ifNil: [true])
+ ifTrue: ['Authorization']
+ ifFalse: ['Proxy-Authorization'])
+ put: (params at: #authMethod), ' ', (params at: #authResponse).
+
+ ^ true!
Item was changed:
----- Method: WebClient>>authenticate:from: (in category 'sending') -----
authenticate: request from: response
"Authenticate after having received a 401/407 response.
Returns true if we should retry, false if we fail here."
+ | headers params |
+
- "NOTE: The first time through we do NOT ask for credentials right away.
- Some authentication mechanisms (NTLM/Negotiate) can use the credentials
- of the currently logged on user. Consequently we only ask for credentials
- if we're unable to do so without asking. Methods that require credentials
- (basic, digest) test for their existence explicitly."
-
- | headers authHeader params |
-
"Pick the right set of parameters"
response code = 401 ifTrue:[
params := authParams.
headers := response headersAt: 'WWW-Authenticate'.
"If the connection was closed, we need to flush the
proxy params or we won't pick up prior credentials."
+ self isConnected
+ ifFalse: [self flushAuthState: proxyParams]
- self isConnected
- ifFalse:[self flushAuthState: proxyParams].
] ifFalse:[
params := proxyParams.
+ headers := response headersAt: 'Proxy-Authenticate'
- headers := response headersAt: 'Proxy-Authenticate'.
].
+
-
"Remove any old response"
params removeKey: #authResponse ifAbsent:[].
+
-
"Process the authentication header(s)"
+ headers
+ detect: [:authHeader |
+ self
+ authProcess: request
+ from: response
+ header: authHeader
+ params: params]
+ ifFound: [:authHeader | ^ true].
+
- 1 to: headers size do:[:i|
- authHeader := headers at: i.
- self authDispatch: request from: response header: authHeader params: params.
- "If we generated an authentication response for the header use it"
- params at: #authResponse ifPresent:[:resp|
- request headerAt: (response code = 401
- ifTrue:['Authorization']
- ifFalse:['Proxy-Authorization'])
- put: (params at: #authMethod), ' ', resp.
- ^true].
- ].
-
"If we fall through here this can have two reasons: One is that we don't have
a suitable authentication method. Check for that first."
params at: #authMethod ifAbsent:[^false].
+
-
"The other possibility is that the credentials are wrong.
Clean out the previous auth state and go ask for credentials."
self flushAuthState: params.
+
-
"Clean out old authentication headers"
response code = 401
ifTrue:[request removeHeader: 'Authorization'].
"Always clean out the proxy auth header since we don't support pre-authentication"
request removeHeader: 'Proxy-Authorization'.
+
-
"Signal WebAuthRequired"
(WebAuthRequired client: self request: request response: response)
signal == true ifFalse:[^false].
+
-
"And retry with the new credentials"
^self authenticate: request from: response!
Item was added:
+ ----- Method: WebClient>>preAuthenticationMethod (in category 'accessing') -----
+ preAuthenticationMethod
+ "The authentication method to be used for initial requests. Symbol, e.g. #basic or #bearer. If nil, no authentication will be used until the server requests an authentication.
+
+ NOTE: Some authentication mechanisms (NTLM/Negotiate) can use the credentials of the currently logged on user. Consequently, by default we only ask for credentials if we're unable to do so without asking."
+
+ ^ preAuthenticationMethod!
Item was added:
+ ----- Method: WebClient>>preAuthenticationMethod: (in category 'accessing') -----
+ preAuthenticationMethod: aSymbol
+ "The authentication method to be used for initial requests. See #preAuthenticationMethod."
+
+ preAuthenticationMethod := aSymbol!
Item was changed:
----- Method: WebClient>>sendRequest:contentBlock: (in category 'sending') -----
sendRequest: request contentBlock: contentBlock
"Send an http request"
| response repeatRedirect repeatAuth |
-
- "XXXX: Fixme. Pre-authenticate the request if we have valid auth credentials"
-
redirections := Dictionary new.
["The outer loop handles redirections"
repeatRedirect := false.
"Always update the host header due to redirect"
request headerAt: 'Host' put: server.
+
+ self preAuthenticationMethod ifNotNil: [:authMethod |
+ self
+ authProcess: request
+ from: nil
+ header: authMethod asString capitalized
+ params: authParams].
+
-
["The inner loop handles authentication"
repeatAuth := false.
+
-
"Connect can fail if SSL proxy CONNECT is involved"
self connect ifNotNil:[:resp| ^resp].
"Write the request to the debugLog if present"
debugLog ifNotNil:[self writeRequest: request on: debugLog].
+
-
"Send the request itself"
self writeRequest: request on: stream.
contentBlock value: stream.
+
-
response := request newResponse readFrom: stream.
response url: (scheme, '://', server, request rawUrl).
+
-
debugLog ifNotNil:[
response writeOn: debugLog.
debugLog flush.
].
response setCookiesDo:[:cookie|
self acceptCookie: cookie host: self serverUrlName path: request url.
].
accessLog ifNotNil:[
WebUtils logRequest: request response: response on: accessLog
].
"Handle authentication if needed"
(self allowAuth and:[response code = 401 or:[response code = 407]]) ifTrue:[
"Eat up the content of the previous response"
response content.
repeatAuth := self authenticate: request from: response.
].
repeatAuth] whileTrue.
+
-
"Flush previous authState.
XXXX: Fixme. authState must be preserved for pre-authentication of requests."
self flushAuthState.
+
-
"Handle redirect if needed"
(self allowRedirect and:[response isRedirect]) ifTrue:[
"Eat up the content of the previous response"
response content.
repeatRedirect := self redirect: request from: response.
].
repeatRedirect] whileTrue:[
"When redirecting, remove authentication headers"
request removeHeader: 'Authorization'.
request removeHeader: 'Proxy-Authorization'.
].
+
-
"If the response is not a success, eat up its content"
(response isSuccess or:[response isInformational]) ifFalse:[response content].
+
-
^response!
More information about the Squeak-dev
mailing list
|