Simon Fell > Its just code
Monday, June 7, 2004
A popular question recently, you have 2 choices, (1) go grab the WSDL Wizard and have it generate all the code for you or (2) follow this example.
This quick demo will call a method from the SOAPBuilders Interop tests called echoStructArray, this method takes an array of structures (aka ComplexTypes) as input and echos the array back as output (see the WSDL for the details. By default, an array of complex types is going to be represented in PocketSOAP as an array of CoSoapNode objects, each Node object will have child nodes in the Nodes property containing the child elements. So to create an array of complex types, we need to declare the array, then populate each array item with a CoSoapNode object, e.g.
Dim arr(2) As Object
Set arr(0) = makeSoapStruct("String one", 1, 1.1)
Set arr(1) = makeSoapStruct("String two", 2, 2.2)
Set arr(2) = makeSoapStruct("String three", 3, 3.3)
Where makeSoapStruct is defined as
' helper function to create a SOAPStruct complex type
Private Function makeSoapStruct(varString As String, varInt As Long, varFloat As Single) As CoSoapNode
Dim ct As New CoSoapNode
ct.Nodes.Create "varString", varString
ct.Nodes.Create "varInt", varInt
ct.Nodes.Create "varFloat", varFloat
Set makeSoapStruct = ct
End Function
To handle the response, its just the reverse, grab the parameter, its value will be an array of variants, each variant will contain a CoSoapNode object, e.g.
'get the returned array
Dim res()
res = e.Parameters.Item(0).Value
' iterate over it
Dim idx As Integer
Dim n As CoSoapNode
For idx = LBound(res) To UBound(res)
' each item in the array is a soapnode, with child nodes for varString, varInt, varFloat
Set n = res(idx)
List1.AddItem n.Nodes.ItemByName("varString").Value & " " & n.Nodes.ItemByName("varInt").Value & " " & n.Nodes.ItemByName("varFloat").Value
Next
That's all there is to it!. The full VB code is available for download (2k), for reference, these are the generated request and response messages from this code.
POST http://soap.4s4c.com/ilab/soap.asp HTTP/1.1
Host: soap.4s4c.com
Accept-Charset: UTF-8, UTF-16;q=0.8, iso-8859-1;q=0.8
Accept-Encoding: deflate, gzip
Content-Type: text/xml; charset=UTF-8
SOAPAction: "http://soapinterop.org/"
User-Agent: PocketSOAP/1.5.b1/PocketHTTP/1.2
Content-Length: 1209
<S:Envelope
xmlns:Enc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:a="http://soapinterop.org/"
xmlns:XS="http://www.w3.org/2001/XMLSchema"
xmlns:XI="http://www.w3.org/2001/XMLSchema-instance">
<S:Body>
<a:echoStructArray S:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<inputStructArray XI:type="Enc:Array" Enc:arrayType="XS:anyType[3]">
<x href="#3dd43e4"/>
<x href="#3ddd48c"/>
<x href="#3dd42bc"/>
</inputStructArray>
</a:echoStructArray>
<x S:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" Enc:root="0" id="3dd42bc">
<varString XI:type="XS:string">String three</varString>
<varInt XI:type="XS:int">3</varInt>
<varFloat XI:type="XS:float">3.3</varFloat>
</x>
<x S:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" Enc:root="0" id="3ddd48c">
<varString XI:type="XS:string">String two</varString>
<varInt XI:type="XS:int">2</varInt>
<varFloat XI:type="XS:float">2.2</varFloat>
</x>
<x S:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" Enc:root="0" id="3dd43e4">
<varString XI:type="XS:string">String one</varString>
<varInt XI:type="XS:int">1</varInt>
<varFloat XI:type="XS:float">1.1</varFloat>
</x>
</S:Body>
</S:Envelope>
HTTP/1.1 200 OK
Date: Tue, 08 Jun 2004 03:23:52 GMT
Server: Microsoft-IIS/5.0
Content-Length: 1175
Content-Type: text/xml; charset=UTF-8
Expires: Tue, 08 Jun 2004 03:23:52 GMT
Cache-control: private
X-Cache: MISS from mayhem.pocketsoap.com
<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<m:echoStructArrayResponse xmlns:m="http://soapinterop.org/">
<outputStructArray xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="ns1:SOAPStruct[3]" xmlns:ns1="http://soapinterop.org/xsd">
<SOAPStruct xsi:type="ns1:SOAPStruct">
<varString xsi:type="xsd:string">String one</varString>
<varInt xsi:type="xsd:int">1</varInt>
<varFloat xsi:type="xsd:float">1.1</varFloat>
</SOAPStruct>
<SOAPStruct xsi:type="ns1:SOAPStruct">
<varString xsi:type="xsd:string">String two</varString>
<varInt xsi:type="xsd:int">2</varInt>
<varFloat xsi:type="xsd:float">2.2</varFloat>
</SOAPStruct>
<SOAPStruct xsi:type="ns1:SOAPStruct">
<varString xsi:type="xsd:string">String three</varString>
<varInt xsi:type="xsd:int">3</varInt>
<varFloat xsi:type="xsd:float">3.3</varFloat>
</SOAPStruct>
</outputStructArray>
</m:echoStructArrayResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Sunday, May 9, 2004
This tutorial shows how to use PocketSOAP to access SForce, the Salesforce.com Web Services API.
- First off, if you don't have a salesforce.com account, head over to sforce.com and sign up for the free developers edition account
- Next, make sure you've got PocketSOAP and the PocketSOAP WSDL Wizard (v2.3 or greater) installed.
- Now we need to grab the WSDL for your account, login to salesforce.com, click the setup link at the top right, then from the left menu under studio select WSDL Generator. Finally, right click on the Download Enterprise WSDL link and select save link to disk, and save the WSDL somewhere on your machine.
- Now we can run it through the WSDL Wizard to get an easy to use object model generated for us. Start the WSDL Wizard, enter the path and filename of the WSDL in the top box, and the second line select a directory for it to generate the VB6 files to, and enter sforce as the name of the project in the bottom box.
- Hit next, you'll be presented with the list of bindings, of which there's only one, so hit next again, now you can see the list of methods, leave them all selected and hit next again. The Wizard will now generate the code, then say its finished. Click OK to close the wizard.
- If everything went according to plan, you now have a ton of generated VB code (~200 classes!), open the sforce.vbp project and compile it.
- Now start a new VB standard EXE project, and do add reference, scroll down the list and pick "SForce Proxy class....". The main entry point into the generated proxy code is the Soap class (this is named from the WSDL), if you look at this in the object browser, you'll see a bunch of methods, one for each one listed in the WSDL.
Now, in order to access the data we need to login, so drop a button on your form, and add this code
' create the proxy object and the login message
Dim svc As New Soap
Dim lr As loginResponse
Dim lo As New login
lo.Username = "<your login>"
lo.password = "<your password>"
' login
Set lr = svc.login(lo)
SForce uses a document/literal style service, so the programming model exposed by the generated proxy has a method for each operation in the WSDL where each method takes an object that represents the request message, and returns an object that represents the response message. In addition any SOAP headers that may apply to the operation are also passed as parameters to the method (this is likely different to the programming model generated by other tools, I'll save why I think this is better for another day)
Now, going back to our login code, you can see that we create an instance of the login message, populate its data (username & password in this case), and call the login method, this returns a loginResponse message.
The loginResponse message contains a single loginResult stucture that contains a few pieces of useful information, the 2 important ones are the serverUrl and the sessionId. In the SForce world, once you're authenticated you communicate with a different server (as indicated by the serverUrl value), and you tell it your authentication info by passing the sessionId back to the server in a SOAP Header. So what we'll do next is create the SOAP header object, and populate it with the sessionId, and point the proxy object at the new Url.
' create the session header, and update the server Url that we connect to
Dim sh As New SessionHeader
sh.sessionId = lr.result.sessionId
svc.Url = lr.result.serverUrl
Now, we'll create a couple of new Accounts, we do this via the create operation, here's how the object browser shows the create method.
The create_ parameter is the create message, and there's 2 headers we can send, the SessionHeader which we've already discussed and the SaveOptions header, this header lets use control how lead assignment is handled, which we don't care about for Accounts, so we can just pass nothing for that in this case.
The create message contains an array of sObjects, everything in Salesforce.com is based on an sObject, the Account object inherits (or extends in XSD speak) from sObject. So, we need to create an array of sObjects, where each item in the array is an account. One wrinkle is that VB won't let you pass a statically sized array to a property call, so you need to ensure that your array is dynamically sized (i.e. use redim)
' create 2 new accounts, note that the create call uses an object hierarchy
' but in VB we need to pass sObject() to the create call, so declare the array
' as that, but populate it with account objects
Dim acc() As sObject
ReDim acc(1)
Dim na As New Account
na.Name = "Simon's Test Account"
na.AccountNumber = "42424242"
na.AnnualRevenue = 10000
Set acc(0) = na
Set na = New Account
na.Name = "Simon's other test account"
na.AccountNumber = "24242424"
na.AnnualRevenue = 11111
Set acc(1) = na
Now we've got the 2 accounts we want to create, we can create the Create message, and make the call to the create operation.
' do the create call
Dim cr As New Create
cr.sObjects = acc
Dim cres As createResponse
Set cres = svc.Create(cr, sh, Nothing)
All that's left is to check the response, to see if there are any errors (as there might be an error with only a single object, there's a separate error indication for each Account we tried to create).
' check the results
Dim idx As Long
For idx = LBound(cres.result) To UBound(cres.result)
If Not cres.result()(idx).success Then
debug.print "failed creating account: " & cres.result()(idx).errors()(0).message
Else
debug.print "created account with Id " + cres.result()(idx).id
End If
Next
That's it!, you can now login through the web interface and see the new accounts you've created, the rest of the functions all work in the same manner, finally the describeSObject call exposes a lot of information about the fields on each of the sObjects derived types in the system (including any custom fields or custom objects you may of created yourself through studio), making it easy to do grid views and similar that are completely driven by the meta data.
Sunday, May 25, 2003
I read a lot of technical books, here are a few of my recent reads that I liked. (in no particular order)
- Programming the Microsoft Windows Driver Model (Walter Oney)
- Windows Forms Programming in C# (Chris Sells)
- Beyond Fear (Bruce Schneier)
- Loosely Coupled (Doug Kay)
- Essential ASP.NET (Fritz Onion)
- Essential .NET volume 1 (Don Box)
- .NET Web Services: Architecture and Implementation with .NET (Keith Ballinger)
- More Exceptional C++ (Herb Sutter)
- Advanced .NET Remoting (Ingo Rammer)
- Definitive XML Schema (Priscilla Walmsley)
- Effective STL (Scott Meyers)
- Transactional COM+ (Tim Ewald)
- C# Essentials (Peter Drayton & co)
- Essential IDL (Martin Gudgen)
- ASP Internals (John Flanders)
- Secrets & Lies (Bruce Schneier)
- Planning Extreme Programming (Kent Beck, Martin Fowler)
- Network Security Private communication in a public world (Charlie Kaufman, Radia Perlman & Mike Speciner)
- The Pragmatic Progammer (Andrew Hunt & David Thomas), I liked this so much, i brought copies for everyone on my team.
- Programming Windows Security (Keith Brown)
- Essential XML (Don Box, Aaron Skonnard & John Lam)
- Exceptional C++ (Herb Sutter)
- Debugging Applications (John Robbins)
- Windows Forms Programming in C#
- Mac OSX for Unix Geeks
- Applied .NET Framework Programming (Jeffrey Richter)
Saturday, May 17, 2003
Syndirella is an RSS aggregator written in C# by Dmitry Jemerov released under the GPL license. This page details a fork of the code base that I've been adding new features to.
Latest drop is 20030509-BT (released May 16, 2003) and is based on Dmitry's drop of May 9, and adds the following features
- Plugin support. Supports both IBlogThis and IBlogExtension based plugins. Multiple plugs in are supported, just drop them in a plugins directory under the main Synderilla executable.
- Support for displaying xhtml:body based item content.
- Support for gzip/deflate compression when retrieving RSS feeds over HTTP.
An earlier drop is detailed here
Tuesday, April 8, 2003
Being able to post to a weblog from within an RSS aggregator is a really useful feature that not many tools currently have. The proliferation of blogging API compounds the problem. Given the number of .NET based aggregators now around, I had a vision for a simple extensibility point within the aggregator to be able to hook in 3rd party blogging tools. This page documents my thoughts, ideas, and code to date.
IBlogExtension
Greg, Luke, Matt, and I discussed a new version of the interface that resulted in IBlogExtension.A signed version of the assembly containing the IBlogExtension definition is available.
Aggregators
- Greg Reinacker announced that NewsGator 1.2 will support this.
- Synderilla 20030509-BT
- RSSBandit v1.1
Plug-Ins
Previous version
IBlogThis enabled Aggregators
BlogThis plug-ins
BlogIT extension to BlogThis
- Greg's initial BlogIT proposal
- Comments from Simon Fell and Douglas P
- More thoughts from Greg.
IBlogThis history
- April 14 weblog post revised details about the structure of the doucment passed to the plugin.
- BlogX gets BlogThis support
- April 12 weblog post on a strongly typed version of the IBlogThis interface.
- Relaxer updated with BlogThis support
- April 9 weblog post detailing the structure of the rss fragment XML.
- As everyone needs to refer to the same assembly for the BlogThis interface, I put together a signed version of the interface I posted.
- April 8 weblog post about first prototype
- April 6 weblog post, first attempt to explain idea, plus link to Brads post which kicked it all off
Tuesday, April 8, 2003
In progress - A RESTLog client application.
Version 0.6 (October 18, 2005)
binaries and/or source- Support for uploading "media" files (images, zips etc, supporting files for a blog post), just drop the file on the Media Upload Zone. (requires the latest RESTLog.NET server code)
Version 0.5 (May 16, 2003)
binaries and/or source.- Support for IBlogExtension added.
- Improvements to the trackback/pingback client.
Version 0.4 (April 27, 2003)
binairies and/or source.- Pingback and Trackback client support added.
- Support for getting the now playing info from Windows Media Player (requires the WMP blogging plugin)
Version 0.3 (April 15, 2003)
binairies and/or source.- BlogThis integration updated to current spec.
- Spell Checker now behaves in a more expected manner (closing the dialog, cancels the spell check, and cancels the post)
- code button added for turning the selected part of the post into a <pre> wrapped section, it also entity encodes the selection, make its easy to cut'n'paste exsiting code/xml etc into a post.
- xml-rpc pings are now sent asynchronously
- dropping a link on the form will select the best match weblog from all those configured, rather than requiring you to pick the right one first.
Version 0.2 (April 9, 2003)
Sunday, April 6, 2003
Installation
This assumes you're familar with configuring IIS & ASP.NET.
- Make sure you have ASP.NET installed and running correctly first.
- unzip the file, preserving directories somewhere convienient ( e.g. c:\inetpub\wwwroot\blog )
- if you need to, goto IIS admin and create a virtual directory that maps to the directory with the index.config file in. Note that this is entirely optional, but makes things slightly easier.
- If you didn't create a virtual dir, then move the dll's out of the bin directory to the parent app's bin directory ( e.g. c:\inetpub\wwwroot\bin )
- Using IIS admin add an application mapping for .html to the ASP.NET Isapi extension. make sure that "check that file exists" is NOT checked. If you choose the limit verbs option, you need to allow GET, POST, PUT, DELETE.
Configuration settings for the weblog are stored in the web.config file, open it up in notead, emac, vi, or whatever your particular text editor posion is.
- <configSections> - this registers the handler for the <restlog.net> section.
- <httpHandlers> - this maps .html requests onto the weblog engine.
- <restlog.net> - this houses all the weblog configuration, this is what you'll want to edit.
- <title> - the title of your weblog, this appears on the web pages, as well as being included in the generated RSS file.
- <description> - the tagline/description for your weblog, this also appears on the web pages and the RSS file.
- <author> - enter the name of the weblog's author
- <indexMaxPosts> - controls the number of entries that appear on the main page, the default is to show the most recent 15 posts, wind this up or down as the mood takes you.
- <rssMaxPosts> - controls the number of entries that appear in the RSS file, the default is to show the most recent 15 posts, wind this up or down as the mood takes you.
- <doPingbacks> - If enabled (by setting the value to true), each time you make a new post, it will automatically check the post for links, and send pingbacks to those servers that support it.
- <rss> - the name of the generated rss file.
- <basepath> - Important set this to the external path to the root of the blog, i.e., if you installed to c:\inetpub\wwwroot\blog\, then it would be /blog/ if you created a virtual directory call weblog in the root of the web server then it would be /weblog/
- <templates> - the names of the 3 templates used. by default these are mapped to .config files, as these won't be served to external clients.
- <main> - this is the main index page, that shows the most recent posts.
- <monthly> - this is the monthly archive page, by default it uses the same template as the main index, but it doesn't have to, if you want your monthly archive pages to do something different.
- <item> - this is the template for a single post page.
The template files index.config and item.config are standard ASPX files, but with a .config file extension. They use ASP.NET's code behind feature so that the weblog engine can provide the relevant information to be rendered. The main and monthly index pages should inherit from the class PocketSoap.RestLog.IndexPage and the item page should inherit from PocketSoap.RestLog.ItemPage.
Both classes expose the information from the web.config file via an instance of the WeblogSettings class available via the Weblog property. The WeblogSettings class has the following properties Title, Description, Author, IndexMaxPosts, RssMaxPosts, DoPingbacks, RssFile, BasePath, MainTemplate, MonthlyTemplate, ItemTemplate.
The Item template exposes the details of the post via an item object, accessed via the Item property, this has the following properties title, description, date, tune, postId, Link, permaLink
The index pages expose a collection (ArrayList) of items to be rendered via the Items property. In addition it has an additional property called ArchiveDate that contains the date of the monthly archived being rendered or the value DateTime.MinValue if its the main index page.
Sunday, April 6, 2003
This weblog is based on an implementation of the RESTLog API that I wrote in .NET. The source code is available under the MIT license, for those who are interesting in running / examining / extending this themselves
Sever (RESTLog.NET v0.1)The server is implemented as a number of custom HttpHandlers that are compiled to a DLL, and has the following features
- Any number of weblog instances can be run on a single ASP.NET install.
- configuration for a particular instance of a weblog is handled entirely in the web.config file.
- template files (ordinary aspx format pages) are used to control the look & feel / rending of the pages.
- A static RSS (1.0) file is generated each time there's a change.
- Support for automatic pingbacks.
- main index page show recent entries, there are also monthly archive pages and individual post pages.
- posts are stored as simple XML files, easy to migrate to/from other blogging tools.
You can download the binaries and source for v0.1, then take a gander at the installation and configurations notes. The latest code is available on SourceForge
Client (relaxer.NET v0.6)A .NET Winforms application for adding/updating/deleting posts for any RESTLog compliant server
- Simple interface, supports multiple weblogs
- Spell checker (requires MS Word)
- Winamp integration (requires WS-Amp) & WMP9 integration (requires the Blog Plugin)
- Drag'n'drop from the browser to edit.
- Can ping weblogs.com plus any other servers that implement the weblogs.com ping interface.
- Includes a pingback & trackback client.
Still in progress, v0.6 is now available.
Client (relaXer v0.1)A Cocoa application for Mac OS X for adding/updating/deleting posts for any RESTLog compliant server
- Native Cocoa application
- Spell Checker
- iTunes integration
- Drag'n'drop from the browser to edit
Still in progress, here a screen shot, to keep you going.
Saturday, February 8, 2003
This tool allows you to automatically notify blo.gs (or any number of services that implements the weblogs.com xml-rpc interface) when you update your weblog
Download the blogping.root file and drop it in your Radio Userland\\tools directory and re-start Radio, you should be up and running.
Version History
v0.2 - 3/17/2003
Can now ping any number of servers, defaults to blo.gs and blogrolling.com.
v0.1 - 2/8/2003
Initial Release
Wednesday, January 1, 2003
Pingback provide for a more connected weblogging experience. This tool is a pingback client tool for Radio, it will automatically send pingback's to those servers that support them when you post entries in your weblog.
Download the pingback.root file and drop it in your Radio Userland\tools directory and re-start radio, you should be up and running.
Version History
v0.4 - 1/11/2003
Fixed a bug where the first link in a post wouldn't get pingback checked if there was more than one link in the post.
v0.3 - 1/8/2003
The <link rel="pingback" ..> tag is now searched for if it can't find a X-Pingback HTTP header as per the auto discovery part of the specification.
The bulk of the pingback work is now spawned off onto a separate thread, so as not to adversly affect upstreaming performance.
Fixed a problem where links with fragment Ids didn't get the fragment Id stripped off the HTTP request.
Verbose logged is turned off [it was on in v0.2 by accident]
v0.2 - 1/1/2003
The pingback url sent now includes the fragmentID of the particular post
v0.1 - 1/1/2003
Initial Release
Saturday, September 28, 2002
An investigation into the current state of namespace awareness in RSS aggregators.
TestsI defined a set of test RSS feeds, both RSS 1.0 and RSS 2.0, these use a mix of modules, differing namespace usage styles, and clashing localnames, this should give a good indication as to how well current aggregators cope with RSS 1.0 & 2.0's ability to be extended with namespaced modules.
- rss1.0withModules.xml
- rss1.0withModulesNoDefNS.xml
- rss1.0withModulesNoDefNSLocalNameClash.xml
- rss2.0noNSwithModules.xml
- rss2.0noNSwithModulesLocalNameClash.xml
- rss2.0NSwithModules.xml
- rss2.0NSwithModulesNoDefNS.xml
- rss2.0NSwithModulesNoDefNSLocalNameClash.xml
My own personal suspicion before running any tests is that the aggregators that haven't needed any changes to work with RSS2.0 aren't handling namespaces properly, and the localName clash tests will trip them up.
Results
Aggie RC4 on XP
- Fails to show entries
- Fails to show entries
- Shows entries from wrong namespace (shows the last szf:description item, probably just looking at the last element it finds with a description localname)
- Entry appears
- Shows entries from wrong namespace (shows the last szf:description item, probably just looking at the last element it finds with a description localname)
- Entry appears
- Entry appears
- Shows entries from wrong namespace (shows the last szf:description item, probably just looking at the last element it finds with a description localname)
It appears that Aggie doesn't really like RSS 1.0, i don't understand yet why test 6&7 (rss2 with NS) work, yet tests 1&2 (rss1) fail. It looks like aggie is ingoring element namespaces, and just looking for localname matches.
Aggie (built from CVS 9/28) on XP
- Entry appears
- Entry appears
- Entry appears
- Entry appears
- Entry appears
- Entry appears
- Entry appears
- Entry appears
Radio 8.0.5 on XP with radio.root updated 9/28
- Entry appears
- Entry appears
- shows entry from wrong namespace, appears to show the first element with a localname of description
- Entry appears
- shows entry from wrong namespace, appears to show the first element with a localname of description
- Entry appears
- Entry appears
- shows entry from wrong namespace, appears to show the first element with a localname of description
NetNewsWire Lite 1.0 on Mac OS 10.2.1
- Entry appears
- Entry appears
- Entry appears
- Entry appears
- Entry appears
- Entry appears
- Can't display this subscription because the RSS feed could not be found.
- Can't display this subscription because the RSS feed could not be found.
Amphetadesk 0.93 on XP
- Entry appears
- won't subscribe to channel. "AmphetaDesk could not determine the format of http://www.pocketsoap.com/rssTests/rss1.0withModulesNoDefNS.xml."
- won't subscribe to channel. "AmphetaDesk could not determine the format of http://www.pocketsoap.com/rssTests/ rss1.0withModulesNoDefNSLocalNameClash.xml."
- Entry appears
- Entry appears
- Entry appears
- won't subscribe to channel. "AmphetaDesk could not determine the format of http://www.pocketsoap.com/rssTests/rss2.0NSwithModulesNoDefNS.xml."
- won't subscribe to channel. "AmphetaDesk could not determine the format of http://www.pocketsoap.com/rssTests/ rss2.0NSwithModulesNoDefNSLocalNameClash.xml."
It appears that Amphetadesk incorrectly keys of the default namespace of the root element to determine the RSS version. Update, Morbus says Amphetadesk just looks for elements in the default namespace.
Conclusions
If you're writing RSS aggregator apps that support RSS 1.0 or RSS 2.0, run, don't walk, and go read the XML Namespaces rec.
Saturday, June 1, 2002
I boiled the IIS authentication and persistent connections issue down to a simple test, and have seen this behavour on IIS 5.0 on W2K server w/SP2 and IIS 5.1 on XP Pro.
Create a simple HTML file foo.htm and drop it in the wwwroot\\inetpub directory, start IIS admin, expand the tree to so that you can see foo.htm, right click properties pick file security, click authentication methods, turn off everything except basic authentication and select a default domain. You will need an account called bang with a password of bang
Telnet to the server and send
GET /foo.htm HTTP/1.1
Host: localhost
you should get back a 401 response, this proves that IIS is configured for authentication only
HTTP/1.1 401 Access Denied
Server: Microsoft-IIS/5.1
Date: Sun, 02 Jun 2002 05:46:39 GMT
WWW-Authenticate: Basic realm="simonathome.com"
Connection: close
Content-Length: 4431
Content-Type: text/html
Now, telnet again, and send
GET /foo.htm HTTP/1.1
Host: localhost
Authorization: Basic YmFuZzpiYW5n
You should get a 200 response, with the contents of your file,
HTTP/1.1 200 OK
Server: Microsoft-IIS/5.1
Date: Sun, 02 Jun 2002 05:56:24 GMT
Content-Type: text/html
Accept-Ranges: bytes
Last-Modified: Sun, 02 Jun 2002 05:45:22 GMT
ETag: "c98679aff89c21:9ed"
Content-Length: 54
<html>
<head>
</head>
<body>
foo
</body>
</html>
the connection should still be open, now send
GET /foo.htm HTTP/1.1
Host: localhost
Rather than the expected 401 authorization error, you get a 200 again, with the file contents.
Sunday, May 19, 2002
Simon wrote: "Here's a suggestion for people writing RSS aggregators, use the HTTP/1.1 Etag and If-None-Match headers so that you only fetch the feed if its changed."
I understand the goal, but not how the implementation would work. Maybe Simon's willing to post some sample header values to shed some light on the idea... [Jake's Radio 'Blog]
Sure, the server response may contain an ETag header, you save this away ascociated with the URL, then on subsequent requests for that url, you include a If-None-Match header with the etag value. If the contents haven't changed, then the server will reply with a 304 Not Modified.
here's an initial request where we don't have a previously obtained etag
GET /weblog/rss.xml HTTP/1.1
Host: www.pocketsoap.com
And the response
HTTP/1.1 200 OK
Server: Microsoft-IIS/5.0
Date: Mon, 20 May 2002 03:08:54 GMT
Content-Type: text/xml
Accept-Ranges: bytes
Last-Modified: Mon, 20 May 2002 00:20:54 GMT
ETag: "e8d8993494ffc11:b8e"
Content-Length: 9548
<?xml version="1.0"?>
<!-- RSS generated by Radio UserLand v8.0.5 ....
Extract the ETag value, then next time you want that URL, you add the If-None-Match header,
GET /weblog/rss.xml HTTP/1.1
If-None-Match: "e8d8993494ffc11:b8e"
Host: www.pocketsoap.com
If the file hasn't changed, then it'll still have the same ETag, which matches, so there's no response, just a 304
HTTP/1.1 304 Not Modified
Server: Microsoft-IIS/5.0
Date: Mon, 20 May 2002 03:08:39 GMT
ETag: "e8d8993494ffc11:b8e"
Content-Length: 0
If however the resource has changed, the server assigns it a different Etag, so it no long matches the etag in the request, the server will send the new version
HTTP/1.1 200 OK
Server: Microsoft-IIS/5.0
Date: Mon, 20 May 2002 03:09:54 GMT
Content-Type: text/xml
Accept-Ranges: bytes
Last-Modified: Mon, 20 May 2002 03:09:51 GMT
ETag: "1238993494ffc11:b8f"
Content-Length: 9548
<?xml version="1.0"?>
<!-- RSS generated by Radio UserLand v8.0.5 ....
Wednesday, May 15, 2002
A while back I posted details of how to use PocketSOAP with Word to post new blog entries to Radio.
Here's a new version of that code that now uses PocketXML-RPC this brings a number of advantages
- Works with other tools besides Radio, the XML-RPC version of the BloggerAPI is implemented by numerous blogging tools.
- The XML-RPC version of the BloggerAPI can be enabled from the prefs page in Radio, no need to run the script that enables the SOAP version.
In additon it also handles paragraphs better, based on a suggestion from Omar Shahine [who by the way did a Mac port of the SOAP version]
First off, make sure you've got PocketXML-RPC installed, and for the Radio folks goto the prefs page and make sure that XML-RPC & SOAP are enabled, and that the Blogger API is enabled. Now you can make XML-RPC calls to manage your blog.
The code is just a few simple Word macros that use PocketXML-RPC to make the XML-RPC calls to the BloggerAPI. Download this VBA module. Now fire up Word and select Tools -> Macro -> Visual Basic Editor. Now import the module into your document, or if you want the macro's always available, import them into your template (expand the tree Normal -> Microsoft Word Objects and right click and select Import File).
Look at the top of the code, there are some settings you'll need to tweak. First you'll need to enter your username & password, these are configured in the Remote Access & Security prefs page. If you want to use Word on a different machine to the machine running Radio, you'll need to tweak the RADIO_URL setting. Finally if you need to connect via a HTTP proxy, you can alter the PROXY_SERVER and PROXY_PORT settings.
Now switch back to the main word document window, enter your post and hit Tools -> Macro -> Macros -> select PostNewBlogEntry and hit run. This will send the document as a new post to Radio. Now change the entry and run the UpdateBlogEntry macro, this will prompt you for a postID which will default to the just created post. This will now post the revised text as an edit to the original post. Hey presto you're blogging from Word!
The post takes some simple HTML formatting from the document, link, italics & bold are all carried over.
You can use the Tools -> Customize options to assign the macro's to buttons on the toolbar and/or keyboard shortcuts.
Thursday, April 11, 2002
Tomorrow marks the one year anniversary of this piece of code, which allowed you to post new blog entries to a Manila hosted blog directly from Word (using PocketSOAP of course). The lack of a spell checker in Radio, combined with my terrible spelling ability prompted me to re-visit this now that I'm in Radio land. The results, a little Word module that allows you to post & update posts from Word to a Radio blog.
Radio implements the Blogger API which is a pure XML-RPC API, however Radio supports both XML-RPC and SOAP, it's a trivial task to enable a SOAP version of the Blogger API. Fire up Radio, open a quick script window and run
user.soap.rpcHandlers.blogger = @radio.weblog.bloggerApi.rpcHandlers
In additional you'll want to goto the prefs page and make sure that XML-RPC & SOAP are enabled, and that the Blogger API is enabled. Now you can make SOAP calls to manage your blog.
The code is just a few simple Word macros that use PocketSOAP to make the SOAP calls to Radio. Make sure you've got PocketSOAP installed, then download this VBA module. Now fire up Word and select Tools -> Macro -> Visual Basic Editor. Now import the module into your document, or if you want the macro's always available, import them into your template (expand the tree Normal -> Microsoft Word Objects and right click and select Import File).
Look at the top of the code, there are some settings you'll need to tweak. First you'll need to enter your username & password, these are configured in the Remote Access & Security prefs page. If you want to use Word on a different machine to the machine running Radio, you'll need to tweak the RADIO_URL setting. Finally if you need to connect via a HTTP proxy, you can alter the PROXY_SERVER and PROXY_PORT settings.
Now switch back to the main word document window, enter your post and hit Tools -> Macro -> Macros -> select PostNewBlogEntry and hit run. This will send the document as a new post to Radio. Now change the entry and run the UpdateBlogEntry macro, this will prompt you for a postID which will default to the just created post. This will now post the revised text as an edit to the original post. Hey presto you're blogging from Word!
The post takes some simple HTML formatting from the document, link, italics & bold are all carried over.
You can use the Tools -> Customize options to assign the macro's to buttons on the toolbar and/or keyboard shortcuts.
Bing!