The R Project SVN R

Rev

Rev 51653 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 51653 Rev 51805
Line 293... Line 293...
293
	    workers[i] = NULL;
293
	    workers[i] = NULL;
294
    DBG(printf("removing worker %p\n", (void*) c));
294
    DBG(printf("removing worker %p\n", (void*) c));
295
    free(c);
295
    free(c);
296
}
296
}
297
 
297
 
-
 
298
#ifndef Win32
-
 
299
extern int R_ignore_SIGPIPE; /* defined in src/main/main.c on unix */
-
 
300
#else
-
 
301
static int R_ignore_SIGPIPE; /* for simplicity of the code below */
-
 
302
#endif
-
 
303
 
298
static int send_response(SOCKET s, const char *buf, unsigned int len)
304
static int send_response(SOCKET s, const char *buf, unsigned int len)
299
{
305
{
300
    unsigned int i = 0;
306
    unsigned int i = 0;
-
 
307
    /* we have to tell R to ignore SIGPIPE otherwise it can raise an error
-
 
308
       and get us into deep trouble */
-
 
309
    R_ignore_SIGPIPE = 1;
301
    while (i < len) {
310
    while (i < len) {
302
	int n = send(s, buf + i, len - i, 0);
311
	int n = send(s, buf + i, len - i, 0);
-
 
312
	if (n < 1) {
-
 
313
	    R_ignore_SIGPIPE = 0;
303
	if (n < 1) return -1;
314
	    return -1;
-
 
315
	}
304
	i += n;
316
	i += n;
305
    }
317
    }
-
 
318
    R_ignore_SIGPIPE = 0;
306
    return 0;
319
    return 0;
307
}
320
}
308
 
321
 
309
/* sends HTTP/x.x plus the text (which should be of the form " XXX ...") */
322
/* sends HTTP/x.x plus the text (which should be of the form " XXX ...") */
310
static int send_http_response(httpd_conn_t *c, const char *text) {
323
static int send_http_response(httpd_conn_t *c, const char *text) {
311
    char buf[96];
324
    char buf[96];
312
    const char *s = HTTP_SIG(c);
325
    const char *s = HTTP_SIG(c);
313
    int l = strlen(text);
326
    int l = strlen(text), res;
314
    /* reduce the number of packets by sending the payload en-block from buf */
327
    /* reduce the number of packets by sending the payload en-block from buf */
315
    if (l < sizeof(buf) - 10) {
328
    if (l < sizeof(buf) - 10) {
316
	strcpy(buf, s);
329
	strcpy(buf, s);
317
	strcpy(buf + 8, text);
330
	strcpy(buf + 8, text);
318
	return send_response(c->sock, buf, l + 8);
331
	return send_response(c->sock, buf, l + 8);
319
    }
332
    }
-
 
333
    R_ignore_SIGPIPE = 1;
320
    if (send(c->sock, s, 8, 0) < 8) return -1;
334
    res = send(c->sock, s, 8, 0);
-
 
335
    R_ignore_SIGPIPE = 0;
-
 
336
    if (res < 8) return -1;
321
    return send_response(c->sock, text, strlen(text));
337
    return send_response(c->sock, text, strlen(text));
322
}
338
}
323
 
339
 
324
/* decode URI in place (decoding never expands) */
340
/* decode URI in place (decoding never expands) */
325
static void uri_decode(char *s)
341
static void uri_decode(char *s)
Line 721... Line 737...
721
		/* move the body part to the beginning of the buffer */
737
		/* move the body part to the beginning of the buffer */
722
		c->line_pos -= s - c->line_buf;
738
		c->line_pos -= s - c->line_buf;
723
		memmove(c->line_buf, s, c->line_pos);
739
		memmove(c->line_buf, s, c->line_pos);
724
		if (c->method != METHOD_POST) { /* anything but POST can be processed right away */
740
		if (c->method != METHOD_POST) { /* anything but POST can be processed right away */
725
		    if (c->attr & CONTENT_LENGTH) {
741
		    if (c->attr & CONTENT_LENGTH) {
726
			send(c->sock, "HTTP/1.0 400 Bad Request (GET/HEAD with body)\r\n\r\n", 49, 0);
742
			send_http_response(c, " 400 Bad Request (GET/HEAD with body)\r\n\r\n");
727
			remove_worker(c);
743
			remove_worker(c);
728
			return;
744
			return;
729
		    }
745
		    }
730
		    process_request(c);
746
		    process_request(c);
731
		    if (c->attr & CONNECTION_CLOSE) {
747
		    if (c->attr & CONNECTION_CLOSE) {
Line 758... Line 774...
758
		if (!*s) { /* incomplete line */
774
		if (!*s) { /* incomplete line */
759
		    if (bol == c->line_buf) {
775
		    if (bol == c->line_buf) {
760
			if (c->line_pos < LINE_BUF_SIZE) /* one, incomplete line, but the buffer is not full yet, just return */
776
			if (c->line_pos < LINE_BUF_SIZE) /* one, incomplete line, but the buffer is not full yet, just return */
761
			    return;
777
			    return;
762
			/* the buffer is full yet the line is incomplete - we're in trouble */
778
			/* the buffer is full yet the line is incomplete - we're in trouble */
763
			send(c->sock, "HTTP/1.0 413 Request entity too large\r\nConnection: close\r\n\r\n", 60, 0);
779
			send_http_response(c, " 413 Request entity too large\r\nConnection: close\r\n\r\n");
764
			remove_worker(c);
780
			remove_worker(c);
765
			return;
781
			return;
766
		    }
782
		    }
767
		    /* move the line to the begining of the buffer for later requests */
783
		    /* move the line to the begining of the buffer for later requests */
768
		    c->line_pos -= bol - c->line_buf;
784
		    c->line_pos -= bol - c->line_buf;
Line 775... Line 791...
775
		    if (c->part == PART_REQUEST) {
791
		    if (c->part == PART_REQUEST) {
776
			/* --- process request line --- */
792
			/* --- process request line --- */
777
			unsigned int rll = strlen(bol); /* request line length */
793
			unsigned int rll = strlen(bol); /* request line length */
778
			char *url = bol + 5;
794
			char *url = bol + 5;
779
			if (rll < 14 || strncmp(bol + rll - 9, " HTTP/1.", 8)) { /* each request must have at least 14 characters [GET / HTTP/1.0] and have HTTP/1.x */
795
			if (rll < 14 || strncmp(bol + rll - 9, " HTTP/1.", 8)) { /* each request must have at least 14 characters [GET / HTTP/1.0] and have HTTP/1.x */
780
			    send(c->sock, "HTTP/1.0 400 Bad Request\r\n\r\n", 28, 0);
796
			    send_response(c->sock, "HTTP/1.0 400 Bad Request\r\n\r\n", 28);
781
			    remove_worker(c);
797
			    remove_worker(c);
782
			    return;
798
			    return;
783
			}
799
			}
784
			if (!strncmp(bol + rll - 3, "1.0", 3)) c->attr |= HTTP_1_0;
800
			if (!strncmp(bol + rll - 3, "1.0", 3)) c->attr |= HTTP_1_0;
785
			if (!strncmp(bol, "GET ", 4)) { c->method = METHOD_GET; url--; }
801
			if (!strncmp(bol, "GET ", 4)) { c->method = METHOD_GET; url--; }
786
			if (!strncmp(bol, "POST ", 5)) c->method = METHOD_POST;
802
			if (!strncmp(bol, "POST ", 5)) c->method = METHOD_POST;
787
			if (!strncmp(bol, "HEAD ", 5)) c->method = METHOD_HEAD;
803
			if (!strncmp(bol, "HEAD ", 5)) c->method = METHOD_HEAD;
788
			if (!c->method) {
804
			if (!c->method) {
789
			    send(c->sock, "HTTP/1.0 501 Invalid or unimplemented method\r\n\r\n", 48, 0);
805
			    send_http_response(c, " 501 Invalid or unimplemented method\r\n\r\n");
790
			    remove_worker(c);
806
			    remove_worker(c);
791
			    return;
807
			    return;
792
			}
808
			}
793
			bol[strlen(bol) - 9] = 0;
809
			bol[strlen(bol) - 9] = 0;
794
			c->url = strdup(url);
810
			c->url = strdup(url);