[Pharo-project] [Zinc] ZnTooManyRedirects exception
Hello, I'm busy updating CloudforkSSO to use the latest version of the Zinc http client (ZnClient). Most of the required changes are pretty simple. But I have a problem with redirects. I cannot let ZnClient handle the redirects because I need to update the Authorization header. So I use the dontFollowRedirects option and proces the redirect myself. But now ZnClient signals a ZnTooManyRedirects exception when a redirect response is received. It seems more logical to me to just answer the response. Especially when the numberOfRetries option is greater than zero. It's no use retrying a request that answers a redirect. Is it possible to change ZnClient so that it doesn't signal a ZnTooManyRedirects when the maxNumberOfRedirects is zero? Jan. PS: For the rest I really like the simple but powerful interface of ZnClient!
Hi Jan, Nice to hear from you again. On 23 Nov 2011, at 13:45, Jan van de Sandt wrote:
Hello,
I'm busy updating CloudforkSSO to use the latest version of the Zinc http client (ZnClient). Most of the required changes are pretty simple. But I have a problem with redirects.
I cannot let ZnClient handle the redirects because I need to update the Authorization header. So I use the dontFollowRedirects option and proces the redirect myself. But now ZnClient signals a ZnTooManyRedirects exception when a redirect response is received.
It seems more logical to me to just answer the response. Especially when the numberOfRetries option is greater than zero. It's no use retrying a request that answers a redirect.
Is it possible to change ZnClient so that it doesn't signal a ZnTooManyRedirects when the maxNumberOfRedirects is zero?
Jan.
As one of the more advanced users of Zn you are right of course: if you want to handle redirects yourself, setting dontFollowRedirects will give you a ZnTooManyRedirects exception when one occurs, which is stupid. And indeed, retrying instead of following redirects does also not make much sense ;-) Let me think a bit about this, and I will come back to you. I'll have to write some tests too.
PS: For the rest I really like the simple but powerful interface of ZnClient!
Thank you! Sven
I really like such kind of exchange. Constructive and positive energy: this is what makes a powerful community and give us energy to out pass ourselves. Stef On Nov 23, 2011, at 2:12 PM, Sven Van Caekenberghe wrote:
Hi Jan,
Nice to hear from you again.
On 23 Nov 2011, at 13:45, Jan van de Sandt wrote:
Hello,
I'm busy updating CloudforkSSO to use the latest version of the Zinc http client (ZnClient). Most of the required changes are pretty simple. But I have a problem with redirects.
I cannot let ZnClient handle the redirects because I need to update the Authorization header. So I use the dontFollowRedirects option and proces the redirect myself. But now ZnClient signals a ZnTooManyRedirects exception when a redirect response is received.
It seems more logical to me to just answer the response. Especially when the numberOfRetries option is greater than zero. It's no use retrying a request that answers a redirect.
Is it possible to change ZnClient so that it doesn't signal a ZnTooManyRedirects when the maxNumberOfRedirects is zero?
Jan.
As one of the more advanced users of Zn you are right of course: if you want to handle redirects yourself, setting dontFollowRedirects will give you a ZnTooManyRedirects exception when one occurs, which is stupid.
And indeed, retrying instead of following redirects does also not make much sense ;-)
Let me think a bit about this, and I will come back to you.
I'll have to write some tests too.
PS: For the rest I really like the simple but powerful interface of ZnClient!
Thank you!
Sven
Jan, On 23 Nov 2011, at 14:12, Sven Van Caekenberghe wrote:
Let me think a bit about this, and I will come back to you.
I added some new features so that now this should work: testRedirectDontFollow | client | (client := ZnClient new) dontFollowRedirects; get: 'http://www.pharo-project.org'. self assert: client response isRedirect. client enforceHttpSuccess: true; get: 'http://www.pharo-project.org'. self assert: client response isRedirect. client close I think this will cover your use case, please let me know how it goes. I discovered that I more ore less already had something that came close: testRedirect | client response | client := ZnClient new url: 'http://www.pharo-project.org'. self assert: (client get; isSuccess). client close; maxNumberOfRedirects: 0; url: 'http://www.pharo-project.org'. self should: [ client get ] raise: ZnTooManyRedirects. client close. response := [ ZnClient new beOneShot; maxNumberOfRedirects: 0; get: 'http://www.pharo-project.org'; response ] on: ZnTooManyRedirects do: [ :exception | exception resume ]. self assert: response isRedirect Resuming the exception gave a true redirect response. But that code is not very nice/handy, and it would not work when combined with enforceHttpSuccess: true. These are new commits: ==================== Summary ==================== Name: Zinc-HTTP-SvenVanCaekenberghe.221 Author: SvenVanCaekenberghe Time: 23 November 2011, 5:30:09 pm UUID: 4df9982e-63e1-49ea-bfb0-2f9cb43f6f0b Ancestors: Zinc-HTTP-SvenVanCaekenberghe.220 added new #followsRedirects boolean option to ZnClient because setting #maxNumberOfRedirects to 0 did not work well for an example see the ZnClientTests>>#testRedirectDontFollow Thx Jan van de Sandt for reporting this ==================== Summary ==================== Name: Zinc-Tests-SvenVanCaekenberghe.115 Author: SvenVanCaekenberghe Time: 23 November 2011, 5:31:22 pm UUID: eb8c67e4-bdf2-4741-b149-78bdaf5d4970 Ancestors: Zinc-Tests-SvenVanCaekenberghe.114 added ZnClientTests>>#testRedirectDontFollow to test the new #followsRedirects boolean option to ZnClient, including under the case of #enforceHttpSuccess: true Regards, Sven
http://code.google.com/p/pharo/issues/detail?id=5014 :) On Nov 23, 2011, at 5:37 PM, Sven Van Caekenberghe wrote:
Jan,
On 23 Nov 2011, at 14:12, Sven Van Caekenberghe wrote:
Let me think a bit about this, and I will come back to you.
I added some new features so that now this should work:
testRedirectDontFollow | client | (client := ZnClient new) dontFollowRedirects; get: 'http://www.pharo-project.org'. self assert: client response isRedirect. client enforceHttpSuccess: true; get: 'http://www.pharo-project.org'. self assert: client response isRedirect. client close
I think this will cover your use case, please let me know how it goes.
I discovered that I more ore less already had something that came close:
testRedirect | client response | client := ZnClient new url: 'http://www.pharo-project.org'. self assert: (client get; isSuccess). client close; maxNumberOfRedirects: 0; url: 'http://www.pharo-project.org'. self should: [ client get ] raise: ZnTooManyRedirects. client close. response := [ ZnClient new beOneShot; maxNumberOfRedirects: 0; get: 'http://www.pharo-project.org'; response ] on: ZnTooManyRedirects do: [ :exception | exception resume ]. self assert: response isRedirect
Resuming the exception gave a true redirect response.
But that code is not very nice/handy, and it would not work when combined with enforceHttpSuccess: true.
These are new commits:
==================== Summary ====================
Name: Zinc-HTTP-SvenVanCaekenberghe.221 Author: SvenVanCaekenberghe Time: 23 November 2011, 5:30:09 pm UUID: 4df9982e-63e1-49ea-bfb0-2f9cb43f6f0b Ancestors: Zinc-HTTP-SvenVanCaekenberghe.220
added new #followsRedirects boolean option to ZnClient because setting #maxNumberOfRedirects to 0 did not work well for an example see the ZnClientTests>>#testRedirectDontFollow Thx Jan van de Sandt for reporting this
==================== Summary ====================
Name: Zinc-Tests-SvenVanCaekenberghe.115 Author: SvenVanCaekenberghe Time: 23 November 2011, 5:31:22 pm UUID: eb8c67e4-bdf2-4741-b149-78bdaf5d4970 Ancestors: Zinc-Tests-SvenVanCaekenberghe.114
added ZnClientTests>>#testRedirectDontFollow to test the new #followsRedirects boolean option to ZnClient, including under the case of #enforceHttpSuccess: true
Regards,
Sven
Hello Sven, Yes, this is exactly what I need. Thanks very much for the quick fix! I know that resuming the exception also works. That was the solution that I used until now. But the new solution is much nicer. Jan. On Wed, Nov 23, 2011 at 5:37 PM, Sven Van Caekenberghe <sven@beta9.be>wrote:
Jan,
On 23 Nov 2011, at 14:12, Sven Van Caekenberghe wrote:
Let me think a bit about this, and I will come back to you.
I added some new features so that now this should work:
testRedirectDontFollow | client | (client := ZnClient new) dontFollowRedirects; get: 'http://www.pharo-project.org'. self assert: client response isRedirect. client enforceHttpSuccess: true; get: 'http://www.pharo-project.org'. self assert: client response isRedirect. client close
I think this will cover your use case, please let me know how it goes.
I discovered that I more ore less already had something that came close:
testRedirect | client response | client := ZnClient new url: 'http://www.pharo-project.org'. self assert: (client get; isSuccess). client close; maxNumberOfRedirects: 0; url: 'http://www.pharo-project.org'. self should: [ client get ] raise: ZnTooManyRedirects. client close. response := [ ZnClient new beOneShot; maxNumberOfRedirects: 0; get: 'http://www.pharo-project.org'; response ] on: ZnTooManyRedirects do: [ :exception | exception resume ]. self assert: response isRedirect
Resuming the exception gave a true redirect response.
But that code is not very nice/handy, and it would not work when combined with enforceHttpSuccess: true.
These are new commits:
==================== Summary ====================
Name: Zinc-HTTP-SvenVanCaekenberghe.221 Author: SvenVanCaekenberghe Time: 23 November 2011, 5:30:09 pm UUID: 4df9982e-63e1-49ea-bfb0-2f9cb43f6f0b Ancestors: Zinc-HTTP-SvenVanCaekenberghe.220
added new #followsRedirects boolean option to ZnClient because setting #maxNumberOfRedirects to 0 did not work well for an example see the ZnClientTests>>#testRedirectDontFollow Thx Jan van de Sandt for reporting this
==================== Summary ====================
Name: Zinc-Tests-SvenVanCaekenberghe.115 Author: SvenVanCaekenberghe Time: 23 November 2011, 5:31:22 pm UUID: eb8c67e4-bdf2-4741-b149-78bdaf5d4970 Ancestors: Zinc-Tests-SvenVanCaekenberghe.114
added ZnClientTests>>#testRedirectDontFollow to test the new #followsRedirects boolean option to ZnClient, including under the case of #enforceHttpSuccess: true
Regards,
Sven
Hello, I am in the process of moving my application over to GLASS. I had been developing using one-click Pharo with Cloudfork and all of my calls to the Amazon services were working correctly. Now, I'm trying to do the same thing under Gemstone GLASS. I have loaded a bunch of the Cloudfork packages and I am able to instantiate an S3 bucket in Amazon but I am running into authentication problems when I try to create something in the bucket, due to missing pieces of the SHA1 class. Are there directions somewhere on how to set this up under GLASS? Has it been done before? Thanks for the help! Larry
Hello Larry, Cloudfork was developed on Pharo Smalltalk and ported to VW and VA Smalltalk. But not yet to Gemstone. We tried to isolate the platform specific code. Most of it is implemented as platform specific subclasses of CFPlatformServiceUtils. CloudforkAWS requires an XML parser, a SHA1 or SHA256 implementation and a HTTP client. I don't know if it has been done before but I think it should be possible to create a platform class for Gemstone that offers access to these functions. I don't have experience with Gemstone. The GLASS mailing list is probably the best source to ask. Jan. On Wed, Jan 11, 2012 at 8:29 PM, Lawrence Kellogg <mac.hive@me.com> wrote:
Hello, I am in the process of moving my application over to GLASS. I had been developing using one-click Pharo with Cloudfork and all of my calls to the Amazon services were working correctly.
Now, I'm trying to do the same thing under Gemstone GLASS. I have loaded a bunch of the Cloudfork packages and I am able to instantiate an S3 bucket in Amazon but I am running into authentication problems when I try to create something in the bucket, due to missing pieces of the SHA1 class. Are there directions somewhere on how to set this up under GLASS? Has it been done before?
Thanks for the help!
Larry
Hello Jan, On Jan 12, 2012, at 3:34 AM, Jan van de Sandt wrote:
Hello Larry,
Cloudfork was developed on Pharo Smalltalk and ported to VW and VA Smalltalk. But not yet to Gemstone. We tried to isolate the platform specific code. Most of it is implemented as platform specific subclasses of CFPlatformServiceUtils.
CloudforkAWS requires an XML parser, a SHA1 or SHA256 implementation and a HTTP client. I don't know if it has been done before but I think it should be possible to create a platform class for Gemstone that offers access to these functions. I don't have experience with Gemstone. The GLASS mailing list is probably the best source to ask.
Thanks for the explanation. Cloudfork is great, thanks for your work. I'll try to getting it working under GLASS but I don't have a lot of time. I got this response on the GS/SS Beta mailing list from James Foster: "Larry, Porting an application fromPharo to Version 3.0.1 should be similar to porting to 2.4.4.x. There are a number of new features (some, like FFI are necessary for you) and performance enhancements. On the other hand, people who have existing projects have not rushed to migrate from 2.x to 3.x so there is not as much production experience with Seaside on 3.x. I've been porting some of our tests to use FFI and have found a couple issues with the VM that should be fixed in 3.0.2 (schedule pending based on demand). I have also done a bit to improve the CHeader parsing. It is certainly our goal with FFI that it be fairly easy to use. In the last hour I've come up with the following in 3.1, and expect that it should be similar in 3.0.1. First, build a class that represents the library: | header class | header := CHeader path: '/usr/include/openssl/sha.h'. class := header wrapperForLibraryAt: '$GEMSTONE/lib/libcrypto.so'. class initializeFunctions. UserGlobals at: class name put: class. Next, use the library: | string result bytes | string := 'Now is the time for all good men to come to the aid of their party'. result := Crypto new SHA1_: string _: string size _: nil. bytes := result asArray collect: [:each | each codePoint]. result class -> bytes. String->anArray( 249, 92, 62, 72, 141, 165, 168, 163, 45, 23, 107, 2, 204, 233, 20, 250, 66, 180, 132, 37) I don't know anything about SSH-1, but this seems to match the info I found (using Google) at http://linux.die.net/man/3/sha. Do you think you would need much more? -James " Do you think this will be enough to get a working Cloudfork? Regards, Larry
Jan.
On Wed, Jan 11, 2012 at 8:29 PM, Lawrence Kellogg <mac.hive@me.com> wrote: Hello, I am in the process of moving my application over to GLASS. I had been developing using one-click Pharo with Cloudfork and all of my calls to the Amazon services were working correctly.
Now, I'm trying to do the same thing under Gemstone GLASS. I have loaded a bunch of the Cloudfork packages and I am able to instantiate an S3 bucket in Amazon but I am running into authentication problems when I try to create something in the bucket, due to missing pieces of the SHA1 class. Are there directions somewhere on how to set this up under GLASS? Has it been done before?
Thanks for the help!
Larry
participants (4)
-
Jan van de Sandt -
Lawrence Kellogg -
Stéphane Ducasse -
Sven Van Caekenberghe