Update of /cvsroot/monetdb/pathfinder/runtime
In directory sc8-pr-cvs16:/tmp/cvs-serv13658
Modified Files:
xrpc_client.mx
Log Message:
- more strict check of the HTTP response status-line
- be more flexible with the URL string of the "execute at" statement =>
remove possible whitespace characters at the beginning and/or the end
of the string.
Index: xrpc_client.mx
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/runtime/xrpc_client.mx,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -d -r1.33 -r1.34
--- xrpc_client.mx 3 May 2007 21:28:06 -0000 1.33
+++ xrpc_client.mx 15 May 2007 21:56:11 -0000 1.34
@@ -569,20 +569,34 @@
* Returns: a socket number if succeeded, -1 otherwise.
*/
static int
-setup_connection(str dst)
+setup_connection(str dst, int *port)
{
struct in_addr addr;
struct sockaddr_in sockaddr;
struct hostent *resolv = NULL;
- int i, ret, sock, port = 0;
+ int i, ret, sock = -1, p = 0;
str strptr = NULL;
-
- errno = 0;
+
+ /* remove whitespace characters at the beginning and the end of the
+ * string */
+ while(dst[0] == ' ' || dst[0] == '\t' ||
+ dst[0] == '\r' || dst[0] == '\n')
+ dst++;
+ i = strlen(dst) -1;
+ while(dst[i] == ' ' || dst[i] == '\t' ||
+ dst[i] == '\r' || dst[i] == '\n')
+ i--;
+ dst[i + 1] = '\0';
+
+ strptr = strstr(dst, "://");
+ if (strptr) strptr += 3;
+ else strptr = dst;
/* 'dst' has the form 'URL[:port]' */
- if ((strptr = strchr(dst, (int)':')) != NULL) {
+ errno = 0;
+ if ((strptr = strchr(strptr, (int)':')) != NULL) {
strptr[0] = '\0'; strptr++;
- port = strtol(strptr, (char **)NULL, 10);
+ p = strtol(strptr, (char **)NULL, 10);
if (errno) {
GDKerror("setup_connection: invalid port number: %s\n",
strerror(errno));
@@ -594,9 +608,9 @@
GDKerror("setup_connection: could not find \"mapi_port\"\n");
return -1;
}
- port = atoi(strptr) + 1;
+ p = atoi(strptr) + 1;
} else {
- port = atoi(strptr);
+ p = atoi(strptr);
}
}
@@ -617,7 +631,7 @@
}
sockaddr.sin_family = AF_INET;
- sockaddr.sin_port = htons(port);
+ sockaddr.sin_port = htons(p);
sockaddr.sin_addr.s_addr = addr.s_addr;
memset(&(sockaddr.sin_zero), '\0', 8);
@@ -630,7 +644,7 @@
for (i = NR_RETRIES; i > 0 && ret < 0; i--) {
if (ret < 0){
GDKwarning("setup_connection: could not set up connection with
%s:%d : %s\n",
- dst, port, errno?strerror(errno):".");
+ dst, p, errno?strerror(errno):".");
GDKwarning("setup_connection: %d tries left\n", i);
errno = 0;
}
@@ -640,10 +654,12 @@
if (ret < 0) {
GDKerror("setup_connection: failed to setup connection with %s:%d :
%s\n",
- dst, port, errno?strerror(errno):".");
+ dst, p, errno?strerror(errno):".");
close(sock);
return -1;
}
+
+ *port = p;
return sock;
}
@@ -739,6 +755,7 @@
GDKerror("handle_soap_fault_msg: SOAP Fault message not "
"well-formed: could not find \"<env:Value\".\n%s\n",
errmsg);
+ return;
}
strptr = strchr(strptr, '>'); assert(strptr);
strptr2 = strstr(++strptr, "</env:Value>");
@@ -776,12 +793,13 @@
*/
static BAT *
response2bat(int sock,
- char *dst,
+ char *host,
+ int port,
buffer *b,
int updCall,
lng *time_xrpcClntDeSeria)
{
- char *strptr = NULL;
+ char *strptr = NULL, respStatus[1024];
int ret;
stream *in;
BAT *shredBAT;
@@ -791,25 +809,51 @@
return NULL;
}
- b->pos = 0;
errno = 0;
- if( !(ret = stream_readline(in, b->buf, 1024)) ){
- GDKerror("response2bat: failed to receive response from %s", dst);
+ if( !(ret = stream_readline(in, respStatus, 1024)) ){
+ GDKerror("response2bat: failed to receive response from %s:%d",
+ host, port);
if(errno) GDKerror("response2bat: %s", strerror(errno));
stream_close(in); stream_destroy(in);
return NULL;
}
- if( !(strptr = strchr(b->buf, ' ')) ){
- GDKerror("response2bat: invalid response from %s:\n%s\n",
- dst, b->buf);
+ /* We only speak HTTP/1.1 */
+ if( ((strptr = strstr(respStatus, "HTTP/1.1 ")) != respStatus) ||
+ (respStatus[8] != ' ') || (respStatus[12] != ' ') ||
+ /* the '\n' is not returned by stream_readline() */
+ (respStatus[ret -1] != '\r') ) {
+ GDKerror("response2bat: invalid response from %s%d\n",
+ host, port);
+ /* read and print everything we can receive */
+ do{
+ respStatus[ret -1] = '\0'; /* overwrite '\r' */
+ GDKerror("%s\n", respStatus);
+ ret = stream_readline(in, respStatus, 1024);
+ } while (ret > 0);
+ stream_close(in); stream_destroy(in);
+ return NULL;
+ }
+ respStatus[ret -1] = '\0';
+
+ do{ /* read the HTTP header and throw it away */
+ errno = 0;
+ ret = stream_readline(in, b->buf, 1024);
+ if(ret == 1 && b->buf[0] == '\r')
+ ret = 0; /* end-of-HTTP-header found */
+ } while (ret > 0);
+ if (ret < 0) {
+ GDKerror("response2bat: failed to receive response from %s:%d",
+ host, port);
+ if(errno) GDKerror("response2bat: %s", strerror(errno));
stream_close(in); stream_destroy(in);
return NULL;
}
+ /* Now, we can check the response status */
+ strptr = strchr(respStatus, ' '); assert(strptr);
if (strncmp(++strptr, "200", 3) != 0) {
- b->buf[ret] = '\0';
- GDKerror("HTTP Error Code : %s\n", b->buf + 9);
+ GDKerror("HTTP Error Code : %s\n", strptr);
b->pos = 0;
do{ /* read the SOAP Fault message */
@@ -818,8 +862,8 @@
if (ret > 0) b->pos += ret;
} while (ret > 0);
if (ret < 0) {
- GDKerror("response2bat: failed to receive response from %s",
- dst);
+ GDKerror("response2bat: failed to receive response from %s:%d",
+ host, port);
if(errno) GDKerror("response2bat: %s", strerror(errno));
return NULL;
}
@@ -829,21 +873,6 @@
return NULL;
}
- do{ /* read the HTTP header and throw it away */
- errno = 0;
- ret = stream_readline(in, b->buf, 1024);
- b->buf[ret] = '\0';
- if(ret == 1 && b->buf[0] == '\r')
- ret = 0; /* end-of-HTTP-header found */
- } while (ret > 0);
- if (ret < 0) {
- GDKerror("response2bat: failed to receive response from %s",
- dst);
- if(errno) GDKerror("response2bat: %s", strerror(errno));
- stream_close(in); stream_destroy(in);
- return NULL;
- }
-
/* Start timing Client DeSerialisation */
*time_xrpcClntDeSeria = GDKusec();
if (!(shredBAT = BATnew(TYPE_str, TYPE_bat, 32))){
@@ -892,7 +921,7 @@
BAT *fun_item, BAT *fun_kind, BAT *int_values, BAT *dbl_values,
BAT *dec_values, BAT *str_values)
{
- int sock = -1;
+ int sock = -1, port = -1;
buffer *b = NULL;
str str_val = NULL;
stream *out = NULL, *bs = NULL;
@@ -915,14 +944,11 @@
lng time_xrpcClntSeria = 0, time_xrpcClntDeSeria = 0;
lng time_xrpcClnt2Serv = 0;
size_t bytes_sent = 0;
- char *protocol = strstr(dst, "://");
- if (protocol) dst = protocol+3;
errCheck(iterc, argc, ws, fun_vid, fun_iter, fun_item, fun_kind,
int_values, dbl_values, dec_values, str_values);
-
- if ((sock = setup_connection(dst)) < 0) {
+ if ((sock = setup_connection(dst, &port)) < 0) {
return GDK_FAIL;
}
if (!(out = socket_wastream(sock, "http_send"))) {
@@ -1209,13 +1235,13 @@
time_xrpcClnt2Serv = GDKusec();
bytes_sent = stream_printf(out,
"POST %s HTTP/1.1\r\n"
- "Host: %s\r\n"
+ "Host: %s:%d\r\n"
"Accept: text/html, text/xml, application/soap+xml\r\n"
"Accept-Language: en-uk en-us\r\n"
"Content-Type: text/html; charset=\"utf-8\"\r\n"
"Content-Length: " SZFMT "\r\n\r\n"
"%s",
- XRPC_REQ_CALLBACK, dst, b->pos, b->buf);
+ XRPC_REQ_CALLBACK, dst, port, b->pos, b->buf);
if (bytes_sent < b->pos) {
GDKerror("CMDhttp_post: failed to send XRPC request.");
clean_up(sock, out, bs, b, argcnt, iterc);
@@ -1224,7 +1250,8 @@
/* Stop timing Network Send Client2Server */
time_xrpcClnt2Serv= GDKusec() - time_xrpcClnt2Serv;
- shredBAT = response2bat(sock, dst, b, *updCall, &time_xrpcClntDeSeria);
+ shredBAT = response2bat(sock, dst, port, b, *updCall,
+ &time_xrpcClntDeSeria);
if(!shredBAT) {
clean_up(sock, out, bs, b, argcnt, iterc);
return GDK_FAIL;
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Monetdb-pf-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/monetdb-pf-checkins