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! |
Free forum by Nabble | Edit this page |