Exemple #1
0
int check_client_header(FILE *file) {
  char buffer[1024];
  http_request request;

  fgets_or_exit(buffer, 1024, file);

  if (parse_http_request(buffer, &request) == 1) {
    char *url = rewrite_url(request.url);
    if (request.method != HTTP_GET) {
      skip_headers(file);
      send_response(file, 400, "Bad request", "Bad request\r\n");
      free(url);
      return 400;
    } else if (strcmp(url, "/")) {
      skip_headers(file);
      send_response(file, 404, "Not Found", "Not Found\r\n");
      free(url);
      return 404;
    } else {
      skip_headers(file);
      free(url);
      return 200;
    }
  } else {
    skip_headers(file);
    send_response(file, 400, "Bad Request", "Bad request\r\n");
    return 400;
  }
}
Exemple #2
0
int parse_http_request ( const char * request_line , http_request * request ){
	int i=0;
	int nbmot=1;
	int troisieme_mot=0;
	int deuxieme_mot=0;
	while(request_line[i]!='\0' && i!=2048){
		if(request_line[i]==' '){
			nbmot++;
			if(deuxieme_mot==0){
				deuxieme_mot=i+1;
			}
			troisieme_mot=i+1;

		}
		i++;
	}

	if(nbmot!=3){
		return 0;
	}
	char * url = malloc(troisieme_mot-deuxieme_mot-1);
	char * buf =url;
	while(deuxieme_mot<troisieme_mot-1){
		*buf=request_line[deuxieme_mot];
		buf++;
		deuxieme_mot++;
	}
	request->url=rewrite_url(url);

	if(!(request_line[0]=='G' && request_line[1]=='E' && request_line[2]=='T')){
		return 0;
	}else{
		request->method=HTTP_GET;
	}
	if(!(request_line[troisieme_mot]=='H' && request_line[troisieme_mot+1]=='T' && request_line[troisieme_mot+2]=='T' && request_line[troisieme_mot+3]=='P' && request_line[troisieme_mot+4]=='/')){
		return 0;
	}if(!(request_line[troisieme_mot+5]=='1')){
		return 0;
	}if(!(request_line[troisieme_mot+6]=='.')){
		return 0;
	}if(!(request_line[troisieme_mot+7]>='0' && request_line[troisieme_mot+7]<='1')){
		return 0;
	}

	return 1;
}
Exemple #3
0
/*
 * read_requesthdrs - read and parse HTTP request headers
 */
int read_http_header(const char* line, http_request *r)
{
    int length = strlen(line);
    int pos, last = length, current_state = s_start;
    char ch = 'a';
    char s[length];

    memset(s, 0, length);

    for (pos = 0; pos < last; ++pos) {
        ch = line[pos];

        switch (current_state) {

        case s_start:
            if (words(line) != 3) {
                r->m = HTTP_INVALID;
                current_state = s_header_done;
                return EXIT_FAILURE;
            }

            if (ch == LF || ch == CR)
                break;

            if ((ch < 'A' || ch > 'Z') && ch != '_') {
                r->m = HTTP_INVALID;
                current_state = s_header_done;
                return EXIT_FAILURE;
            }

            current_state = s_method;
            break;

        case s_method:
            if (ch == ' ') {
                switch (pos) {
                case 3:
                    if (strncmp(line, "GET", 3) == 0) {
                        r->m = HTTP_GET;
                        current_state = s_uri;
                        break;
                    }

                    if (strncmp(line, "PUT", 3) == 0) {
                        current_state = s_uri;
                        r->m = HTTP_PUT;
                        break;
                    }

                    break;
                case 4:
                    if (strncmp(line, "HEAD", 4) == 0) {
                        current_state = s_uri;
                        r->m = HTTP_HEAD;
                        break;
                    }

                    if (strncmp(line, "POST", 4) == 0) {
                        current_state = s_uri;
                        r->m = HTTP_POST;
                        break;
                    }
                    break;
                case 5:
                    if (strncmp(line, "TRACE", 5) == 0) {
                        current_state = s_uri;
                        r->m = HTTP_TRACE;
                        break;
                    }

                    break;
                case 6:
                    if (strncmp(line, "DELETE", 6) == 0) {
                        current_state = s_uri;
                        r->m = HTTP_DELETE;
                        break;
                    }

                    break;
                case 7:
                    if (strncmp(line, "CONNECT", 7) == 0) {
                        r->m = HTTP_CONNECT;
                        break;
                    }

                    if (strncmp(line, "OPTIONS", 7) == 0) {
                        r->m = HTTP_OPTIONS;
                        break;
                    }

                    break;
                }

                if (current_state != s_uri) {
                    r->m = HTTP_INVALID;
                    current_state = s_header_done;
                    return EXIT_FAILURE;
                }
            }

            break;

        case s_uri:
            if (ch == ' ') {
                strcpy(r->uri, rewrite_url(s));
                current_state = s_http_correct;
                break;
            } else {
                append(s, length, ch);
            }

            break;

        case s_http_correct:
            switch (ch) {
            case ' ':
                break;
            case CR:
                current_state = s_header_done;
                break;
            case LF:
                current_state = s_header_done;
                break;
            case 'H':
                current_state = s_http_H;
                break;
            default:
                current_state = s_header_done;
                return EXIT_FAILURE;
            }

            break;

        case s_http_H:
            switch (ch) {
            case 'T':
                current_state = s_http_HT;
                break;
            default:
                r->m = HTTP_INVALID;
                current_state = s_header_done;
                return EXIT_FAILURE;
            }

            break;

        case s_http_HT:
            switch (ch) {
            case 'T':
                current_state = s_http_HTT;
                break;
            default:
                r->m = HTTP_INVALID;
                current_state = s_header_done;
                return EXIT_FAILURE;
            }

            break;

        case s_http_HTT:
            switch (ch) {
            case 'P':
                current_state = s_http_HTTP;
                break;
            default:
                r->m = HTTP_INVALID;
                current_state = s_header_done;
                return EXIT_FAILURE;
            }

            break;

        case s_http_HTTP:
            switch (ch) {
            case '/':
                current_state = s_http_first_major_version;
                break;
            default:
                r->m = HTTP_INVALID;
                current_state = s_header_done;
                return EXIT_FAILURE;
            }

            break;

        case s_http_first_major_version:
            if (ch < '1' || ch > '9') {
                r->m = HTTP_INVALID;
                current_state = s_header_done;
                return EXIT_FAILURE;
            }

            r->major_version = strtol(&ch, NULL, 1);
            current_state = s_http_major_version;

            break;

        case s_http_major_version:
            if (ch == '.') {
                current_state = s_http_first_minor_version;
                break;
            }

            if (ch < '0' || ch > '9') {
                r->m = HTTP_INVALID;
                current_state = s_header_done;
                return EXIT_FAILURE;
            }

            r->major_version = r->major_version * 10 + strtol(&ch, NULL, 1);
            break;

        case s_http_first_minor_version:
            if (ch < '0' || ch > '9') {
                r->m = HTTP_INVALID;
                current_state = s_header_done;
                return EXIT_FAILURE;
            }

            r->minor_version = strtol(&ch, NULL, 1);
            current_state = s_http_minor_version;
            break;

        case s_http_minor_version:
            if (ch == CR) {
                current_state = s_header_done;
                break;
            }

            if (ch == LF) {
                current_state = s_header_done;
                break;
            }
        }

    }

    return EXIT_SUCCESS;
}
Exemple #4
0
int main(int argc, char **argv)
{
    char **singleusercmd = NULL;
    char *testurl = NULL;
    char *dropprivuser = NULL;
#ifndef NO_X11
    char *display = NULL; 
#endif
    int doing_opts = 1;
    int port = 880;
    int multiuser = 0;

    /*
     * Parse the arguments.
     */
    while (--argc > 0) {
        char *p = *++argv;
        if (*p == '-' && doing_opts) {
            if (!strcmp(p, "--multiuser")) {
		multiuser = 1;
#ifndef NO_X11
	    } else if (!strcmp(p, "--display") || !strcmp(p, "-display")) {
                if (--argc <= 0) {
                    fprintf(stderr, "ick-proxy: %s expected a parameter\n", p);
                    return 1;
                }
                display = *++argv;
#endif
            } else if (!strcmp(p, "-p")) {
                if (--argc <= 0) {
                    fprintf(stderr, "ick-proxy: -p expected a parameter\n");
                    return 1;
                }
                port = atoi(*++argv);
            } else if (!strcmp(p, "-s")) {
                if (--argc <= 0) {
                    fprintf(stderr, "ick-proxy: -s expected a parameter\n");
                    return 1;
                }
		override_script = *++argv;
            } else if (!strcmp(p, "-i")) {
                if (--argc <= 0) {
                    fprintf(stderr, "ick-proxy: -i expected a parameter\n");
                    return 1;
                }
		override_inpac = *++argv;
            } else if (!strcmp(p, "-o")) {
                if (--argc <= 0) {
                    fprintf(stderr, "ick-proxy: -o expected a parameter\n");
                    return 1;
                }
		override_outpac = *++argv;
            } else if (!strcmp(p, "-t")) {
                if (--argc <= 0) {
                    fprintf(stderr, "ick-proxy: -t expected a parameter\n");
                    return 1;
                }
		testurl = *++argv;
            } else if (!strcmp(p, "-u")) {
                if (--argc <= 0) {
                    fprintf(stderr, "ick-proxy: -u expected a parameter\n");
                    return 1;
                }
		dropprivuser = *++argv;
            } else if (!strcmp(p, "--help") || !strcmp(p, "-help") ||
                       !strcmp(p, "-?") || !strcmp(p, "-h")) {
                /* Valid help request. */
                usage();
                return 0;
            } else if (!strcmp(p, "--licence") || !strcmp(p, "--license")) {
                licence();
                return 0;
            } else if (!strcmp(p, "--version")) {
                version();
                return 0;
            } else if (!strcmp(p, "--")) {
                doing_opts = 0;
            } else {
                /* Invalid option; give help as well as whining. */
                fprintf(stderr, "ick-proxy: unrecognised option '%s'\n", p);
                usage();
                return 1;
            }
        } else {
            singleusercmd = argv;
            break;
        }
    }

    /*
     * Handle command-line URL-test mode.
     */
    if (testurl) {
	char *err, *ret;

	ick_proxy_setup();

	ret = rewrite_url(&err, "", testurl);
	if (!ret) {
	    fprintf(stderr, "ick-proxy: rewrite error: %s\n", err);
	    sfree(err);
	    return 1;
	} else {
	    puts(ret);
	    sfree(ret);
	    return 0;
	}
    }

    /*
     * Otherwise, hand off to uxmain.
     */
    if (!multiuser && !singleusercmd) {
#ifdef NO_X11
	fprintf(stderr, "ick-proxy: expected a command in single-user"
		" mode\n");
	return 1;
#else
	/*
	 * Open the X display.
	 */
	disp = XOpenDisplay(display);
	if (!disp) {
	    fprintf(stderr, "ick-proxy: unable to open X display\n");
	    return 1;
	}

	/*
	 * When working with an X display, we daemonise, if only
	 * to avoid zombie processes if we're started from a
	 * .xsession that isn't wait()ing for us.
	 */
	return uxmain(0, -1, NULL, NULL, ConnectionNumber(disp), xreadfd, 1);
#endif
    }

    /*
     * The `daemon' flag is set iff we are multi-user.
     */
    return uxmain(multiuser, port, dropprivuser, singleusercmd,
		  -1, NULL, multiuser);
}
Exemple #5
0
static int proxy_balancer_pre_request(proxy_worker **worker,
                                      proxy_balancer **balancer,
                                      request_rec *r,
                                      proxy_server_conf *conf, char **url)
{
    int access_status;
    proxy_worker *runtime;
    char *route = NULL;
    char *sticky = NULL;
    apr_status_t rv;

    *worker = NULL;
    /* Step 1: check if the url is for us
     * The url we can handle starts with 'balancer://'
     * If balancer is already provided skip the search
     * for balancer, because this is failover attempt.
     */
    if (!*balancer &&
        !(*balancer = ap_proxy_get_balancer(r->pool, conf, *url)))
        return DECLINED;

    /* Step 2: find the session route */

    runtime = find_session_route(*balancer, r, &route, &sticky, url);
    /* Lock the LoadBalancer
     * XXX: perhaps we need the process lock here
     */
    if ((rv = PROXY_THREAD_LOCK(*balancer)) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
                     "proxy: BALANCER: (%s). Lock failed for pre_request",
                     (*balancer)->name);
        return DECLINED;
    }
    if (runtime) {
        int i, total_factor = 0;
        proxy_worker *workers;
        /* We have a sticky load balancer
         * Update the workers status
         * so that even session routes get
         * into account.
         */
        workers = (proxy_worker *)(*balancer)->workers->elts;
        for (i = 0; i < (*balancer)->workers->nelts; i++) {
            /* Take into calculation only the workers that are
             * not in error state or not disabled.
             *
             * TODO: Abstract the below, since this is dependent
             *       on the LB implementation
             */
            if (PROXY_WORKER_IS_USABLE(workers)) {
                workers->s->lbstatus += workers->s->lbfactor;
                total_factor += workers->s->lbfactor;
            }
            workers++;
        }
        runtime->s->lbstatus -= total_factor;
        runtime->s->elected++;

        *worker = runtime;
    }
    else if (route && (*balancer)->sticky_force) {
        int i, member_of = 0;
        proxy_worker *workers;
        /*
         * We have a route provided that doesn't match the
         * balancer name. See if the provider route is the
         * member of the same balancer in which case return 503
         */
        workers = (proxy_worker *)(*balancer)->workers->elts;
        for (i = 0; i < (*balancer)->workers->nelts; i++) {
            if (*(workers->s->route) && strcmp(workers->s->route, route) == 0) {
                member_of = 1;
                break;
            }
            workers++;
        }
        if (member_of) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
                         "proxy: BALANCER: (%s). All workers are in error state for route (%s)",
                         (*balancer)->name, route);
            if ((rv = PROXY_THREAD_UNLOCK(*balancer)) != APR_SUCCESS) {
                ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
                             "proxy: BALANCER: (%s). Unlock failed for pre_request",
                             (*balancer)->name);
            }
            return HTTP_SERVICE_UNAVAILABLE;
        }
    }

    if ((rv = PROXY_THREAD_UNLOCK(*balancer)) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
                     "proxy: BALANCER: (%s). Unlock failed for pre_request",
                     (*balancer)->name);
    }
    if (!*worker) {
        runtime = find_best_worker(*balancer, r);
        if (!runtime) {
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
                         "proxy: BALANCER: (%s). All workers are in error state",
                         (*balancer)->name);

            return HTTP_SERVICE_UNAVAILABLE;
        }
        if ((*balancer)->sticky && runtime) {
            /*
             * This balancer has sticky sessions and the client either has not
             * supplied any routing information or all workers for this route
             * including possible redirect and hotstandby workers are in error
             * state, but we have found another working worker for this
             * balancer where we can send the request. Thus notice that we have
             * changed the route to the backend.
             */
            apr_table_setn(r->subprocess_env, "BALANCER_ROUTE_CHANGED", "1");
        }
        *worker = runtime;
    }

    (*worker)->s->busy++;

    /* Add balancer/worker info to env. */
    apr_table_setn(r->subprocess_env,
                   "BALANCER_NAME", (*balancer)->name);
    apr_table_setn(r->subprocess_env,
                   "BALANCER_WORKER_NAME", (*worker)->name);
    apr_table_setn(r->subprocess_env,
                   "BALANCER_WORKER_ROUTE", (*worker)->s->route);

    /* Rewrite the url from 'balancer://url'
     * to the 'worker_scheme://worker_hostname[:worker_port]/url'
     * This replaces the balancers fictional name with the
     * real hostname of the elected worker.
     */
    access_status = rewrite_url(r, *worker, url);
    /* Add the session route to request notes if present */
    if (route) {
        apr_table_setn(r->notes, "session-sticky", sticky);
        apr_table_setn(r->notes, "session-route", route);

        /* Add session info to env. */
        apr_table_setn(r->subprocess_env,
                       "BALANCER_SESSION_STICKY", sticky);
        apr_table_setn(r->subprocess_env,
                       "BALANCER_SESSION_ROUTE", route);
    }
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                 "proxy: BALANCER (%s) worker (%s) rewritten to %s",
                 (*balancer)->name, (*worker)->name, *url);

    return access_status;
}
bool rewrite_urls(xmlNode *n, const char *base,
		struct save_complete_entry *list)
{
	xmlNode *child;

	assert(n->type == XML_ELEMENT_NODE);

	/**
	 * We only need to consider the following cases:
	 *
	 * Attribute:      Elements:
	 *
	 * 1)   data         <object>
	 * 2)   href         <a> <area> <link>
	 * 3)   src          <script> <input> <frame> <iframe> <img>
	 * 4)   n/a          <style>
	 * 5)   n/a          any <base> tag
	 * 6)   background   any (except those above)
	 */
	if (!n->name) {
		/* ignore */
	}
	/* 1 */
	else if (strcmp((const char *) n->name, "object") == 0) {
		if (!rewrite_url(n, "data", base, list))
			return false;
	}
	/* 2 */
	else if (strcmp((const char *) n->name, "a") == 0 ||
			strcmp((const char *) n->name, "area") == 0 ||
			strcmp((const char *) n->name, "link") == 0) {
		if (!rewrite_url(n, "href", base, list))
			return false;
	}
	/* 3 */
	else if (strcmp((const char *) n->name, "frame") == 0 ||
			strcmp((const char *) n->name, "iframe") == 0 ||
			strcmp((const char *) n->name, "input") == 0 ||
			strcmp((const char *) n->name, "img") == 0 ||
			strcmp((const char *) n->name, "script") == 0) {
		if (!rewrite_url(n, "src", base, list))
			return false;
	}
	/* 4 */
	else if (strcmp((const char *) n->name, "style") == 0) {
		unsigned int len;
		xmlChar *content;

		for (child = n->children; child != 0; child = child->next) {
			char *rewritten;
			/* Get current content */
			content = xmlNodeGetContent(child);
			if (!content)
				/* unfortunately we don't know if this is
				 * due to memory exhaustion, or because
				 * there is no content for this node */
				continue;

			/* Rewrite @import rules */
			rewritten = rewrite_stylesheet_urls(
					(const char *) content,
					strlen((const char *) content),
					(int *) &len, base, list);
			xmlFree(content);
			if (!rewritten)
				return false;

			/* set new content */
			xmlNodeSetContentLen(child,
					(const xmlChar*)rewritten,
					len);
		}

		return true;
	}
	/* 5 */
	else if (strcmp((const char *) n->name, "base") == 0) {
		/* simply remove any <base> tags from the document */
		xmlUnlinkNode(n);
		xmlFreeNode(n);
		/* base tags have no content, so there's no point recursing
		 * additionally, we've just destroyed this node, so trying
		 * to recurse would result in bad things happening */
		return true;
	}
	/* 6 */
	else {
	        if (!rewrite_url(n, "background", base, list))
	                return false;
	}

	/* now recurse */
	for (child = n->children; child;) {
		/* we must extract the next child now, as if the current
		 * child is a <base> element, it will be removed from the
		 * tree (see 5, above), thus preventing extraction of the
		 * next child */
		xmlNode *next = child->next;
		if (child->type == XML_ELEMENT_NODE) {
			if (!rewrite_urls(child, base, list))
				return false;
		}
		child = next;
	}

	return true;
}