const char *charset = negotiationCharset;
const char *host_port = cur_host;
Z_GDU *gdu;
- char *path = 0;
+ char *path = yaz_encode_sru_dbpath_odr(out, databaseNames[0]);
- path = (char *) odr_malloc(out, 2+strlen(databaseNames[0]));
- *path = '/';
- strcpy(path+1, databaseNames[0]);
-
- printf("path=%s\n", path);
gdu = z_get_HTTP_Request_host_path(out, host_port, path);
if (!yaz_matchstr(sru_method, "get"))
YAZ_EXPORT void yaz_array_to_uri(char **path, ODR o,
char **name, char **value);
+/** \brief encodes URI component
+ \param dst destination string (should be at least 3*strlen(uri)+1)
+ \param uri URI component C-string (source)
+*/
+YAZ_EXPORT void yaz_encode_uri_component(char *dst, const char *uri);
+
+/** \brief decodes URI component
+ \param dst destination string (should be at least strlen(uri)+1)
+ \param uri URI component buffer (source)
+ \param len number of bytes to decode from uri
+*/
+YAZ_EXPORT void yaz_decode_uri_component(char *dst, const char *uri,
+ size_t len);
+
YAZ_EXPORT int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
Z_SOAP **soap_package, ODR decode, char **charset);
YAZ_EXPORT int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
YAZ_EXPORT
void yaz_mk_sru_surrogate(ODR o, Z_SRW_record *record, int pos,
int code, const char *details);
-
+
+/** \brief encode SRU database for HTTP path
+ \param out memory handle for resulting encoded database string
+ \param db source database
+ \returns encoded database path (includes leading /)
+*/
+YAZ_EXPORT
+char *yaz_encode_sru_dbpath_odr(ODR out, const char *db);
+
+/** \brief encode SRU database for HTTP path
+ \param dst destination buffer (should be at least strlen(db) +2 in size)
+ \param db source database
+
+ The resulting database (dst) includes a leading /
+*/
+YAZ_EXPORT
+void yaz_encode_sru_dbpath_buf(char *dst, const char *db);
YAZ_END_CDECL
*/
#include <stdlib.h>
+#include <assert.h>
#include <yaz/srw.h>
#include <yaz/matchstr.h>
#include <yaz/yaz-iconv.h>
+/** \brief decodes HTTP path (which should hold SRU database)
+ \param o memory for returned result
+ \param uri URI path (up to but not including ?)
+ \returns ODR allocated database
+*/
+static char *yaz_decode_sru_dbpath_odr(ODR n, const char *uri, size_t len)
+{
+ char *ret = odr_malloc(n, strlen(uri) + 1);
+ yaz_decode_uri_component(ret, uri, len);
+ return ret;
+}
+
+void yaz_encode_sru_dbpath_buf(char *dst, const char *db)
+{
+ assert(db);
+ *dst = '/';
+ yaz_encode_uri_component(dst+1, db);
+}
+
+char *yaz_encode_sru_dbpath_odr(ODR out, const char *db)
+{
+ char *dst = odr_malloc(out, 3 * strlen(db) + 2);
+ yaz_encode_sru_dbpath_buf(dst, db);
+ return dst;
+}
+
#if YAZ_HAVE_XML2
static int yaz_base64decode(const char *in, char *out)
{
if (!p1)
p1 = p0 + strlen(p0);
if (p1 != p0)
- {
- db = (char*) odr_malloc(decode, p1 - p0 + 1);
- memcpy (db, p0, p1 - p0);
- db[p1 - p0] = '\0';
- }
-
+ db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
grab_charset(decode, content_type, charset);
ret = z_soap_codec(decode, soap_package,
if (!p1)
p1 = p0 + strlen(p0);
if (p1 != p0)
- {
- db = (char*) odr_malloc(decode, p1 - p0 + 1);
- memcpy (db, p0, p1 - p0);
- db[p1 - p0] = '\0';
- }
+ db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
if (!strcmp(hreq->method, "POST"))
p1 = hreq->content_buf;
yaz_uri_to_array(p1, decode, &uri_name, &uri_val);
}
-
/*
* Local variables:
* c-basic-offset: 4
return ch - 'a'+10;
else if (ch >= 'A' && ch <= 'F')
return ch - 'A'+10;
- return 0;
+ return -1;
}
-void encode_uri_char(char *dst, char ch)
+static void encode_uri_char(char *dst, char ch)
{
if (ch == ' ')
strcpy(dst, "+");
}
}
+void yaz_encode_uri_component(char *dst, const char *uri)
+{
+ for (; *uri; uri++)
+ {
+ encode_uri_char(dst, *uri);
+ dst += strlen(dst);
+ }
+ *dst = '\0';
+}
+
+static unsigned char decode_uri_char(const char *path, size_t *len)
+{
+ unsigned char ch;
+ if (*path == '+')
+ {
+ ch = ' ';
+ *len = 1;
+ }
+ else if (*path == '%' && *len >= 3)
+ {
+ int d1 = hex_digit(path[1]);
+ int d2 = hex_digit(path[2]);
+ if (d1 >= 0 && d2 >= 0)
+ {
+ ch = d1 * 16 + d2;
+ *len = 3;
+ }
+ else
+ {
+ ch = *path;
+ *len = 1;
+ }
+ }
+ else
+ {
+ ch = *path;
+ *len = 1;
+ }
+ return ch;
+}
+
+void yaz_decode_uri_component(char *dst, const char *uri, size_t len)
+{
+ while (len)
+ {
+ size_t sz = len;
+ *dst++ = decode_uri_char(uri, &sz);
+ uri += sz;
+ len = len - sz;
+ }
+ *dst = '\0';
+}
+
void yaz_array_to_uri(char **path, ODR o, char **name, char **value)
{
size_t i, szp = 0, sz = 1;
for(i = 0; name[i]; i++)
{
- size_t j, ilen;
+ size_t ilen;
if (i)
(*path)[szp++] = '&';
ilen = strlen(name[i]);
memcpy(*path+szp, name[i], ilen);
szp += ilen;
(*path)[szp++] = '=';
- for (j = 0; value[i][j]; j++)
- {
- size_t vlen;
- char vstr[5];
- encode_uri_char(vstr, value[i][j]);
- vlen = strlen(vstr);
- memcpy(*path+szp, vstr, vlen);
- szp += vlen;
- }
+
+ yaz_encode_uri_component(*path + szp, value[i]);
+ szp += strlen(*path + szp);
}
(*path)[szp] = '\0';
}
(*val)[no] = ret = (char *) odr_malloc(o, p1 - path + 1);
while (*path && *path != '&')
{
- if (*path == '+')
- {
- ret[i++] = ' ';
- path++;
- }
- else if (*path == '%' && path[1] && path[2])
- {
- ret[i++] = hex_digit (path[1])*16 + hex_digit (path[2]);
- path = path + 3;
- }
- else
- ret[i++] = *path++;
+ size_t l = 3;
+ ret[i++] = decode_uri_char(path, &l);
+ path += l;
}
ret[i] = '\0';
ret = (char *) odr_malloc(o, p1 - path + 1);
while (*path && *path != '&')
{
- if (*path == '+')
- {
- ret[i++] = ' ';
- path++;
- }
- else if (*path == '%' && path[1] && path[2])
- {
- ret[i++] = hex_digit (path[1])*16 + hex_digit (path[2]);
- path = path + 3;
- }
- else
- ret[i++] = *path++;
+ size_t l = 3;
+ ret[i++] = decode_uri_char(path, &l);
+ path += l;
}
ret[i] = '\0';
return ret;
if (c->cs && c->cs->protocol == PROTO_HTTP)
{
#if YAZ_HAVE_XML2
- const char *path = 0;
+ const char *db = 0;
c->proto = PROTO_HTTP;
- cs_get_host_args(c->host_port, &path);
+ cs_get_host_args(c->host_port, &db);
xfree(c->path);
- c->path = (char*) xmalloc(strlen(path)+2);
- c->path[0] = '/';
- strcpy(c->path+1, path);
+
+ c->path = xmalloc(strlen(db) * 3 + 2);
+ yaz_encode_sru_dbpath_buf(c->path, db);
#else
set_ZOOM_error(c, ZOOM_ERROR_UNSUPPORTED_PROTOCOL, "SRW");
do_close(c);
char *fdatabase = 0;
if (database)
- {
- fdatabase = (char *) odr_malloc(c->odr_out, strlen(database)+2);
- strcpy(fdatabase, "/");
- strcat(fdatabase, database);
- }
+ fdatabase = yaz_encode_sru_dbpath_odr(c->odr_out, database);
gdu = z_get_HTTP_Request_host_path(c->odr_out, c->host_port,
fdatabase ? fdatabase : c->path);