erickson [Thu, 6 Mar 2008 17:22:21 +0000 (17:22 +0000)]
Updated OpenSRF Javascript client library. Currently, it only implements XMLHttpRequest as
a transport layer, and, thus far, only implements the multipart/x-mixed-replace (server push)
content type, which means only Mozilla browsers are support.
Non-multipart support will be added to support all other browsers in the future -- not much
code involved there.
Most of the existing OpenSRF JS files will be deprecated after the mozilla-based jabber
handling is imported into this new lib.
Currently, all you need is opensrf.js and opensrf_xhr.js to use the lib in xmlhttprequest mode
erickson [Wed, 5 Mar 2008 22:36:59 +0000 (22:36 +0000)]
Added support for multi-router registration
replaced unnecessary <domains><domain/></domains> with a single <domain> element in opensrf_core.xml
wrapped the top-level <router> element in a <routers> container element in opensrf_core.xml to
support additional router configuration
Updated the python, C, and Perl to match the above changes
Gave the router the ability to launch more than one router process, based on the config
Added a transport_error flag to C session to indicate a communcation error, which will prevent
client sessions from hanging when making bad requests
miker [Thu, 31 Jan 2008 19:46:21 +0000 (19:46 +0000)]
Patch from Scott McKellar (including commentary):
1. I added the const qualifier to the second parameter of xmlSaxAttr().
2. I moved the prototype of _xmlToJSON() from the header to the
implementation file, and made the function static.
At least in its present form, _xmlToJSON should not be part of the
public interface because it is confusing. Sometimes it allocates a
new jsonObject, which needs to be freed, and sometimes it doesn't.
A better design would be for it to expect to receive a non-NULL pointer
to an existing jsonObject. Since it is called in only one place
(other than a couple of recursive calls), this would be an easy
change to make. However I left it alone -- as long as the function
is visible only from within its own source file, the potential for
confusion is limited.
miker [Thu, 31 Jan 2008 19:39:02 +0000 (19:39 +0000)]
Patch from Scott McKellar:
1. I replaced the deprecated identifier osrf_message with osrfMessage,
except for the typedef defining the former.
2. In the header I commented out the prototypes for
osrf_message_set_request_info() and osrf_message_to_xml(), since these
functions are nowhere defined.
3. I made sure to initialize all members of a newly allocated
osrfMessage.
4. In osrf_message_deserialize(): I changed a series of ifs into a
series of else ifs, in order to avoid needless comparisons after one
comparison finds a match.
5. Also in osrf_message_deserialize(): I introduced a temporary
variable to cache the result of some calls to jsonObjectGetString(),
in order to avoid repeating the identical calls.
miker [Thu, 31 Jan 2008 19:23:27 +0000 (19:23 +0000)]
Patch from Scott McKellar:
1. In osrfSystemBootstrap(): we build an osrfStringArray of children
to spawn, and then spawn them. However we didn't free the
osrfStringArray afterwards. Now we do.
2. In osrfSystemBootstrapClientResc(): we were potentially leaking
the osrfStringArray arr in an early return. I moved the early return
to a point before the allocation of the osrfStringArray and a number
of other things. Not only does the early return not have to free
the osrfStringArray, it also doesn't have to free the other things
any more.
miker [Thu, 31 Jan 2008 19:12:40 +0000 (19:12 +0000)]
Patch from Scott McKellar:
1. In send_request() we allocate a jsonObject o and then immediately
assign the resulting pointer to params. I eliminated the rather
pointless o and allocated params directly.
2. We didn't ever free params. Now we do.
3. I replaced two deprecated identifiers with their camel-case
equivalents:
2. In osrf_app_server_session_init() we were leaking session in the
case of an early return. I stuck in a free().
3. Likewise in osrfAppSessionMakeLocaleRequest() we were leaking req
in the case of an early return. I plugged that one too.
4. In osrfAppRequestRespondComplete() we were leaking payload in one
branch of an if/else. I moved the osrfMessageFree() beyond both
branches so that it would be unconditional.
miker [Thu, 31 Jan 2008 18:23:52 +0000 (18:23 +0000)]
Patch from Scott McKellar:
1. I renamed __osrfRouter simply to router, and made it static. We
had one global variable and one auto variable pointing to the same
object, causing some needless juggling. Now we have just one
pointer.
2. I removed the leading underscores from __setupRouter().
3. I renamed the parameter to routerSignalHandler() from "signal"
to "signo", since "signal" is a reserved identifier. I also added
some code to re-raise the signal caught.
[from a followup email]
> I chose instead to terminate the program by re-raising the signal.
> That way the parent process has a chance to detect that the program
> was terminated by a signal rather than by a normal return.
After posting this I realized that the router program runs as a
daemon, and its adopted parent process doesn't care whether it
terminates by a signal or by a normal return. So there's not
much point in re-raising the signal.
It remains true that the signal handler should contrive to
terminate the program, either by exiting or by setting a flag that
the rest of the program tests.
[ The original patch, re-raising the signal, is applied. ]
4. In main() I moved two calls to free() so that they are reachable.
5. In main() I return either EXIT_SUCCESS or EXIT_FAILURE, which are
portable. Otherwise we could find ourselves returning -1, which is
not portable.
6. In setupRouter() I arranged to free resource, and to free
tservers and tclients in the case of an early return. I also free
router in the unlikely event that osrfRouterRun returns.
7. I reworded an error message to something that I think is more
clear.
miker [Thu, 31 Jan 2008 18:18:29 +0000 (18:18 +0000)]
Patch from Scott McKellar:
1. In the header: I added compilation guards.
2. In the header: I changed leading double underscores to leading
single underscores. These identifiers don't appear elsewhere in the
code base, with either double or single underscores.
3. I moved most of the header into the implementation file. The
headers whose prototypes I moved are now static. Where there were
comments associated with the prototypes, I moved them to the function
definitions.
4. I removed an extra leading underscore from __osrfRouterFillFDSet().
5. I replaced some deprecated identifiers with their camel-case
equivalents:
erickson [Sun, 20 Jan 2008 00:00:15 +0000 (00:00 +0000)]
added the ability to wait forever by passing <0 to recv. explicitly setting sender address in messages to be correct. added ability to create a message from raw xml
erickson [Tue, 15 Jan 2008 23:24:31 +0000 (23:24 +0000)]
I started adding some basic bootstrap options looking ahead to server-side python.
This resulted in a small set of code cleanup including:
move from camelCase to lower_under for method names
move from global variables to class-level static variables
move from global functions to class-level static functions
miker [Mon, 7 Jan 2008 02:11:47 +0000 (02:11 +0000)]
Patch from Scott McKellar:
1. I moved almost everything from the header file into the
implementation file, since it isn't referenced elsewhere. All that's
left is one function prototype and a series of nested #includes.
2. I added compilation guards to the header.
3. Except for osrf_prefork_run(), all functions are now static, as is
the child_dead variable.
4. I commented out the MAX_BUFSIZE macro, since it isn't used.
5. I removed the declaration of main(), which seemed rather pointless.
6. I added the const qualifier to the parameters of osrf_prefork_run()
and osrf_prefork_routers().
7. I made sure that all members were explicitly initialized when
creating a prefork_simple or a prefork_child.
8. I commented out both the prototype and the definition of
find_prefork_child(), since we don't call it anywhere.
miker [Mon, 7 Jan 2008 02:08:10 +0000 (02:08 +0000)]
Patch from Scott McKellar:
1. I moved almost everything from the header into the implementation
file, since it isn't referenced elsewhere. All that's left is one
prototype and some nested #includes.
2. I moved the nested #includes inside the compilation guard.
3. Except for osrf_stack_transport_handler(), all functions are now
static.
4. I applied the const qualifier to the second parameter of
osrf_stack_transport_handler().
5. I plugged a memory leak in osrf_stack_transport_handler(). When
unable to open a session, we were returning without freeing the
input message.
miker [Mon, 7 Jan 2008 02:04:54 +0000 (02:04 +0000)]
JSON to XML patches from Scott McKellar:
Guard against multiple #inclusions.
Plug a potential memory leak in the jsonObjectToXML
function. If the input parameter was NULL we would fail to free
the growing_buffer we had just allocated. I rearranged it to check
for NULL before allocating the growing_buffer.
Also: I added the static qualifier to the _escape_xml function, to
match the declaration at the top of the file.
miker [Mon, 7 Jan 2008 01:57:18 +0000 (01:57 +0000)]
Memory leak plugged by Scott McKellar:
In handle_request() we allocate a growing_buffer and pass the pointer
to send_request(). However we weren't freeing the growing_buffer
after the return from send_request().
miker [Mon, 7 Jan 2008 01:55:25 +0000 (01:55 +0000)]
Two patch sets from Scott McKellar
First:
1. I moved the macros OSRF_LIST_DEFAULT_SIZE and OSRF_LIST_INC_SIZE
from the header into the implementation file. No other source files
reference them, nor should they.
2. I moved the OSRF_LIST_MAX_SIZE macro into the implementation file
as well, and then commented it out. It is nowhere referenced, but
out of caution I preserved it like a fly in amber.
3. I removed a leading underscore from each of the struct names
__osrfListStruct and __osrfListIteratorStruct.
4. I removed some obsolete comment text concerning osrfNewList().
5. I deleted the declaration for __osrfListSetSize(), which is
nowhere defined.
6. I made sure to explicitly initialize all struct members.
7. When allocating pointer arrays, I explicitly initialize all the
pointers to NULL.
8. I rewrote osrfNewList() as a thin wrapper for osrfNewListSize(),
to eliminate some duplication of code.
Second:
These patches eliminate the following identifiers, which have all been
replaced by their camel-case equivalents:
miker [Mon, 7 Jan 2008 01:46:42 +0000 (01:46 +0000)]
Patch from Scott McKellar:
1. Move several internal details from the header to the implementation
file:
The macros OSRF_HASH_LIST_SIZE and OSRF_HASH_NODE_FREE
The declaration of the osrfHashNode struct
The declarations of the osrfNewHashNode and osrfHashNodeFree
functions (which are now static)
2. Remove a leading underscore from each of the struct tags
__osrfHashStruct and __osrfHashIteratorStruct;
miker [Sat, 5 Jan 2008 19:07:02 +0000 (19:07 +0000)]
Patch from Scott McKellar:
These patches are the culmination of several postings on this subject.
The overall effect is to store numbers in jsonObjects as strings,
rather than as doubles, in order to avoid needless loss of precision
in translating back and forth between text and floating point
representations.
I shall not repeat the details outlined in previous posts, but rather
focus on what's new:
1. A new extern function jsonNewNumberStringObject constructs a
JSON_NUMBER from a character string. If the string is not numeric
according to JSON rules, the function returns NULL.
2. A new extern function jsonScrubNumber accepts a character string
and reformats it, if possible, into a numeric string that is valid
according to JSON rules. For example, it transforms " +00.42"
into "0.42". The transformed string is returned as a char* that
the caller is responsible for freeing.
jsonScrubNumber performs this transformation by manipulating text,
not by passing the value through a double. Therefore it can handle
numbers that would be too long, too large, or too small for strtod()
and its kindred to handle.
It accepts leading white space and scientific notation, but not
trailing white space, hex, or octal.
If the input string is not numeric, jsonScrubNumber returns NULL.
3. The doubleToString function now translates the incoming double
to a character string with up to 30 decimal digits of precision.
That should be enough to minimize the impact on existing code,
depending of course on how faithfully snprintf() does the formatting.
4. In osrf_json.h: I changed the signature of the next-to-last
function pointer in a jsonParserHandler, so that it accepts a
character pointer instead of a double. Likewise for the corresponding
declaration of _jsonHandleNumber in osrf_json_utils.h.
5. In osrf_json_parser.c: I construct a JSON_NUMBER from the input
character string without passing it through a double. If the input
character string is not valid according to JSON rules, I try to use
the new jsonScrubNumber() to normalize the formatting so that JSON
can accept it.
miker [Tue, 1 Jan 2008 01:56:28 +0000 (01:56 +0000)]
Patch from Scott McKellar:
1. Plugs a memory leak in file_to_string(). If we failed to open the
file, we were returning without freeing the growing_buffer that held
the file name.
2. Replaces a couple of calls to buffer_data() with calls to
buffer_release().
miker [Tue, 1 Jan 2008 01:52:44 +0000 (01:52 +0000)]
Patch from Scott McKellar:
1. Added the const qualifier in various places.
2. Eliminated some unnecessary calls to strlen(), where they were
used merely to determine whether a string was empty.
3. Ensured that all members of a new transport_message are
explicitly populated.
4. Plugged a memory leak in the case where strdup() fails.
5. Eliminated some unhelpful casts of malloc'd pointers.
6. Added some protective tests for NULL pointer parameters.
7. In several spots I replaced numeric literals with character
literals, both to make the code more readable and to avoid a needless
dependence on ASCII.
8. Rewrote the jid_get_resource function to avoid repeatedly
overwriting the same buffer.
miker [Tue, 11 Dec 2007 12:33:57 +0000 (12:33 +0000)]
Patch from Scott McKellar to correct some problems with _jsonParserError(),
which constructs and issues a message about a parsing error:
The problems arise in the course of extracting a fragment of JSON text to
provide the context of the error.
1. The code starts by picking the beginning and end of the fragment to
extract. In order to avoid beginning before the start of the string,
the original code goes through a loop, incrementing an index until it
is non-negative. A similar loop corrects for an ending beyond the
end of the string.
These loops do the job, but to my eyes they look silly. I replaced
them by assigning the corrected values directly, when corrections
are in order.
2. There is an off-by-two error in calculating the size of the buffer
needed to hold the fragment. To begin with, we miscalculate the
length of the fragment. If the fragment extends from character 30
through character 40, there are 11 characters in the fragment, not
10. Then we neglect to add another byte for a terminal nul.
The result is that the last two characters in the intended fragment
are not displayed. If the character in error is the last or the
next to last character in the string, it doesn't get displayed as
part of the fragment, leading to likely bafflement.
I corrected both these errors, embiggening the buffer by two.
3. The original code copies the fragment into the buffer by calling
snprintf(). Besides being needlessly inefficient, snprintf() is
dangerous in this context. If the copied fragment contains a
format specifier such as "%s" or "%d", sprintf goes off looking for
a non-existent parameter, resulting in a mangled message or worse.
I replaced the snprintf() with a memcpy() and a terminal nul.
miker [Mon, 10 Dec 2007 02:35:36 +0000 (02:35 +0000)]
Patch from Scott McKellar to speed up parts of the growing_buffer API; return values from buffer add/reset API brought into a consistent state for proper return value checks