The Inbox: WebClient-Core-ct.128.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

The Inbox: WebClient-Core-ct.128.mcz

commits-2
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!