The R Project SVN R

Rev

Rev 86790 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
48990 urbaneks 1
/*
2
 *  R : A Computer Language for Statistical Data Analysis
85799 kalibera 3
 *  Copyright (C) 2009-2024 The R Core Team.
48990 urbaneks 4
 *
5
 *  This program is free software; you can redistribute it and/or modify
6
 *  it under the terms of the GNU General Public License as published by
7
 *  the Free Software Foundation; either version 2 of the License, or
8
 *  (at your option) any later version.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
16
 *  along with this program; if not, a copy is available at
68949 ripley 17
 *  https://www.R-project.org/Licenses/
48990 urbaneks 18
 */
19
 
20
/* This is a small HTTP server that serves requests by evaluating
21
 * the httpd() function and passing the result to the browser. */
22
 
86514 kalibera 23
/* Note that the server runs partially on the main R thread (it has to,
24
   because it uses R), and it also sends the response mostly from the
25
   main thread. It is thus not possible to use the server from the R thread
26
   itself, e.g. via download.file(), because of a deadlock between the
27
   server and the client, when the data isn't sent in a single chunk.
28
   On Unix, the deadlock could also happen when the client is sending a
29
   request to the server (and the request isn't sent in a single chunk).
30
 
31
   This cannot happen with the intended use of this server, when it is used
32
   to serve help pages to an external client (a web browser).
33
*/
34
 
48990 urbaneks 35
/* Example:
49434 ripley 36
   httpd <- function(path,query=NULL,...) {
37
      cat("Request for:", path,"\n"); print(query);
38
      list(paste("Hello, <b>world</b>!<p>You asked for \"",path,"\".",sep=''))
39
   }
48990 urbaneks 40
   .Internal(startHTTPD("127.0.0.1",8080))
41
 */
42
 
43
/* size of the line buffer for each worker (request and header only)
44
 * requests that have longer headers will be rejected with 413 */
45
#define LINE_BUF_SIZE 1024
46
 
47
/* maximum number of active workers (parallel connections)
48
 * when exceeded the server closes new connections */
49
#define MAX_WORKERS 32
50
 
51
 
52
/* --- Rhttpd implementation --- */
53
 
54
#ifdef HAVE_CONFIG_H
55
#include <config.h>
56
#endif
57
 
58
#include <Defn.h>
59
#include <Fileio.h>
60
#include <Rconnections.h>
61
 
62
#include <stdlib.h>
63
#include <stdio.h>
64
#include <string.h>
65
 
66
#include <Rmodules/Rinternet.h>
67
 
68
#define HttpdServerActivity 8
69
#define HttpdWorkerActivity 9
70
 
84215 maechler 71
/* this is originally from sisock.h - system independent sockets */
48990 urbaneks 72
 
65805 ripley 73
#ifndef _WIN32
49434 ripley 74
# include <R_ext/eventloop.h>
75
# include <sys/types.h>
76
# ifdef HAVE_UNISTD_H
77
#  include <unistd.h>
78
# endif
68899 ripley 79
# include <netdb.h>
80
# include <sys/socket.h>
81
# include <netinet/in.h>
82
# include <arpa/inet.h>
49434 ripley 83
# include <errno.h>
48990 urbaneks 84
 
49434 ripley 85
# define sockerrno errno
86
# define SOCKET int
87
# define INVALID_SOCKET (-1)
88
# define closesocket(A) close(A)
89
# define initsocks()
90
# define donesocks()
48990 urbaneks 91
#else
49434 ripley 92
/* --- Windows-only --- */
85799 kalibera 93
# include <winsock2.h>
49434 ripley 94
# include <windows.h>
95
# include <string.h>
48990 urbaneks 96
 
49434 ripley 97
# define sockerrno WSAGetLastError()
48990 urbaneks 98
 
99
 
100
static int initsocks(void)
101
{
102
    WSADATA dt;
85799 kalibera 103
    /* initialize WinSock 2.2 */
104
    WORD wVers = MAKEWORD(2, 2);
105
    return (WSAStartup(wVers, &dt)) ? -1 : 0;
48990 urbaneks 106
}
107
 
49434 ripley 108
# define donesocks() WSACleanup()
48990 urbaneks 109
typedef int socklen_t;
110
 
65805 ripley 111
#endif /* _WIN32 */
48990 urbaneks 112
 
113
/* --- system-independent part --- */
114
 
115
#define SA struct sockaddr
116
#define SAIN struct sockaddr_in
117
 
118
static struct sockaddr *build_sin(struct sockaddr_in *sa, const char *ip, int port) {
119
    memset(sa, 0, sizeof(struct sockaddr_in));
120
    sa->sin_family = AF_INET;
121
    sa->sin_port = htons(port);
122
    sa->sin_addr.s_addr = (ip) ? inet_addr(ip) : htonl(INADDR_ANY);
123
    return (struct sockaddr*)sa;
124
}
125
 
126
/* --- END of sisock.h --- */
127
 
128
/* debug output - change the DBG(X) X to enable debugging output */
129
#define DBG(X)
130
 
131
/* --- httpd --- */
132
 
133
#define PART_REQUEST 0
134
#define PART_HEADER  1
135
#define PART_BODY    2
136
 
62724 urbaneks 137
#define METHOD_POST  1
138
#define METHOD_GET   2
139
#define METHOD_HEAD  3
140
#define METHOD_OTHER 8 /* for custom requests only */
48990 urbaneks 141
 
142
/* attributes of a connection/worker */
51562 urbaneks 143
#define CONNECTION_CLOSE  0x01 /* Connection: close response behavior is requested */
144
#define HOST_HEADER       0x02 /* headers contained Host: header (required for HTTP/1.1) */
145
#define HTTP_1_0          0x04 /* the client requested HTTP/1.0 */
146
#define CONTENT_LENGTH    0x08 /* Content-length: was specified in the headers */
147
#define THREAD_OWNED      0x10 /* the worker is owned by a thread and cannot removed */
148
#define THREAD_DISPOSE    0x20 /* the thread should dispose of the worker */
149
#define CONTENT_TYPE      0x40 /* message has a specific content type set */
150
#define CONTENT_FORM_UENC 0x80 /* message content type is application/x-www-form-urlencoded */
48990 urbaneks 151
 
54055 urbaneks 152
struct buffer {
153
    struct buffer *next, *prev;
59184 ripley 154
    size_t size, length;
54055 urbaneks 155
    char data[1];
156
};
157
 
78421 kalibera 158
/* 
159
   All processing inside R is executed on the main R thread via
160
   R_ProcessEvents (on Unix via event handlers, on Windows via a message
161
   window).
162
 
163
   We still have to protect re-entrance and not continue processing if there
164
   is a worker inside R already. If we did not then another client connection
59338 urbaneks 165
   would trigger handler and pile up eval on top of the stack, leading to
78421 kalibera 166
   exhaustion very quickly and a big mess.
167
*/
168
#ifdef _WIN32
169
static HANDLE process_request_mutex;
170
#else
59338 urbaneks 171
static int in_process;
78421 kalibera 172
#endif
59338 urbaneks 173
 
48990 urbaneks 174
/* --- connection/worker structure holding all data for an active connection --- */
175
typedef struct httpd_conn {
176
    SOCKET sock;         /* client socket */
177
    struct in_addr peer; /* IP address of the peer */
65805 ripley 178
#ifdef _WIN32
48990 urbaneks 179
    HANDLE thread;       /* worker thread */
180
#else
181
    InputHandler *ih;    /* worker input handler */
182
#endif
183
    char line_buf[LINE_BUF_SIZE];  /* line buffer (used for request and headers) */
184
    char *url, *body;              /* URL and request body */
51562 urbaneks 185
    char *content_type;            /* content type (if set) */
59184 ripley 186
    size_t line_pos, body_pos; /* positions in the buffers */
52878 urbaneks 187
    long content_length;           /* desired content length */
48990 urbaneks 188
    char part, method, attr;       /* request part, method and connection attributes */
54055 urbaneks 189
    struct buffer *headers;        /* buffer holding header lines */
48990 urbaneks 190
} httpd_conn_t;
191
 
51562 urbaneks 192
#define IS_HTTP_1_1(C) (((C)->attr & HTTP_1_0) == 0)
193
 
49887 urbaneks 194
/* returns the HTTP/x.x string for a given connection - we support 1.0 and 1.1 only */
51562 urbaneks 195
#define HTTP_SIG(C) (IS_HTTP_1_1(C) ? "HTTP/1.1" : "HTTP/1.0")
49887 urbaneks 196
 
51562 urbaneks 197
/* --- static list of currently active workers --- */
48990 urbaneks 198
static httpd_conn_t *workers[MAX_WORKERS];
199
 
200
/* --- flag determining whether one-time initialization is yet to be performed --- */
201
static int needs_init = 1;
202
 
65805 ripley 203
#ifdef _WIN32
48990 urbaneks 204
#define WM_RHTTP_CALLBACK ( WM_USER + 1 )
205
static HWND message_window;
49434 ripley 206
static LRESULT CALLBACK
207
RhttpdWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
48990 urbaneks 208
#ifndef HWND_MESSAGE
209
#define HWND_MESSAGE ((HWND)-3) /* NOTE: this is supported by W2k/XP and up only! */
210
#endif
211
#endif
212
 
82931 ripley 213
static void first_init(void)
49434 ripley 214
{
48990 urbaneks 215
    initsocks();
65805 ripley 216
#ifdef _WIN32
49434 ripley 217
    /* create a dummy message-only window for synchronization with the
218
     * main event loop */
48990 urbaneks 219
    HINSTANCE instance = GetModuleHandle(NULL);
220
    LPCTSTR class = "Rhttpd";
49434 ripley 221
    WNDCLASS wndclass = { 0, RhttpdWindowProc, 0, 0, instance, NULL, 0, 0,
222
			  NULL, class };
48990 urbaneks 223
    RegisterClass(&wndclass);
49434 ripley 224
    message_window = CreateWindow(class, "Rhttpd", 0, 1, 1, 1, 1,
225
				  HWND_MESSAGE, NULL, instance, NULL);
78421 kalibera 226
 
227
    process_request_mutex = CreateMutex(NULL, FALSE, NULL);
228
    if (!process_request_mutex) 
229
        DBG(printf("Mutex creation failed\n"));
48990 urbaneks 230
#endif
231
    needs_init = 0;
232
}
233
 
54055 urbaneks 234
/* free buffers starting from the tail(!!) */
235
static void free_buffer(struct buffer *buf) {
236
    if (!buf) return;
237
    if (buf->prev) free_buffer(buf->prev);
238
    free(buf);
239
}
240
 
241
/* allocate a new buffer */
242
static struct buffer *alloc_buffer(int size, struct buffer *parent) {
243
    struct buffer *buf = (struct buffer*) malloc(sizeof(struct buffer) + size);
244
    if (!buf) return buf;
245
    buf->next = 0;
246
    buf->prev = parent;
247
    if (parent) parent->next = buf;
248
    buf->size = size;
249
    buf->length = 0;
250
    return buf;
251
}
252
 
253
/* convert doubly-linked buffers into one big raw vector */
254
static SEXP collect_buffers(struct buffer *buf) {
255
    SEXP res;
256
    char *dst;
257
    int len = 0;
258
    if (!buf) return allocVector(RAWSXP, 0);
259
    while (buf->prev) { /* count the total length and find the root */
260
	len += buf->length;
261
	buf = buf->prev;
262
    }
263
    res = allocVector(RAWSXP, len + buf->length);
264
    dst = (char*) RAW(res);
265
    while (buf) {
87180 kalibera 266
	if (buf->length)
267
	    memcpy(dst, buf->data, buf->length);
54055 urbaneks 268
	dst += buf->length;
269
	buf = buf->next;
270
    }
271
    return res;
272
}
273
 
49434 ripley 274
static void finalize_worker(httpd_conn_t *c)
275
{
48990 urbaneks 276
    DBG(printf("finalizing worker %p\n", (void*) c));
65805 ripley 277
#ifndef _WIN32
48990 urbaneks 278
    if (c->ih) {
279
	removeInputHandler(&R_InputHandlers, c->ih);
280
	c->ih = NULL;
281
    }
282
#endif
283
    if (c->url) {
284
	free(c->url);
285
	c->url = NULL;
286
    }
49434 ripley 287
 
48990 urbaneks 288
    if (c->body) {
289
	free(c->body);
290
	c->body = NULL;
291
    }
49434 ripley 292
 
51562 urbaneks 293
    if (c->content_type) {
294
	free(c->content_type);
295
	c->content_type = NULL;
296
    }
54055 urbaneks 297
    if (c->headers) {
298
	free_buffer(c->headers);
299
	c->headers = NULL;
300
    }
48990 urbaneks 301
    if (c->sock != INVALID_SOCKET) {
302
	closesocket(c->sock);
303
	c->sock = INVALID_SOCKET;
304
    }
305
}
306
 
49434 ripley 307
/* adds a worker to the worker list and returns 0. If the list is
308
 * full, the worker is finalized and returns -1.
309
 * Note that we don't need locking, because add_worker is guaranteed
310
 * to be called by the same thread (server thread).
311
  */
48990 urbaneks 312
static int add_worker(httpd_conn_t *c) {
313
    unsigned int i = 0;
314
    for (; i < MAX_WORKERS; i++)
315
	if (!workers[i]) {
65805 ripley 316
#ifdef _WIN32
86510 kalibera 317
	    DBG(printf("registering worker %p as %d (thread=%p)\n", (void*) c, i, (void *) c->thread));
48990 urbaneks 318
#else
319
	    DBG(printf("registering worker %p as %d (handler=%p)\n", (void*) c, i, (void*) c->ih));
320
#endif
321
	    workers[i] = c;
322
	    return 0;
323
	}
49434 ripley 324
    /* FIXME: ok no more space for a new worker - what do we do now?
325
     * for now we just drop it on the floor .. */
48990 urbaneks 326
    finalize_worker(c);
327
    free(c);
328
    return -1;
329
}
330
 
49434 ripley 331
/* finalize worker, remove it from the list and free the memory. If
332
 * the worker is owned by a thread, it is not finalized and the
333
 * THREAD_DISPOSE flag is set instead. */
334
static void remove_worker(httpd_conn_t *c)
335
{
48990 urbaneks 336
    unsigned int i = 0;
337
    if (!c) return;
49434 ripley 338
    if (c->attr & THREAD_OWNED) { /* if the worker is used by a
339
				   * thread, we can only signal for
340
				   * its removal */
48990 urbaneks 341
	c->attr |= THREAD_DISPOSE;
342
	return;
343
    }
344
    finalize_worker(c);
345
    for (; i < MAX_WORKERS; i++)
346
	if (workers[i] == c)
347
	    workers[i] = NULL;
348
    DBG(printf("removing worker %p\n", (void*) c));
49434 ripley 349
    free(c);
48990 urbaneks 350
}
351
 
51805 urbaneks 352
#ifndef Win32
353
extern int R_ignore_SIGPIPE; /* defined in src/main/main.c on unix */
354
#else
355
static int R_ignore_SIGPIPE; /* for simplicity of the code below */
356
#endif
357
 
59184 ripley 358
static int send_response(SOCKET s, const char *buf, size_t len)
49434 ripley 359
{
48990 urbaneks 360
    unsigned int i = 0;
51805 urbaneks 361
    /* we have to tell R to ignore SIGPIPE otherwise it can raise an error
362
       and get us into deep trouble */
363
    R_ignore_SIGPIPE = 1;
48990 urbaneks 364
    while (i < len) {
59184 ripley 365
	ssize_t n = send(s, buf + i, len - i, 0);
51805 urbaneks 366
	if (n < 1) {
367
	    R_ignore_SIGPIPE = 0;
368
	    return -1;
369
	}
48990 urbaneks 370
	i += n;
371
    }
51805 urbaneks 372
    R_ignore_SIGPIPE = 0;
48990 urbaneks 373
    return 0;
374
}
375
 
49887 urbaneks 376
/* sends HTTP/x.x plus the text (which should be of the form " XXX ...") */
377
static int send_http_response(httpd_conn_t *c, const char *text) {
51562 urbaneks 378
    char buf[96];
49887 urbaneks 379
    const char *s = HTTP_SIG(c);
59184 ripley 380
    size_t l = strlen(text);
381
    ssize_t res;
51562 urbaneks 382
    /* reduce the number of packets by sending the payload en-block from buf */
383
    if (l < sizeof(buf) - 10) {
384
	strcpy(buf, s);
385
	strcpy(buf + 8, text);
386
	return send_response(c->sock, buf, l + 8);
387
    }
51805 urbaneks 388
    R_ignore_SIGPIPE = 1;
389
    res = send(c->sock, s, 8, 0);
390
    R_ignore_SIGPIPE = 0;
391
    if (res < 8) return -1;
49887 urbaneks 392
    return send_response(c->sock, text, strlen(text));
393
}
394
 
48990 urbaneks 395
/* decode URI in place (decoding never expands) */
49434 ripley 396
static void uri_decode(char *s)
397
{
48990 urbaneks 398
    char *t = s;
399
    while (*s) {
400
	if (*s == '+') { /* + -> SPC */
401
	    *(t++) = ' '; s++;
402
	} else if (*s == '%') {
403
	    unsigned char ec = 0;
404
	    s++;
405
	    if (*s >= '0' && *s <= '9') ec |= ((unsigned char)(*s - '0')) << 4;
406
	    else if (*s >= 'a' && *s <= 'f') ec |= ((unsigned char)(*s - 'a' + 10)) << 4;
407
	    else if (*s >= 'A' && *s <= 'F') ec |= ((unsigned char)(*s - 'A' + 10)) << 4;
408
	    if (*s) s++;
409
	    if (*s >= '0' && *s <= '9') ec |= (unsigned char)(*s - '0');
410
	    else if (*s >= 'a' && *s <= 'f') ec |= (unsigned char)(*s - 'a' + 10);
411
	    else if (*s >= 'A' && *s <= 'F') ec |= (unsigned char)(*s - 'A' + 10);
412
	    if (*s) s++;
413
	    *(t++) = (char) ec;
414
	} else *(t++) = *(s++);
415
    }
416
    *t = 0;
417
}
418
 
49434 ripley 419
/* parse a query string into a named character vector - must NOT be
420
 * URI decoded */
421
static SEXP parse_query(char *query)
422
{
48990 urbaneks 423
    int parts = 0;
424
    SEXP res, names;
425
    char *s = query, *key = 0, *value = query, *t = query;
426
    while (*s) {
427
	if (*s == '&') parts++;
428
	s++;
429
    }
430
    parts++;
431
    res = PROTECT(allocVector(STRSXP, parts));
432
    names = PROTECT(allocVector(STRSXP, parts));
433
    s = query;
434
    parts = 0;
435
    while (1) {
436
	if (*s == '=' && !key) { /* first '=' in a part */
437
	    key = value;
438
	    *(t++) = 0;
439
	    value = t;
440
	    s++;
441
	} else if (*s == '&' || !*s) { /* next part */
442
	    int last_entry = !*s;
443
	    *(t++) = 0;
444
	    if (!key) key = "";
445
	    SET_STRING_ELT(names, parts, mkChar(key));
446
	    SET_STRING_ELT(res, parts, mkChar(value));
447
	    parts++;
448
	    if (last_entry) break;
449
	    key = 0;
450
	    value = t;
451
	    s++;
452
	} else if (*s == '+') { /* + -> SPC */
453
	    *(t++) = ' '; s++;
454
	} else if (*s == '%') { /* we cannot use uri_decode becasue we need &/= *before* decoding */
455
	    unsigned char ec = 0;
456
	    s++;
457
	    if (*s >= '0' && *s <= '9') ec |= ((unsigned char)(*s - '0')) << 4;
458
	    else if (*s >= 'a' && *s <= 'f') ec |= ((unsigned char)(*s - 'a' + 10)) << 4;
459
	    else if (*s >= 'A' && *s <= 'F') ec |= ((unsigned char)(*s - 'A' + 10)) << 4;
460
	    if (*s) s++;
461
	    if (*s >= '0' && *s <= '9') ec |= (unsigned char)(*s - '0');
462
	    else if (*s >= 'a' && *s <= 'f') ec |= (unsigned char)(*s - 'a' + 10);
463
	    else if (*s >= 'A' && *s <= 'F') ec |= (unsigned char)(*s - 'A' + 10);
464
	    if (*s) s++;
465
	    *(t++) = (char) ec;
466
	} else *(t++) = *(s++);
467
    }
468
    setAttrib(res, R_NamesSymbol, names);
469
    UNPROTECT(2);
470
    return res;
471
}
472
 
54055 urbaneks 473
static SEXP R_ContentTypeName, R_HandlersName;
474
 
51562 urbaneks 475
/* create an object representing the request body. It is NULL if the body is empty (or zero length).
476
 * In the case of a URL encoded form it will have the same shape as the query string (named string vector).
477
 * In all other cases it will be a raw vector with a "content-type" attribute (if specified in the headers) */
478
static SEXP parse_request_body(httpd_conn_t *c) {
479
    if (!c || !c->body) return R_NilValue;
480
 
481
    if (c->attr & CONTENT_FORM_UENC) { /* URL encoded form - return parsed form */
482
	c->body[c->content_length] = 0; /* the body is guaranteed to have an extra byte for the termination */
483
	return parse_query(c->body);
484
    } else { /* something else - pass it as a raw vector */
485
	SEXP res = PROTECT(Rf_allocVector(RAWSXP, c->content_length));
486
	if (c->content_length)
487
	    memcpy(RAW(res), c->body, c->content_length);
54055 urbaneks 488
	if (c->content_type) { /* attach the content type so it can be interpreted */
489
	    if (!R_ContentTypeName) R_ContentTypeName = install("content-type");
490
	    setAttrib(res, R_ContentTypeName, mkString(c->content_type));
491
	}
51562 urbaneks 492
	UNPROTECT(1);
493
	return res;
494
    }
495
}
496
 
65805 ripley 497
#ifdef _WIN32
49434 ripley 498
/* on Windows we have to guarantee that process_request is performed
499
 * on the main thread, so we have to dispatch it through a message */
48990 urbaneks 500
static void process_request_main_thread(httpd_conn_t *c);
501
 
49434 ripley 502
static void process_request(httpd_conn_t *c)
503
{
78421 kalibera 504
    if (WaitForSingleObject(process_request_mutex, INFINITE) != 0) {
505
	DBG(printf("Acquiring mutex failed\n"));
506
        /* (very) unexpected error, maybe we're shutting down? */
507
        return;
508
    }
509
 
49434 ripley 510
    /* SendMessage is synchronous, so it will wait until the message
511
     * is processed */
86511 kalibera 512
    DBG(printf("enqueuing process_request_main_thread\n"));
48990 urbaneks 513
    SendMessage(message_window, WM_RHTTP_CALLBACK, 0, (LPARAM) c);
86511 kalibera 514
    DBG(printf("process_request_main_thread returned\n"));
78421 kalibera 515
 
516
    ReleaseMutex(process_request_mutex);
48990 urbaneks 517
}
49434 ripley 518
#define process_request process_request_main_thread
48990 urbaneks 519
#endif
520
 
49887 urbaneks 521
/* finalize a request - essentially for HTTP/1.0 it means that
522
 * we have to close the connection */
523
static void fin_request(httpd_conn_t *c) {
524
    if (!IS_HTTP_1_1(c))
525
	c->attr |= CONNECTION_CLOSE;
526
}
527
 
51563 urbaneks 528
static SEXP custom_handlers_env;
529
 
530
/* returns a httpd handler (closure) for a given path. As a special case
531
 * it can return a symbol that will be resolved in the "tools" namespace.
532
 * currently it allows custom handlers for paths of the form
533
 * /custom/<name>[/.*] where <name> must less than 64 characters long
534
 * and is matched against closures in tools:::.httpd.handlers.env */
535
static SEXP handler_for_path(const char *path) {
536
    if (path && !strncmp(path, "/custom/", 8)) { /* starts with /custom/ ? */
537
	const char *c = path + 8, *e = c;
538
	while (*c && *c != '/') c++; /* find out the name */
539
	if (c - e > 0 && c - e < 64) { /* if it's 1..63 chars long, proceed */
540
	    char fn[64];
541
	    memcpy(fn, e, c - e); /* create a local C string with the name for the install() call */
542
	    fn[c - e] = 0;
86511 kalibera 543
	    DBG(printf("handler_for_path('%s'): looking up custom handler '%s'\n", path, fn));
51563 urbaneks 544
	    /* we cache custom_handlers_env so in case it has not been loaded yet, fetch it */
54055 urbaneks 545
	    if (!custom_handlers_env) {
546
		if (!R_HandlersName) R_HandlersName = install(".httpd.handlers.env");
68392 luke 547
		SEXP toolsNS = PROTECT(R_FindNamespace(mkString("tools")));
548
		custom_handlers_env = eval(R_HandlersName, toolsNS);
549
		UNPROTECT(1); /* toolsNS */
54055 urbaneks 550
	    }
51563 urbaneks 551
	    /* we only proceed if .httpd.handlers.env really exists */
552
	    if (TYPEOF(custom_handlers_env) == ENVSXP) {
86790 luke 553
		SEXP cl = findVarInFrame(custom_handlers_env, install(fn));
51563 urbaneks 554
		if (cl != R_UnboundValue && TYPEOF(cl) == CLOSXP) /* we need a closure */
555
		    return cl;
556
	    }
557
	}
558
    }
86511 kalibera 559
    DBG(printf(" - falling back to default httpd\n"));
51563 urbaneks 560
    return install("httpd");
561
}
562
 
48990 urbaneks 563
/* process a request by calling the httpd() function in R */
59338 urbaneks 564
static void process_request_(void *ptr)
49434 ripley 565
{
59338 urbaneks 566
    httpd_conn_t *c = (httpd_conn_t*) ptr;
48990 urbaneks 567
    const char *ct = "text/html";
568
    char *query = 0, *s;
569
    SEXP sHeaders = R_NilValue;
570
    int code = 200;
82334 kalibera 571
    const void *vmax = NULL;
572
 
86511 kalibera 573
    DBG(printf("process request for %p\n", (void*) c));
48990 urbaneks 574
    if (!c || !c->url) return; /* if there is not enough to process, bail out */
82334 kalibera 575
    vmax = vmaxget();
48990 urbaneks 576
    s = c->url;
577
    while (*s && *s != '?') s++; /* find the query part */
578
    if (*s) {
579
	*(s++) = 0;
580
	query = s;
581
    }
582
    uri_decode(c->url); /* decode the path part */
51562 urbaneks 583
    {   /* construct "try(httpd(url, query, body), silent=TRUE)" */
48990 urbaneks 584
	SEXP sTrue = PROTECT(ScalarLogical(TRUE));
54055 urbaneks 585
	SEXP sBody = PROTECT(parse_request_body(c));
586
	SEXP sQuery = PROTECT(query ? parse_query(query) : R_NilValue);
587
	SEXP sReqHeaders = PROTECT(c->headers ? collect_buffers(c->headers) : R_NilValue);
588
	SEXP sArgs = PROTECT(list4(mkString(c->url), sQuery, sBody, sReqHeaders));
589
	SEXP sTry = install("try");
590
	SEXP y, x = PROTECT(lang3(sTry,
591
				  LCONS(handler_for_path(c->url), sArgs),
51562 urbaneks 592
				  sTrue));
48990 urbaneks 593
	SET_TAG(CDR(CDR(x)), install("silent"));
86511 kalibera 594
	DBG(printf("eval(try(httpd('%s'),silent=TRUE))\n", c->url));
54055 urbaneks 595
 
51562 urbaneks 596
	/* evaluate the above in the tools namespace */
68392 luke 597
	SEXP toolsNS = PROTECT(R_FindNamespace(mkString("tools")));
598
	x = eval(x, toolsNS);
599
	UNPROTECT(1); /* toolsNS */
600
	PROTECT(x);
48990 urbaneks 601
 
602
	/* the result is expected to have one of the following forms:
603
 
82506 kalibera 604
	  a) character vector of length 1 => error (possibly from try),
605
	     will create 500 response
49434 ripley 606
 
82506 kalibera 607
	      the string must specify charset UTF-8 and the server will
608
	      convert it to UTF-8 (must be in sync with dynamicHelp.R)
609
 
610
 
49434 ripley 611
	  b) list(payload[, content-type[, headers[, status code]]])
612
 
613
	      payload: can be a character vector of length one or a
614
	      raw vector. if the character vector is named "file" then
82506 kalibera 615
	      the content of a file of that name is the payload (the file
616
	      will be served byte-by-byte and the headers must specify
617
	      the charset of the file). if the character vector is not named
618
	      "file", it will be converted to UTF-8 (and hence the vector
619
	      itself must specify charset UTF-8, must be in sync with
620
	      dynamicHelp.R)
49434 ripley 621
 
622
	      content-type: must be a character vector of length one
623
	      or NULL (if present, else default is "text/html")
624
 
625
	      headers: must be a character vector - the elements will
626
	      have CRLF appended and neither Content-type nor
627
	      Content-length may be used
628
 
629
	     status code: must be an integer if present (default is 200)
630
	 */
631
 
48990 urbaneks 632
	if (TYPEOF(x) == STRSXP && LENGTH(x) > 0) { /* string means there was an error */
82506 kalibera 633
	    const char *s = translateCharUTF8(STRING_ELT(x, 0));
49887 urbaneks 634
	    send_http_response(c, " 500 Evaluation error\r\nConnection: close\r\nContent-type: text/plain\r\n\r\n");
86511 kalibera 635
	    DBG(printf("respond with 500 and content: %s\n", translateChar(STRING_ELT(x, 0))));
48990 urbaneks 636
	    if (c->method != METHOD_HEAD)
637
		send_response(c->sock, s, strlen(s));
638
	    c->attr |= CONNECTION_CLOSE; /* force close */
54055 urbaneks 639
	    UNPROTECT(7);
82334 kalibera 640
	    vmaxset(vmax);
48990 urbaneks 641
	    return;
642
	}
48995 urbaneks 643
 
644
	if (TYPEOF(x) == VECSXP && LENGTH(x) > 0) { /* a list (generic vector) can be a real payload */
645
	    SEXP xNames = getAttrib(x, R_NamesSymbol);
48990 urbaneks 646
	    if (LENGTH(x) > 1) {
48995 urbaneks 647
		SEXP sCT = VECTOR_ELT(x, 1); /* second element is content type if present */
48990 urbaneks 648
		if (TYPEOF(sCT) == STRSXP && LENGTH(sCT) > 0)
82506 kalibera 649
		    ct = translateCharUTF8(STRING_ELT(sCT, 0));
48995 urbaneks 650
		if (LENGTH(x) > 2) { /* third element is headers vector */
48990 urbaneks 651
		    sHeaders = VECTOR_ELT(x, 2);
652
		    if (TYPEOF(sHeaders) != STRSXP)
653
			sHeaders = R_NilValue;
48995 urbaneks 654
		    if (LENGTH(x) > 3) /* fourth element is HTTP code */
48990 urbaneks 655
			code = asInteger(VECTOR_ELT(x, 3));
656
		}
657
	    }
658
	    y = VECTOR_ELT(x, 0);
659
	    if (TYPEOF(y) == STRSXP && LENGTH(y) > 0) {
660
		char buf[64];
82506 kalibera 661
		const char *cs = translateCharUTF8(STRING_ELT(y, 0)), *fn = 0;
48990 urbaneks 662
		if (code == 200)
49887 urbaneks 663
		    send_http_response(c, " 200 OK\r\nContent-type: ");
48990 urbaneks 664
		else {
83436 ripley 665
		    snprintf(buf, 64, "%s %d Code %d\r\nContent-type: ",
666
			     HTTP_SIG(c), code, code);
48990 urbaneks 667
		    send_response(c->sock, buf, strlen(buf));
668
		}
669
		send_response(c->sock, ct, strlen(ct));
670
		if (sHeaders != R_NilValue) {
671
		    unsigned int i = 0, n = LENGTH(sHeaders);
672
		    for (; i < n; i++) {
82506 kalibera 673
			const char *hs = translateCharUTF8(STRING_ELT(sHeaders, i));
48990 urbaneks 674
			send_response(c->sock, "\r\n", 2);
675
			send_response(c->sock, hs, strlen(hs));
676
		    }
677
		}
48995 urbaneks 678
		/* special content - a file: either list(file="") or list(c("*FILE*", "")) - the latter will go away */
679
		if (TYPEOF(xNames) == STRSXP && LENGTH(xNames) > 0 &&
82334 kalibera 680
		    !strcmp(translateChar(STRING_ELT(xNames, 0)), "file"))
82506 kalibera 681
		    fn = translateChar(STRING_ELT(y, 0)); /* translateCharFP2 not exported */
48995 urbaneks 682
		if (LENGTH(y) > 1 && !strcmp(cs, "*FILE*"))
82336 kalibera 683
		    fn = translateChar(STRING_ELT(y, 1)); /* translateCharFP2 not exported */
48995 urbaneks 684
		if (fn) {
48990 urbaneks 685
		    char *fbuf;
686
		    FILE *f = fopen(fn, "rb");
687
		    long fsz = 0;
688
		    if (!f) {
689
			send_response(c->sock, "\r\nContent-length: 0\r\n\r\n", 23);
54055 urbaneks 690
			UNPROTECT(7);
49887 urbaneks 691
			fin_request(c);
82334 kalibera 692
			vmaxset(vmax);
48990 urbaneks 693
			return;
694
		    }
695
		    fseek(f, 0, SEEK_END);
696
		    fsz = ftell(f);
697
		    fseek(f, 0, SEEK_SET);
83436 ripley 698
		    snprintf(buf, 64, "\r\nContent-length: %ld\r\n\r\n", fsz);
48993 urbaneks 699
		    send_response(c->sock, buf, strlen(buf));
48990 urbaneks 700
		    if (c->method != METHOD_HEAD) {
701
			fbuf = (char*) malloc(32768);
51562 urbaneks 702
			if (fbuf) {
703
			    while (fsz > 0 && !feof(f)) {
59184 ripley 704
				size_t rd = (fsz > 32768) ? 32768 : fsz;
51562 urbaneks 705
				if (fread(fbuf, 1, rd, f) != rd) {
706
				    free(fbuf);
54055 urbaneks 707
				    UNPROTECT(7);
51562 urbaneks 708
				    c->attr |= CONNECTION_CLOSE;
69259 luke 709
				    fclose(f);
82334 kalibera 710
				    vmaxset(vmax);
51562 urbaneks 711
				    return;
712
				}
713
				send_response(c->sock, fbuf, rd);
714
				fsz -= rd;
48990 urbaneks 715
			    }
51562 urbaneks 716
			    free(fbuf);
717
			} else { /* allocation error - get out */
54055 urbaneks 718
			    UNPROTECT(7);
51562 urbaneks 719
			    c->attr |= CONNECTION_CLOSE;
69259 luke 720
			    fclose(f);
82334 kalibera 721
			    vmaxset(vmax);
51562 urbaneks 722
			    return;
48990 urbaneks 723
			}
724
		    }
725
		    fclose(f);
54055 urbaneks 726
		    UNPROTECT(7);
49887 urbaneks 727
		    fin_request(c);
82334 kalibera 728
		    vmaxset(vmax);
48990 urbaneks 729
		    return;
730
		}
83436 ripley 731
		snprintf(buf, 64, "\r\nContent-length: %u\r\n\r\n",
732
			 (unsigned int) strlen(cs));
48990 urbaneks 733
		send_response(c->sock, buf, strlen(buf));
734
		if (c->method != METHOD_HEAD)
735
		    send_response(c->sock, cs, strlen(cs));
54055 urbaneks 736
		UNPROTECT(7);
49887 urbaneks 737
		fin_request(c);
82334 kalibera 738
		vmaxset(vmax);
48990 urbaneks 739
		return;
740
	    }
741
	    if (TYPEOF(y) == RAWSXP) {
742
		char buf[64];
743
		Rbyte *cs = RAW(y);
744
		if (code == 200)
49887 urbaneks 745
		    send_http_response(c, " 200 OK\r\nContent-type: ");
48990 urbaneks 746
		else {
83436 ripley 747
		    snprintf(buf, 64, "%s %d Code %d\r\nContent-type: ",
748
			     HTTP_SIG(c), code, code);
48990 urbaneks 749
		    send_response(c->sock, buf, strlen(buf));
750
		}
751
		send_response(c->sock, ct, strlen(ct));
752
		if (sHeaders != R_NilValue) {
753
		    unsigned int i = 0, n = LENGTH(sHeaders);
754
		    for (; i < n; i++) {
82506 kalibera 755
			const char *hs = translateCharUTF8(STRING_ELT(sHeaders, i));
48990 urbaneks 756
			send_response(c->sock, "\r\n", 2);
757
			send_response(c->sock, hs, strlen(hs));
758
		    }
759
		}
83436 ripley 760
		snprintf(buf, 64, "\r\nContent-length: %u\r\n\r\n", LENGTH(y));
48990 urbaneks 761
		send_response(c->sock, buf, strlen(buf));
762
		if (c->method != METHOD_HEAD)
763
		    send_response(c->sock, (char*) cs, LENGTH(y));
54055 urbaneks 764
		UNPROTECT(7);
49887 urbaneks 765
		fin_request(c);
82334 kalibera 766
		vmaxset(vmax);
48990 urbaneks 767
		return;
768
	    }
769
	}
54055 urbaneks 770
	UNPROTECT(7);
48990 urbaneks 771
    }
49887 urbaneks 772
    send_http_response(c, " 500 Invalid response from R\r\nConnection: close\r\nContent-type: text/plain\r\n\r\nServer error: invalid response from R\r\n");
48990 urbaneks 773
    c->attr |= CONNECTION_CLOSE; /* force close */
82334 kalibera 774
    vmaxset(vmax);
48990 urbaneks 775
}
776
 
59338 urbaneks 777
/* wrap the actual call with ToplevelExec since we need to have a guaranteed
778
   return so we can track the presence of a worker code inside R to prevent
78421 kalibera 779
   re-entrance from other clients
780
 
781
   on Windows, this function is named process_request_main_thread via
782
   C preprocessor; on all platforms it is executed on the main R thread
783
*/
59338 urbaneks 784
static void process_request(httpd_conn_t *c)
785
{
78421 kalibera 786
#ifndef _WIN32
59338 urbaneks 787
    in_process = 1;
78421 kalibera 788
#endif
59338 urbaneks 789
    R_ToplevelExec(process_request_, c);
78421 kalibera 790
#ifndef _WIN32
59338 urbaneks 791
    in_process = 0;
78421 kalibera 792
#endif
59338 urbaneks 793
}
794
 
65805 ripley 795
#ifdef _WIN32
48990 urbaneks 796
#undef process_request
797
#endif
798
 
79433 kalibera 799
/* Remove . and (most) .. from "p" following RFC 3986, 5.2.4.*/
79429 kalibera 800
static char *remove_dot_segments(char *p) {
801
 
802
    char *inbuf = Rstrdup(p);
803
    char *in = inbuf;   /* first byte of input buffer */
804
 
79433 kalibera 805
    char *outbuf = malloc(strlen(inbuf) + 1);
806
    if (!outbuf)
807
	error("allocation error in remove_dot_segments");
79429 kalibera 808
    char *out = outbuf; /* last byte (terminator) of output buffer */
809
    *out = '\0';
810
 
811
    while(*in) {
812
/*
813
       A.  If the input buffer begins with a prefix of "../" or "./",
814
           then remove that prefix from the input buffer; otherwise,
815
*/
816
	if (in[0] == '.' && in[1] == '.' && in[2] == '/') {
817
	    /* remove "../" */
818
	    in += 3;
819
	    continue;
820
	}
821
	if (in[0] == '.' && in[1] == '/') {
822
	    /* remove "./" */
823
	    in += 2;
824
	    continue;
825
	}
826
/*
827
       B.  if the input buffer begins with a prefix of "/./" or "/.",
828
           where "." is a complete path segment, then replace that
829
           prefix with "/" in the input buffer; otherwise,
830
*/
831
	if (in[0] == '/' && in[1] == '.' && in[2] == '/') {
832
	    /* replace "/./" by "/"  */
833
	    in += 2;
834
	    continue;
835
	}
836
	if (in[0] == '/' && in[1] == '.' && in[2] == '\0') {
837
	    /* replace trailing "/." by "/"  */
838
	    in[1] = '\0';
839
	    continue;
840
	}
841
/*
842
       C.  if the input buffer begins with a prefix of "/../" or "/..",
843
           where ".." is a complete path segment, then replace that
844
           prefix with "/" in the input buffer and remove the last
845
           segment and its preceding "/" (if any) from the output
846
           buffer; otherwise,
847
*/
848
	if (in[0] == '/' && in[1] == '.' && in[2] == '.' && in[3] == '/') {
849
	    /* replace "/../" by "/" */
850
	    in += 3;
851
	    /* remove trailing "/segment" from output */
852
	    while(out > outbuf && *out != '/') out--;
853
	    *out = '\0';
854
	    continue;
855
	}
856
	if (in[0] == '/' && in[1] == '.' && in[2] == '.' && in[3] == '\0') {
857
	    /* replace trailing "/.." by "/" */
858
	    in[1] = '\0';
859
	    /* remove trailing "/segment" from output */
860
	    while(out > outbuf && *out != '/') out--;
861
	    *out = '\0';
862
	    continue;
863
	}
864
/*
865
       D.  if the input buffer consists only of "." or "..", then remove
866
           that from the input buffer; otherwise,
867
*/
868
	if ( (in[0] == '.' && in[1] == '\0') ||
869
	     (in[0] == '.' && in[1] == '.' && in[2] == '\0') ) {
870
	    /* remove input */
871
	    in[0] = '\0';
872
	    continue;
873
	}
874
/*
875
       E.  move the first path segment in the input buffer to the end of
876
           the output buffer, including the initial "/" character (if
877
           any) and any subsequent characters up to, but not including,
878
           the next "/" character or the end of the input buffer.
879
*/
880
	if (in[0] == '/') {
881
	    *out++ = '/';
882
	    in++;
883
	}
884
	for(; *in && *in != '/'; in++) *out++ = *in;
885
	*out = '\0';
886
    }
887
 
888
    free(inbuf);
889
    return outbuf;
890
}
891
 
49434 ripley 892
/* this function is called to fetch new data from the client
893
 * connection socket and process it */
48990 urbaneks 894
static void worker_input_handler(void *data) {
895
    httpd_conn_t *c = (httpd_conn_t*) data;
49434 ripley 896
 
48990 urbaneks 897
    DBG(printf("worker_input_handler, data=%p\n", data));
898
    if (!c) return;
49434 ripley 899
 
78421 kalibera 900
#ifndef _WIN32
59338 urbaneks 901
    if (in_process) return; /* we don't allow recursive entrance */
78421 kalibera 902
#endif
59338 urbaneks 903
 
48990 urbaneks 904
    DBG(printf("input handler for worker %p (sock=%d, part=%d, method=%d, line_pos=%d)\n", (void*) c, (int)c->sock, (int)c->part, (int)c->method, (int)c->line_pos));
49434 ripley 905
 
906
    /* FIXME: there is one edge case that is not caught on unix: if
907
     * recv reads two or more full requests into the line buffer then
908
     * this function exits after the first one, but input handlers may
909
     * not trigger, because there may be no further data. It is not
910
     * trivial to fix, because just checking for a full line at the
911
     * beginning and not calling recv won't trigger a new input
912
     * handler. However, under normal circumstance this should not
913
     * happen, because clients should wait for the response and even
914
     * if they don't it's unlikely that both requests get combined
915
     * into one packet. */
48990 urbaneks 916
    if (c->part < PART_BODY) {
917
	char *s = c->line_buf;
59184 ripley 918
	ssize_t n = recv(c->sock, c->line_buf + c->line_pos, 
919
			 LINE_BUF_SIZE - c->line_pos - 1, 0);
86510 kalibera 920
	DBG(printf("[recv n=%lld, line_pos=%llu, part=%d]\n", (long long)n,
921
	           (unsigned long long)c->line_pos, (int)c->part));
48990 urbaneks 922
	if (n < 0) { /* error, scrape this worker */
923
	    remove_worker(c);
924
	    return;
925
	}
926
	if (n == 0) { /* connection closed -> try to process and then remove */
927
	    process_request(c);
928
	    remove_worker(c);
929
	    return;
930
	}
931
	c->line_pos += n;
932
	c->line_buf[c->line_pos] = 0;
933
	DBG(printf("in buffer: {%s}\n", c->line_buf));
934
	while (*s) {
935
	    /* ok, we have genuine data in the line buffer */
936
	    if (s[0] == '\n' || (s[0] == '\r' && s[1] == '\n')) { /* single, empty line - end of headers */
937
		/* --- check request validity --- */
938
		DBG(printf(" end of request, moving to body\n"));
939
		if (!(c->attr & HTTP_1_0) && !(c->attr & HOST_HEADER)) { /* HTTP/1.1 mandates Host: header */
49887 urbaneks 940
		    send_http_response(c, " 400 Bad Request (Host: missing)\r\nConnection: close\r\n\r\n");
48990 urbaneks 941
		    remove_worker(c);
942
		    return;
943
		}
51562 urbaneks 944
		if (c->attr & CONTENT_LENGTH && c->content_length) {
52878 urbaneks 945
		    if (c->content_length < 0 ||  /* we are parsing signed so negative numbers are bad */
946
			c->content_length > 2147483640 || /* R will currently have issues with body around 2Gb or more, so better to not go there */
947
			!(c->body = (char*) malloc(c->content_length + 1 /* allocate an extra termination byte */ ))) {
51562 urbaneks 948
			send_http_response(c, " 413 Request Entity Too Large (request body too big)\r\nConnection: close\r\n\r\n");
949
			remove_worker(c);
950
			return;
951
		    }
48990 urbaneks 952
		}
953
		c->body_pos = 0;
954
		c->part = PART_BODY;
955
		if (s[0] == '\r') s++;
956
		s++;
957
		/* move the body part to the beginning of the buffer */
958
		c->line_pos -= s - c->line_buf;
959
		memmove(c->line_buf, s, c->line_pos);
62724 urbaneks 960
		/* GET/HEAD or no content length mean no body */
961
		if (c->method == METHOD_GET || c->method == METHOD_HEAD ||
962
		    !(c->attr & CONTENT_LENGTH) || c->content_length == 0) {
62770 urbaneks 963
		    if ((c->attr & CONTENT_LENGTH) && c->content_length > 0) {
51805 urbaneks 964
			send_http_response(c, " 400 Bad Request (GET/HEAD with body)\r\n\r\n");
48990 urbaneks 965
			remove_worker(c);
966
			return;
967
		    }
968
		    process_request(c);
969
		    if (c->attr & CONNECTION_CLOSE) {
970
			remove_worker(c);
971
			return;
972
		    }
973
		    /* keep-alive - reset the worker so it can process a new request */
974
		    if (c->url) { free(c->url); c->url = NULL; }
975
		    if (c->body) { free(c->body); c->body = NULL; }
51562 urbaneks 976
		    if (c->content_type) { free(c->content_type); c->content_type = NULL; }
54055 urbaneks 977
		    if (c->headers) { free_buffer(c->headers); c->headers = NULL; }
48990 urbaneks 978
		    c->body_pos = 0;
979
		    c->method = 0;
980
		    c->part = PART_REQUEST;
981
		    c->attr = 0;
982
		    c->content_length = 0;
983
		    return;
984
		}
51653 urbaneks 985
		/* copy body content (as far as available) */
986
		c->body_pos = (c->content_length < c->line_pos) ? c->content_length : c->line_pos;
987
		if (c->body_pos) {
988
		    memcpy(c->body, c->line_buf, c->body_pos);
989
		    c->line_pos -= c->body_pos; /* NOTE: we are NOT moving the buffer since non-zero left-over causes connection close */
990
		}
48990 urbaneks 991
		/* POST will continue into the BODY part */
992
		break;
993
	    }
994
	    {
995
		char *bol = s;
996
		while (*s && *s != '\r' && *s != '\n') s++;
997
		if (!*s) { /* incomplete line */
998
		    if (bol == c->line_buf) {
999
			if (c->line_pos < LINE_BUF_SIZE) /* one, incomplete line, but the buffer is not full yet, just return */
1000
			    return;
1001
			/* the buffer is full yet the line is incomplete - we're in trouble */
51805 urbaneks 1002
			send_http_response(c, " 413 Request entity too large\r\nConnection: close\r\n\r\n");
48990 urbaneks 1003
			remove_worker(c);
1004
			return;
1005
		    }
84215 maechler 1006
		    /* move the line to the beginning of the buffer for later requests */
48990 urbaneks 1007
		    c->line_pos -= bol - c->line_buf;
1008
		    memmove(c->line_buf, bol, c->line_pos);
1009
		    return;
1010
		} else { /* complete line, great! */
1011
		    if (*s == '\r') *(s++) = 0;
1012
		    if (*s == '\n') *(s++) = 0;
1013
		    DBG(printf("complete line: {%s}\n", bol));
1014
		    if (c->part == PART_REQUEST) {
1015
			/* --- process request line --- */
59184 ripley 1016
			size_t rll = strlen(bol); /* request line length */
62724 urbaneks 1017
			char *url = strchr(bol, ' ');
1018
			if (!url || 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 */
51805 urbaneks 1019
			    send_response(c->sock, "HTTP/1.0 400 Bad Request\r\n\r\n", 28);
48990 urbaneks 1020
			    remove_worker(c);
1021
			    return;
1022
			}
62724 urbaneks 1023
			url++;
79433 kalibera 1024
			bol[strlen(bol) - 9] = 0; /* cut off " HTTP/1.x" */
1025
			c->url = remove_dot_segments(url);
48990 urbaneks 1026
			if (!strncmp(bol + rll - 3, "1.0", 3)) c->attr |= HTTP_1_0;
62724 urbaneks 1027
			if (!strncmp(bol, "GET ", 4)) c->method = METHOD_GET;
48990 urbaneks 1028
			if (!strncmp(bol, "POST ", 5)) c->method = METHOD_POST;
1029
			if (!strncmp(bol, "HEAD ", 5)) c->method = METHOD_HEAD;
62724 urbaneks 1030
			/* only custom handlers can use other methods */
79433 kalibera 1031
			if (!strncmp(c->url, "/custom/", 8)) {
62724 urbaneks 1032
			    char *mend = url - 1;
1033
			    /* we generate a header with the method so it can be passed to the handler */
1034
			    if (!c->headers)
1035
				c->headers = alloc_buffer(1024, NULL);
1036
			    /* make sure it fits */
1037
			    if (c->headers->size - c->headers->length >= 18 + (mend - bol)) {
62726 urbaneks 1038
				if (!c->method) c->method = METHOD_OTHER;
62724 urbaneks 1039
				/* add "Request-Method: xxx" */
1040
				memcpy(c->headers->data + c->headers->length, "Request-Method: ", 16);
1041
				c->headers->length += 16;
87180 kalibera 1042
				if (mend - bol)
1043
				    memcpy(c->headers->data + c->headers->length, bol, mend - bol);
62724 urbaneks 1044
				c->headers->length += mend - bol;	
1045
				c->headers->data[c->headers->length++] = '\n';
1046
			    }
1047
			}
48990 urbaneks 1048
			if (!c->method) {
51805 urbaneks 1049
			    send_http_response(c, " 501 Invalid or unimplemented method\r\n\r\n");
48990 urbaneks 1050
			    remove_worker(c);
1051
			    return;
1052
			}
1053
			c->part = PART_HEADER;
1054
			DBG(printf("parsed request, method=%d, URL='%s'\n", (int)c->method, c->url));
1055
		    } else if (c->part == PART_HEADER) {
1056
			/* --- process headers --- */
1057
			char *k = bol;
54055 urbaneks 1058
			if (!c->headers)
1059
			    c->headers = alloc_buffer(1024, NULL);
1060
			if (c->headers) { /* record the header line in the buffer */
59184 ripley 1061
			    size_t l = strlen(bol);
54055 urbaneks 1062
			    if (l) { /* this should be really always true */
1063
				if (c->headers->length + l + 1 > c->headers->size) { /* not enough space? */
59184 ripley 1064
				    size_t fits = c->headers->size - c->headers->length;
54055 urbaneks 1065
				    if (fits) memcpy(c->headers->data + c->headers->length, bol, fits);
1066
				    if (alloc_buffer(2048, c->headers)) {
1067
					c->headers = c->headers->next;
87180 kalibera 1068
					if (l - fits) memcpy(c->headers->data, bol + fits, l - fits);
54055 urbaneks 1069
					c->headers->length = l - fits;
1070
					c->headers->data[c->headers->length++] = '\n';
1071
				    }
1072
				} else {
1073
				    memcpy(c->headers->data + c->headers->length, bol, l);
1074
				    c->headers->length += l;	
1075
				    c->headers->data[c->headers->length++] = '\n';
1076
				}
1077
			    }
1078
			}
48990 urbaneks 1079
			while (*k && *k != ':') {
1080
			    if (*k >= 'A' && *k <= 'Z')
1081
				*k |= 0x20;
1082
			    k++;
1083
			}
1084
			if (*k == ':') {
1085
			    *(k++) = 0;
1086
			    while (*k == ' ' || *k == '\t') k++;
1087
			    DBG(printf("header '%s' => '%s'\n", bol, k));
1088
			    if (!strcmp(bol, "content-length")) {
1089
				c->attr |= CONTENT_LENGTH;
52878 urbaneks 1090
				c->content_length = atol(k);
48990 urbaneks 1091
			    }
51562 urbaneks 1092
			    if (!strcmp(bol, "content-type")) {
1093
				char *l = k;
69420 urbaneks 1094
				/* convert content-type to lowercase to facilitate comparison
1095
				   since MIME types are case-insensitive.
1096
				   However, we have to stop at ; since parameters
1097
				   may be case-sensitive (see PR 16541) */
1098
				while (*l && *l != ';') { if (*l >= 'A' && *l <= 'Z') *l |= 0x20; l++; }
51562 urbaneks 1099
				c->attr |= CONTENT_TYPE;
1100
				if (c->content_type) free(c->content_type);
78536 ripley 1101
				c->content_type = Rstrdup(k);
51562 urbaneks 1102
				if (!strncmp(k, "application/x-www-form-urlencoded", 33))
1103
				    c->attr |= CONTENT_FORM_UENC;
1104
			    }
48990 urbaneks 1105
			    if (!strcmp(bol, "host"))
1106
				c->attr |= HOST_HEADER;
1107
			    if (!strcmp(bol, "connection")) {
1108
				char *l = k;
1109
				while (*l) { if (*l >= 'A' && *l <= 'Z') *l |= 0x20; l++; }
1110
				if (!strncmp(k, "close", 5))
54979 urbaneks 1111
				    c->attr |= CONNECTION_CLOSE;
48990 urbaneks 1112
			    }
1113
			}
1114
		    }
1115
		}
1116
	    }
1117
	}
51653 urbaneks 1118
	if (c->part < PART_BODY) {
1119
	    /* we end here if we processed a buffer of exactly one line */
1120
	    c->line_pos = 0;
48990 urbaneks 1121
	    return;
1122
	}
51653 urbaneks 1123
    }
1124
    if (c->part == PART_BODY && c->body) { /* BODY  - this branch always returns */
1125
	if (c->body_pos < c->content_length) { /* need to receive more ? */
86510 kalibera 1126
	    DBG(printf("BODY: body_pos=%llu, content_length=%ld\n",
1127
	        (unsigned long long)c->body_pos, c->content_length));
59184 ripley 1128
	    ssize_t n = recv(c->sock, c->body + c->body_pos, 
1129
			    c->content_length - c->body_pos, 0);
86510 kalibera 1130
	    DBG(printf("      [recv n=%lld - had %llu of %lu]\n", (long long)n,
1131
	        (unsigned long long)c->body_pos, c->content_length));
51653 urbaneks 1132
	    c->line_pos = 0;
1133
	    if (n < 0) { /* error, scrap this worker */
1134
		remove_worker(c);
1135
		return;
1136
	    }
1137
	    if (n == 0) { /* connection closed -> try to process and then remove */
1138
		process_request(c);
48990 urbaneks 1139
	    remove_worker(c);
51653 urbaneks 1140
		return;
1141
	    }
1142
	    c->body_pos += n;
48990 urbaneks 1143
	}
1144
	if (c->body_pos == c->content_length) { /* yay! we got the whole body */
1145
	    process_request(c);
51653 urbaneks 1146
	    if (c->attr & CONNECTION_CLOSE || c->line_pos) { /* we have to close the connection if there was a double-hit */
48990 urbaneks 1147
		remove_worker(c);
1148
		return;
1149
	    }
1150
	    /* keep-alive - reset the worker so it can process a new request */
1151
	    if (c->url) { free(c->url); c->url = NULL; }
1152
	    if (c->body) { free(c->body); c->body = NULL; }
51562 urbaneks 1153
	    if (c->content_type) { free(c->content_type); c->content_type = NULL; }
54327 urbaneks 1154
	    if (c->headers) { free_buffer(c->headers); c->headers = NULL; }
48990 urbaneks 1155
	    c->line_pos = 0; c->body_pos = 0;
1156
	    c->method = 0;
1157
	    c->part = PART_REQUEST;
1158
	    c->attr = 0;
1159
	    c->content_length = 0;
1160
	    return;
1161
	}
1162
    }
49434 ripley 1163
 
48990 urbaneks 1164
    /* we enter here only if recv was used to leave the headers with no body */
1165
    if (c->part == PART_BODY && !c->body) {
1166
	char *s = c->line_buf;
1167
	if (c->line_pos > 0) {
1168
	    if ((s[0] != '\r' || s[1] != '\n') && (s[0] != '\n')) {
49887 urbaneks 1169
		send_http_response(c, " 411 length is required for non-empty body\r\nConnection: close\r\n\r\n");
48990 urbaneks 1170
		remove_worker(c);
1171
		return;
1172
	    }
1173
	    /* empty body, good */
1174
	    process_request(c);
1175
	    if (c->attr & CONNECTION_CLOSE) {
1176
		remove_worker(c);
1177
		return;
1178
	    } else { /* keep-alive */
1179
		int sh = 1;
1180
		if (s[0] == '\r') sh++;
1181
		if (c->line_pos <= sh)
1182
		    c->line_pos = 0;
1183
		else { /* shift the remaining buffer */
1184
		    memmove(c->line_buf, c->line_buf + sh, c->line_pos - sh);
1185
		    c->line_pos -= sh;
1186
		}
1187
		/* keep-alive - reset the worker so it can process a new request */
1188
		if (c->url) { free(c->url); c->url = NULL; }
1189
		if (c->body) { free(c->body); c->body = NULL; }
51562 urbaneks 1190
		if (c->content_type) { free(c->content_type); c->content_type = NULL; }
54327 urbaneks 1191
		if (c->headers) { free_buffer(c->headers); c->headers = NULL; }
48990 urbaneks 1192
		c->body_pos = 0;
1193
		c->method = 0;
1194
		c->part = PART_REQUEST;
1195
		c->attr = 0;
1196
		c->content_length = 0;
1197
		return;
1198
	    }
1199
	}
59184 ripley 1200
	ssize_t n = recv(c->sock, c->line_buf + c->line_pos, 
1201
			 LINE_BUF_SIZE - c->line_pos - 1, 0);
51562 urbaneks 1202
	if (n < 0) { /* error, scrap this worker */
48990 urbaneks 1203
	    remove_worker(c);
1204
	    return;
1205
	}
1206
	if (n == 0) { /* connection closed -> try to process and then remove */
1207
	    process_request(c);
1208
	    remove_worker(c);
1209
	    return;
1210
	}
1211
	if ((s[0] != '\r' || s[1] != '\n') && (s[0] != '\n')) {
49887 urbaneks 1212
	    send_http_response(c, " 411 length is required for non-empty body\r\nConnection: close\r\n\r\n");
48990 urbaneks 1213
	    remove_worker(c);
1214
	    return;
49434 ripley 1215
	}
48990 urbaneks 1216
    }
1217
}
1218
 
85800 ripley 1219
static SOCKET srv_sock = INVALID_SOCKET;
1220
 
1221
#ifdef _WIN32
48990 urbaneks 1222
static void srv_input_handler(void *data);
85799 kalibera 1223
static WSAEVENT server_thread_should_stop = NULL;
48990 urbaneks 1224
 
49434 ripley 1225
/* Windows implementation uses threads to accept and serve
1226
   connections, using the main event loop to synchronize with R
1227
   through a message-only window which is created on the R thread
1228
 */
48990 urbaneks 1229
static LRESULT CALLBACK RhttpdWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1230
{
86511 kalibera 1231
    DBG(printf("RhttpdWindowProc(%p, %x, %x, %x)\n", (void *) hwnd, (int) uMsg, (int) wParam, (int) lParam));
48990 urbaneks 1232
    if (hwnd == message_window && uMsg == WM_RHTTP_CALLBACK) {
1233
	httpd_conn_t *c = (httpd_conn_t*) lParam;
1234
	process_request_main_thread(c);
1235
	return 0;
1236
    }
1237
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
1238
}
1239
 
49434 ripley 1240
/* server thread - accepts connections on the server socket and
1241
   creates worker threads
1242
 */
48990 urbaneks 1243
static DWORD WINAPI ServerThreadProc(LPVOID lpParameter) {
85799 kalibera 1244
 
1245
    WSAEVENT srv_sock_ready = WSACreateEvent();
1246
    if (!srv_sock_ready ||
1247
	WSAEventSelect(srv_sock, srv_sock_ready, FD_ACCEPT)) {
1248
 
1249
	return 1;
48990 urbaneks 1250
    }
85799 kalibera 1251
 
1252
    WSAEVENT events[] = { srv_sock_ready, server_thread_should_stop };
1253
    for(;;) {
1254
	DWORD ret = WSAWaitForMultipleEvents(2, events, FALSE, WSA_INFINITE,
1255
	                                     FALSE);
1256
	if (ret == WSA_WAIT_EVENT_0) {
1257
	    WSANETWORKEVENTS events;
1258
	    /* only re-set, we know the event is FD_ACCEPT */
1259
	    WSAEnumNetworkEvents(srv_sock, srv_sock_ready, &events);
1260
	    srv_input_handler(lpParameter);
1261
	    continue;
1262
	}
1263
	/* exit the thread when signalled to do so or on error */
1264
	break;
1265
    }
1266
 
48990 urbaneks 1267
    return 0;
1268
}
1269
 
1270
/* worker thread - processes one client connection socket */
1271
static DWORD WINAPI WorkerThreadProc(LPVOID lpParameter) {
1272
    httpd_conn_t *c = (httpd_conn_t*) lpParameter;
1273
    if (!c) return 0;
1274
    while ((c->attr & THREAD_DISPOSE) == 0) {
1275
	c->attr |= THREAD_OWNED; /* make sure the worker is not removed by the handler since we need it */
1276
	worker_input_handler(c);
1277
    }
1278
    /* the handler signalled a desire to remove the worker, do it */
1279
    c->attr = 0; /* reset the flags */
1280
    remove_worker(c); /* free the worker */
1281
    return 0;
1282
}
1283
 
1284
/* global server thread - currently we support only one server at a time */
85799 kalibera 1285
static HANDLE server_thread = NULL;
48990 urbaneks 1286
#else
49434 ripley 1287
/* on unix we register all used sockets (server and workers) as input
1288
 * handlers such that we can avoid polling */
48990 urbaneks 1289
 
1290
/* global input handler for the server socket */
1291
static InputHandler *srv_handler;
1292
#endif
1293
 
49434 ripley 1294
static void srv_input_handler(void *data)
1295
{
48990 urbaneks 1296
    httpd_conn_t *c;
1297
    SAIN peer_sa;
1298
    socklen_t peer_sal = sizeof(peer_sa);
1299
    SOCKET cl_sock = accept(srv_sock, (SA*) &peer_sa, &peer_sal);
1300
    if (cl_sock == INVALID_SOCKET) /* accept failed, don't bother */
1301
	return;
1302
    c = (httpd_conn_t*) calloc(1, sizeof(httpd_conn_t));
78455 ripley 1303
    if (c == NULL) error("allocation error in srv_input_handler");
48990 urbaneks 1304
    c->sock = cl_sock;
1305
    c->peer = peer_sa.sin_addr;
65805 ripley 1306
#ifndef _WIN32
49434 ripley 1307
    c->ih = addInputHandler(R_InputHandlers, cl_sock, &worker_input_handler,
1308
			    HttpdWorkerActivity);
48990 urbaneks 1309
    if (c->ih) c->ih->userData = c;
1310
    add_worker(c);
1311
#else
86509 kalibera 1312
    /* The accepted socket inherits properties of the socket listened to.
1313
       The server socket is non-blocking, because WSAEventSelect has been used on it.
1314
       Make sure the accepted socket is blocking. */
1315
    WSAEventSelect(c->sock, NULL, 0);
1316
    unsigned long mode = 0;
1317
    ioctlsocket(c->sock, FIONBIO, &mode);
1318
 
49434 ripley 1319
    if (!add_worker(c)) { /* create worker thread only if the worker
1320
			   * was accepted */
1321
	if (!(c->thread = CreateThread(NULL, 0, WorkerThreadProc,
1322
				       (LPVOID) c, 0, 0)))
48990 urbaneks 1323
	    remove_worker(c);
1324
    }
1325
#endif
1326
}
1327
 
85799 kalibera 1328
#ifdef _WIN32
1329
void stop_server_thread(void)
1330
{
1331
    if (!server_thread || !server_thread_should_stop)
1332
	return;
1333
    WSASetEvent(server_thread_should_stop);
1334
    WaitForSingleObject(server_thread, INFINITE);
1335
    WSACloseEvent(server_thread_should_stop);
1336
    CloseHandle(server_thread);
1337
    server_thread = NULL;
1338
    server_thread_should_stop = NULL;
1339
}
1340
#endif
1341
 
49434 ripley 1342
int in_R_HTTPDCreate(const char *ip, int port) 
1343
{
65805 ripley 1344
#ifndef _WIN32
48990 urbaneks 1345
    int reuse = 1;
49788 ripley 1346
#endif
48990 urbaneks 1347
    SAIN srv_sa;
49434 ripley 1348
 
48990 urbaneks 1349
    if (needs_init) /* initialization may need to be performed on first use */
1350
	first_init();
49434 ripley 1351
 
85799 kalibera 1352
#ifdef _WIN32
1353
    /* on Windows stop the server thread if it exists */
1354
    stop_server_thread();
1355
#endif
1356
 
48990 urbaneks 1357
    /* is already in use, close the current socket */
1358
    if (srv_sock != INVALID_SOCKET)
1359
	closesocket(srv_sock);
49434 ripley 1360
 
48990 urbaneks 1361
    /* create a new socket */
1362
    srv_sock = socket(AF_INET, SOCK_STREAM, 0);
1363
    if (srv_sock == INVALID_SOCKET)
1364
	Rf_error("unable to create socket");
49434 ripley 1365
 
65805 ripley 1366
#ifndef _WIN32
48990 urbaneks 1367
    /* set socket for reuse so we can re-init if we die */
49754 murdoch 1368
    /* But on Windows, this lets us stomp on any port already in use, so don't do it. */
49434 ripley 1369
    setsockopt(srv_sock, SOL_SOCKET, SO_REUSEADDR,
1370
	       (const char*)&reuse, sizeof(reuse));
49754 murdoch 1371
#endif
49434 ripley 1372
 
48990 urbaneks 1373
    /* bind to the desired port */
1374
    if (bind(srv_sock, build_sin(&srv_sa, ip, port), sizeof(srv_sa))) {
80477 kalibera 1375
#ifndef _WIN32
48990 urbaneks 1376
	if (sockerrno == EADDRINUSE) {
80477 kalibera 1377
#else
1378
	if (sockerrno == WSAEADDRINUSE) {
1379
#endif
48990 urbaneks 1380
	    closesocket(srv_sock);
1381
	    srv_sock = INVALID_SOCKET;
1382
	    return -2;
1383
	} else {
1384
	    closesocket(srv_sock);
1385
	    srv_sock = INVALID_SOCKET;
1386
	    Rf_error("unable to bind socket to TCP port %d", port);
1387
	}
1388
    }
49434 ripley 1389
 
48990 urbaneks 1390
    /* setup listen */
85799 kalibera 1391
    if (listen(srv_sock, 8)) {
1392
	closesocket(srv_sock);
1393
	srv_sock = INVALID_SOCKET;
48990 urbaneks 1394
	Rf_error("cannot listen to TCP port %d", port);
85799 kalibera 1395
    }
49434 ripley 1396
 
65805 ripley 1397
#ifndef _WIN32
48990 urbaneks 1398
    /* all went well, register the socket as a handler */
1399
    if (srv_handler) removeInputHandler(&R_InputHandlers, srv_handler);
49434 ripley 1400
    srv_handler = addInputHandler(R_InputHandlers, srv_sock,
1401
				  &srv_input_handler, HttpdServerActivity);
48990 urbaneks 1402
#else
1403
    /* do the desired Windows synchronization */
85799 kalibera 1404
    server_thread_should_stop = WSACreateEvent();
1405
    if (!server_thread_should_stop) {
1406
	closesocket(srv_sock);
1407
	srv_sock = INVALID_SOCKET;
1408
	Rf_error("cannot create synchronization event");
1409
    }
1410
 
48990 urbaneks 1411
    server_thread = CreateThread(NULL, 0, ServerThreadProc, 0, 0, 0);
85799 kalibera 1412
    if (!server_thread) {
1413
	closesocket(srv_sock);
1414
	srv_sock = INVALID_SOCKET;
1415
	WSACloseEvent(server_thread_should_stop);
1416
	server_thread_should_stop = NULL;
1417
	Rf_error("cannot create server thread");
1418
    }
48990 urbaneks 1419
#endif
1420
    return 0;
1421
}
1422
 
49434 ripley 1423
void in_R_HTTPDStop(void)
1424
{
65805 ripley 1425
#ifdef _WIN32
49434 ripley 1426
    /* on Windows stop the server thread if it exists */
85799 kalibera 1427
    stop_server_thread();
1428
#endif
1429
 
1430
    if (srv_sock != INVALID_SOCKET) {
1431
	closesocket(srv_sock);
1432
	srv_sock = INVALID_SOCKET;
49434 ripley 1433
    }
85799 kalibera 1434
 
1435
#ifndef _WIN32
49434 ripley 1436
    if (srv_handler) removeInputHandler(&R_InputHandlers, srv_handler);
1437
#endif
1438
}
1439
 
1440
/* Create an internal http server in R. Note that currently there can
1441
   only be at most one http server running at any given time so the
1442
   behavior is undefined if a server already exists (currently any
1443
   previous servers will be shut down by this call but the shutdown
1444
   may not be clean).
1445
 
1446
   @param sIP is the IP to bind to (or NULL for any)
1447
   @param sPort is the TCP port number to bin to
1448
   @return returns an integer value -- 0L on success, other values
1449
   denote failures: -2L means that the address/port combination is
1450
   already in use
1451
*/
1452
SEXP R_init_httpd(SEXP sIP, SEXP sPort)
1453
{
48990 urbaneks 1454
    const char *ip = 0;
82334 kalibera 1455
    const void *vmax = NULL;
1456
 
48990 urbaneks 1457
    if (sIP != R_NilValue && (TYPEOF(sIP) != STRSXP || LENGTH(sIP) != 1))
1458
	Rf_error("invalid bind address specification");
82334 kalibera 1459
    vmax = vmaxget();
48990 urbaneks 1460
    if (sIP != R_NilValue)
82334 kalibera 1461
	ip = translateChar(STRING_ELT(sIP, 0));
1462
    SEXP ans = ScalarInteger(in_R_HTTPDCreate(ip, asInteger(sPort)));
1463
    vmaxset(vmax);
1464
    return ans;
48990 urbaneks 1465
}