summaryrefslogtreecommitdiff
path: root/tests/simple-httpd.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/simple-httpd.c')
-rw-r--r--tests/simple-httpd.c319
1 files changed, 0 insertions, 319 deletions
diff --git a/tests/simple-httpd.c b/tests/simple-httpd.c
deleted file mode 100644
index 46f0988d..00000000
--- a/tests/simple-httpd.c
+++ /dev/null
@@ -1,319 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Copyright (C) 2001-2003, Ximian, Inc.
- */
-
-#include "test-utils.h"
-
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <sys/stat.h>
-
-#ifdef HAVE_MMAP
-#include <sys/mman.h>
-#endif
-
-#ifdef HAVE_MMAP
-struct mapping {
- void *start;
- size_t length;
-};
-
-static void
-free_mapping (gpointer data)
-{
- struct mapping *mapping = data;
- munmap (mapping->start, mapping->length);
- g_slice_free (struct mapping, mapping);
-}
-#endif
-
-static int
-compare_strings (gconstpointer a, gconstpointer b)
-{
- const char **sa = (const char **)a;
- const char **sb = (const char **)b;
-
- return strcmp (*sa, *sb);
-}
-
-static GString *
-get_directory_listing (const char *path)
-{
- GPtrArray *entries;
- GString *listing;
- char *escaped;
- DIR *dir;
- struct dirent *dent;
- int i;
-
- entries = g_ptr_array_new ();
- dir = opendir (path);
- if (dir) {
- while ((dent = readdir (dir))) {
- if (!strcmp (dent->d_name, ".") ||
- (!strcmp (dent->d_name, "..") &&
- !strcmp (path, "./")))
- continue;
- escaped = g_markup_escape_text (dent->d_name, -1);
- g_ptr_array_add (entries, escaped);
- }
- closedir (dir);
- }
-
- g_ptr_array_sort (entries, (GCompareFunc)compare_strings);
-
- listing = g_string_new ("<html>\r\n");
- escaped = g_markup_escape_text (strchr (path, '/'), -1);
- g_string_append_printf (listing, "<head><title>Index of %s</title></head>\r\n", escaped);
- g_string_append_printf (listing, "<body><h1>Index of %s</h1>\r\n<p>\r\n", escaped);
- g_free (escaped);
- for (i = 0; i < entries->len; i++) {
- g_string_append_printf (listing, "<a href=\"%s\">%s</a><br>\r\n",
- (char *)entries->pdata[i],
- (char *)entries->pdata[i]);
- g_free (entries->pdata[i]);
- }
- g_string_append (listing, "</body>\r\n</html>\r\n");
-
- g_ptr_array_free (entries, TRUE);
- return listing;
-}
-
-static void
-do_get (SoupServer *server, SoupMessage *msg, const char *path)
-{
- char *slash;
- struct stat st;
- int fd;
-
- if (stat (path, &st) == -1) {
- if (errno == EPERM)
- soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN);
- else if (errno == ENOENT)
- soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);
- else
- soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR);
- return;
- }
-
- if (S_ISDIR (st.st_mode)) {
- GString *listing;
- char *index_path;
-
- slash = strrchr (path, '/');
- if (!slash || slash[1]) {
- char *redir_uri;
-
- redir_uri = g_strdup_printf ("%s/", soup_message_get_uri (msg)->path);
- soup_message_set_redirect (msg, SOUP_STATUS_MOVED_PERMANENTLY,
- redir_uri);
- g_free (redir_uri);
- return;
- }
-
- index_path = g_strdup_printf ("%s/index.html", path);
- if (stat (index_path, &st) != -1) {
- do_get (server, msg, index_path);
- g_free (index_path);
- return;
- }
- g_free (index_path);
-
- listing = get_directory_listing (path);
- soup_message_set_response (msg, "text/html",
- SOUP_MEMORY_TAKE,
- listing->str, listing->len);
- g_string_free (listing, FALSE);
- return;
- }
-
- fd = open (path, O_RDONLY);
- if (fd == -1) {
- soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR);
- return;
- }
-
- if (msg->method == SOUP_METHOD_GET) {
-#ifdef HAVE_MMAP
- struct mapping *mapping = g_slice_new (struct mapping);
- SoupBuffer *buffer;
-
- mapping->start = mmap (NULL, st.st_size, PROT_READ,
- MAP_PRIVATE, fd, 0);
- mapping->length = st.st_size;
- buffer = soup_buffer_new_with_owner (mapping->start,
- mapping->length,
- mapping, free_mapping);
- soup_message_body_append_buffer (msg->response_body, buffer);
- soup_buffer_free (buffer);
-#else
- char *buf;
-
- buf = g_malloc (st.st_size);
- read (fd, buf, st.st_size);
- close (fd);
- soup_message_body_append (msg->response_body, SOUP_MEMORY_TAKE,
- buf, st.st_size);
-#endif
- } else /* msg->method == SOUP_METHOD_HEAD */ {
- char *length;
-
- /* We could just use the same code for both GET and
- * HEAD. But we'll optimize and avoid the extra
- * malloc.
- */
- length = g_strdup_printf ("%lu", (gulong)st.st_size);
- soup_message_headers_append (msg->response_headers,
- "Content-Length", length);
- g_free (length);
- }
-
- soup_message_set_status (msg, SOUP_STATUS_OK);
-}
-
-static void
-do_put (SoupServer *server, SoupMessage *msg, const char *path)
-{
- struct stat st;
- FILE *f;
- gboolean created = TRUE;
-
- if (stat (path, &st) != -1) {
- const char *match = soup_message_headers_get_one (msg->request_headers, "If-None-Match");
- if (match && !strcmp (match, "*")) {
- soup_message_set_status (msg, SOUP_STATUS_CONFLICT);
- return;
- }
-
- if (!S_ISREG (st.st_mode)) {
- soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN);
- return;
- }
-
- created = FALSE;
- }
-
- f = fopen (path, "w");
- if (!f) {
- soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR);
- return;
- }
-
- fwrite (msg->request_body->data, 1, msg->request_body->length, f);
- fclose (f);
-
- soup_message_set_status (msg, created ? SOUP_STATUS_CREATED : SOUP_STATUS_OK);
-}
-
-static void
-server_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
-{
- char *file_path;
- SoupMessageHeadersIter iter;
- const char *name, *value;
-
- g_print ("%s %s HTTP/1.%d\n", msg->method, path,
- soup_message_get_http_version (msg));
- soup_message_headers_iter_init (&iter, msg->request_headers);
- while (soup_message_headers_iter_next (&iter, &name, &value))
- g_print ("%s: %s\n", name, value);
- if (msg->request_body->length)
- g_print ("%s\n", msg->request_body->data);
-
- file_path = g_strdup_printf (".%s", path);
-
- if (msg->method == SOUP_METHOD_GET || msg->method == SOUP_METHOD_HEAD)
- do_get (server, msg, file_path);
- else if (msg->method == SOUP_METHOD_PUT)
- do_put (server, msg, file_path);
- else
- soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);
-
- g_free (file_path);
- g_print (" -> %d %s\n\n", msg->status_code, msg->reason_phrase);
-}
-
-static void
-quit (int sig)
-{
- /* Exit cleanly on ^C in case we're valgrinding. */
- exit (0);
-}
-
-int
-main (int argc, char **argv)
-{
- GMainLoop *loop;
- SoupServer *server, *ssl_server;
- int opt;
- int port = SOUP_ADDRESS_ANY_PORT;
- int ssl_port = SOUP_ADDRESS_ANY_PORT;
- const char *ssl_cert_file = NULL, *ssl_key_file = NULL;
-
- g_type_init ();
- signal (SIGINT, quit);
-
- while ((opt = getopt (argc, argv, "p:k:c:s:")) != -1) {
- switch (opt) {
- case 'p':
- port = atoi (optarg);
- break;
- case 'k':
- ssl_key_file = optarg;
- break;
- case 'c':
- ssl_cert_file = optarg;
- break;
- case 's':
- ssl_port = atoi (optarg);
- break;
- default:
- g_printerr ("Usage: %s [-p port] [-c ssl-cert-file -k ssl-key-file [-s ssl-port]]\n",
- argv[0]);
- exit (1);
- }
- }
-
- server = soup_server_new (SOUP_SERVER_PORT, port,
- SOUP_SERVER_SERVER_HEADER, "simple-httpd ",
- NULL);
- if (!server) {
- g_printerr ("Unable to bind to server port %d\n", port);
- exit (1);
- }
- soup_server_add_handler (server, NULL,
- server_callback, NULL, NULL);
- g_print ("\nStarting Server on port %d\n",
- soup_server_get_port (server));
- soup_server_run_async (server);
-
- if (ssl_cert_file && ssl_key_file) {
- ssl_server = soup_server_new (
- SOUP_SERVER_PORT, ssl_port,
- SOUP_SERVER_SSL_CERT_FILE, ssl_cert_file,
- SOUP_SERVER_SSL_KEY_FILE, ssl_key_file,
- NULL);
-
- if (!ssl_server) {
- g_printerr ("Unable to bind to SSL server port %d\n", ssl_port);
- exit (1);
- }
- soup_server_add_handler (ssl_server, NULL,
- server_callback, NULL, NULL);
- g_print ("Starting SSL Server on port %d\n",
- soup_server_get_port (ssl_server));
- soup_server_run_async (ssl_server);
- }
-
- g_print ("\nWaiting for requests...\n");
-
- loop = g_main_loop_new (NULL, TRUE);
- g_main_loop_run (loop);
-
- return 0;
-}