Exemplo n.º 1
0
static int mod_http_request(calipso_request_t *request)
{
    char date[64];
    time_t tm;
    //calipso_pool_t *pool = calipso_request_get_pool(request);
   	calipso_config_t * config = calipso_request_get_config(request);
   	calipso_reply_t * reply = calipso_request_get_reply(request);
	int http_status  = calipso_reply_get_status(reply);

    tm = calipso_request_get_time(request);

	cpo_http_time(date, &tm);

    calipso_reply_set_header_value(reply, "Date", "%s", date);
	calipso_reply_set_header_value(reply, "Server", "%s", calipso_get_server_string(config));
	/* connection ? */
	mod_http_set_keepalive(request);

	/* check pre errors from request/reply */
	if ( calipso_http_status_is_error(http_status)) {
		TRACE("Pre http error %d\n", http_status);
		return (0);
	}

	/*XXX: HTTP 1.1 require host */
    if (request->host == NULL) {
        calipso_reply_set_status(reply, HTTP_BAD_REQUEST);
        return (0);
    }

    calipso_reply_set_status(reply, HTTP_OK);

    return 1;
}
Exemplo n.º 2
0
static int mod_autoind_resource(calipso_request_t *request)
{
    char *uri;
    calipso_reply_t *reply = calipso_request_get_reply(request);
    calipso_resource_t *resource = calipso_reply_get_resource(reply);
    int http_status  = calipso_reply_get_status(reply);

    if (!calipso_resource_is_directory(resource)
            ||( calipso_http_status_is_error(http_status)
                && http_status != HTTP_FORBIDDEN )) {
        return NOK;
    }

    if(calipso_resource_is_directory(reply->resource))  {

        uri = calipso_request_get_uri(request);

        if( cpo_strlen( strrchr(uri,'/') ) == 1 ) {
            calipso_reply_set_status(reply, HTTP_OK);
        } else {
            calipso_reply_set_status(reply, HTTP_MOVED_PERMANENTLY);
        }

        mod_autoind_reply(request);
    }

    return OK;
}
Exemplo n.º 3
0
static int mod_http_set_if_modified_since(calipso_request_t *request, const char *http_date)
{
	const char *modified_since = calipso_request_get_header_value(request, "if-modified-since");

	if(modified_since && !strcmp(http_date , modified_since)) {

		calipso_reply_set_status(request->reply, HTTP_NOT_MODIFIED);
		return OK;	
	}
	return NOK;
}
Exemplo n.º 4
0
static int calipso_request_read_body(calipso_request_t *request)
{
    int reqlen = 0;

    calipso_client_t *client = request->client;
    calipso_socket_t *listener = client->listener;

    int max_size = request->in_filter->total_bytes + client->pending_bytes;

    if (max_size < REQUEST_BODY_SIZE_MAX) {

        char *buf = xmalloc(client->pending_bytes + 2);

        if (buf == NULL) {
            return calipso_reply_set_status(request->reply,
                                            HTTP_INTERNAL_SERVER_ERROR);
        }

        reqlen = listener->r(client, buf, client->pending_bytes);

        if (reqlen > 0) {

            assert(reqlen == (int)client->pending_bytes);

            chunks_add_tail(request->in_filter, buf, reqlen);
        } else if (reqlen < 0) {

            calipso_client_connection_error(client);
            reqlen = CPO_ERR;
        }

        free(buf);
    } else {
        return calipso_reply_set_status(request->reply,
                                        HTTP_REQUEST_ENTITY_TOO_LARGE);
    }

    return reqlen;
}
Exemplo n.º 5
0
static int  mod_rewrite_request(calipso_request_t *request)
{
	regex_t r;
	TRACE("Start\n");

	compile_regex (&r, "^/dokuwiki/(data|conf|bin|inc)/");

	if ( match(&r, request->uri) ) {
		//test just deny
		calipso_reply_set_status(request->reply, HTTP_FORBIDDEN);
	} 

	regfree (& r);
	return CPO_OK;
}
Exemplo n.º 6
0
static int mod_http_partial_content(calipso_request_t *request, int fd)
{
	/* HTTP_PARTIAL_CONTENT */

    char *range;
    char *type;
    char *offset1;
	char *offset2;
    
    uintmax_t total_size;
    uintmax_t partial_size;

    range = calipso_request_get_header_value(request, "range");

    if (range) {
        calipso_reply_set_status(request->reply, HTTP_PARTIAL_CONTENT);
		type = offset1 = offset2 = NULL;
		http_range_tokenize(range, &type, &offset1 , &offset2);
        TRACE("RANGE: %s\n", range);
        TRACE("type: %s offset1: %s offset2: %s \n", type, offset1, offset2);

        total_size = calipso_resource_get_size(request->reply->resource);
        partial_size = total_size - atol(offset1);
		TRACE("partial size: %llu ? total size %llu\n", partial_size, total_size);

		calipso_reply_set_header_value(request->reply, 
			"content-range", "bytes=%s-%llu/%llu", offset1, total_size - 1, total_size);
        calipso_reply_set_header_value(request->reply, 
			"Content-Length", "%llu", partial_size);

        /*set fd position */
        (off_t)lseek(fd, (off_t)atoi(offset1), SEEK_SET);

    }
/* !HTTP_PARTIAL_CONTENT*/
	return OK;
}
Exemplo n.º 7
0
static int mod_autoind_make_index_table(calipso_reply_t * reply, const char *uri, int prop)
{
    DIR *dir;
    struct stat sb;
    struct tm tm;
    char date[26];
    struct dirent *ent;

    cpo_array_t arr;
    cpo_autoind_entry_t *entry;
    int i,dname_len;
    char *dname;
    const char * directory = calipso_resource_get_path(reply->resource);

    struct chunk_ctx * cb  = chunk_ctx_alloc(reply->pool);

    arr.elem_size = sizeof(cpo_autoind_entry_t);
    arr.v = calloc(40 , sizeof(cpo_autoind_entry_t) );
    arr.num = 0;
    arr.max = 32;


    if ((dir = opendir(directory)) == NULL) {

        calipso_reply_set_status(reply, HTTP_FORBIDDEN);
        return CPO_ERR;
    }

    while ((ent = readdir(dir)) != NULL) {

        if(!strncmp(ent->d_name, ".", 1)) {
            continue;
        }

        if( stat(ent->d_name , &sb) != -1) {

            entry = cpo_array_push(&arr);
            entry->name  = cpo_pool_strdup(reply->pool, ent->d_name);
            entry->mtime = sb.st_mtime;
            entry->size =  sb.st_size;
            entry->is_dir =  S_ISDIR(sb.st_mode);
        }
    }

    closedir(dir);

    cpo_array_qsort(&arr, mod_autoindex_cmp_entries);

    chunk_ctx_printf(reply->pool, cb, indheadfoot[0], uri, uri);

    if(strcmp(uri,"/") ) {
        char dir[FILENAME_MAX];
        strncpy(dir, uri, sizeof(dir));

        chunk_ctx_printf(reply->pool, cb, "<a href=\"%s\">%s</a>%s %40s\n",
                         dirname(dir), PARENT_DIR_NAME, add_space(PARENT_DIR_NAME,
                                 sizeof(PARENT_DIR_NAME), SPACE_CHAR), "-");
    }

    for(i =0; i < arr.num; i++)
    {
        entry = cpo_array_get_at(&arr, i);
        dname_len = cpo_strlen(entry->name);

        if(ETALON_SPACE < dname_len) {
            int dots;
            dname = cpo_pool_strdup(reply->pool, entry->name);

            for(dots = 4; dots >= 1; dots--) {
                dname[ETALON_SPACE-dots] = ((dots == 1) ? '>' : '.');
            }

            dname[ETALON_SPACE]='\0';
            dname_len = ETALON_SPACE;
        } else {
            dname = entry->name;
        }

        if(dname) {

            cpo_gmtime(&tm, &entry->mtime);

            cpo_snprintf(date, sizeof(date), "%02d-%s-%d %02d:%02d ",
                         tm.tm_mday, months[tm.tm_mon ],	tm.tm_year, tm.tm_hour, tm.tm_min);

            if(entry->is_dir) {

                chunk_ctx_printf(reply->pool, cb, "<a href=\"%s%s/\">%s/</a>%s%10s %20s\n",
                                 uri, entry->name , dname, add_space(dname, dname_len, SPACE_CHAR), date, "-");
            } else {

                chunk_ctx_printf(reply->pool, cb, "<a href=\"%s%s\">%s</a>%s %s %20.llu\n",
                                 uri, entry->name , dname, add_space(dname, dname_len ,SPACE_CHAR), date, (uintmax_t) entry->size);
            }
            //free dname
        }
    }

    chunk_ctx_printf(reply->pool, cb, indheadfoot[1], "");

    CNUNKS_ADD_TAIL_CTX(reply->out_filter, cb);

    free(arr.v);

    return CPO_OK;
}
Exemplo n.º 8
0
static int mod_http_resource(calipso_request_t *request)
{
    int fd;
    struct stat sb;
	char date[32];
	
    calipso_reply_t *reply = calipso_request_get_reply(request);
    calipso_resource_t *resource = calipso_reply_get_resource(reply);
    const char *filename = calipso_resource_get_path(resource);
	int http_status  = calipso_reply_get_status(reply);
	
	/* Set the default handler */
    calipso_request_set_handler(request, mod_http_reply);

	if (calipso_http_status_is_error(http_status)) {
		TRACE(" http error %d\n", http_status);
		return (0);
	}
	//XXX: IsHandler AddHandelr ...
	if ( is_file_of(filename, ".php") ) {
		return (0);
	}

	/* check method */
    if (strcasecmp(request->method, "GET")  != 0 &&
            strcasecmp(request->method, "HEAD") != 0) {
        calipso_reply_set_status(reply, HTTP_NOT_IMPLEMENTED);
        return (NOK);
    }
	/* stat the resource for other modules to know what type it is */
#ifdef _WIN32
	remove_trailing_slash(filename);
#endif
	if (stat(filename, &sb) < 0) {
	
        //TRACE("ERROR: %s %s\n", strerror(errno), filename);

        switch (errno) {
        case ENOTDIR:
        case ENOENT:
            calipso_reply_set_status(reply, HTTP_NOT_FOUND);
            break;
        case EACCES:
            calipso_reply_set_status(reply, HTTP_FORBIDDEN);
            break;
        case ENAMETOOLONG:
            calipso_reply_set_status(reply, HTTP_REQUEST_URI_TOO_LARGE);
            break;
        default:
            calipso_reply_set_status(reply, HTTP_INTERNAL_SERVER_ERROR);
        }

        return CPO_OK;
    }

    calipso_resource_set_stat(resource, &sb);

	cpo_http_time(date, &sb.st_mtime);
	
	/* modified_since */
	if(USE_HEADER_MODFIED_SINCE && 
		CPO_OK == mod_http_set_if_modified_since(request, date))
		return OK;
	
    if (! calipso_resource_is_file(resource)) {

        /* default state mod_directory override */
		if(!calipso_http_status_is_error(http_status)) {
        	calipso_reply_set_status(reply, HTTP_FORBIDDEN);
		}
        return CPO_OK;
    }

	/*XXX: fcache needed */
	fd = cpo_file_open(filename, 0);

	if(fd < 0 ){
		calipso_reply_set_status(reply, HTTP_INTERNAL_SERVER_ERROR);
		return CPO_ERR;
	}

	calipso_reply_set_header_value(reply, "Accept-Ranges", "bytes");

	if (!calipso_reply_get_header_value(reply, "content-range"))
		reply->content_length = calipso_resource_get_size(resource);
    	//calipso_reply_set_header_value(reply, "Content-Length", "%llu",
        //                               calipso_resource_get_size(resource));

	calipso_reply_set_header_value(reply, "Last-Modified", date);

    calipso_resource_set_file_descriptor(resource, fd);

	mod_http_partial_content(request, fd);

    return CPO_OK;
}
Exemplo n.º 9
0
static int mod_http_translate(calipso_request_t *request)
{
    char *pathname = NULL;
    char *uri = NULL;
    char *documentroot = NULL;

	calipso_client_t *client = calipso_request_get_client(request);
    calipso_server_t *server = calipso_client_get_server(client);
    calipso_reply_t *reply = calipso_request_get_reply(request);
    calipso_resource_t *resource = calipso_reply_get_resource(reply);
    calipso_pool_t *pool = calipso_request_get_pool(request);

	int http_status  = calipso_reply_get_status(reply);

	if ( calipso_http_status_is_error(http_status)) {
		TRACE(" http error %d\n", http_status);
		return (0);
	}

	if( remove_dots_from_uri_path(request->uri) == -1 ) {
		calipso_reply_set_status(reply, HTTP_BAD_REQUEST);
        return 0;
	}

	if (!cpo_uri_sanity_check( request->uri )) {
       	calipso_reply_set_status(reply, HTTP_BAD_REQUEST);
        return 0;
    }

	uri = calipso_request_get_uri(request);

    //if (*uri != '/') {
    //    calipso_reply_set_status(reply, HTTP_BAD_REQUEST);
    //    return (0);
    //}

    documentroot = calipso_server_get_documentroot(server);

    if (!documentroot) {
        calipso_reply_set_status(reply, HTTP_BAD_REQUEST);
        return (0);
    }

    pathname = cpo_pool_malloc(pool, MAXPATHLEN);
    strlcpy(pathname, documentroot, MAXPATHLEN);
	cpo_uri_strdecode(uri, uri);
    if (strlcat(pathname, uri, MAXPATHLEN) >= MAXPATHLEN) {
        calipso_reply_set_status(reply, HTTP_REQUEST_URI_TOO_LARGE);
        return (0);
    }

    /* security chek */
    //if (!cpo_uri_sanity_check( pathname )) {
    //   	calipso_reply_set_status(reply, HTTP_BAD_REQUEST);
    //    return 0;
    //}

    /* decode string */
    //cpo_uri_strdecode(pathname, pathname);
    calipso_resource_set_path(resource, pathname);

    return 1;
}
Exemplo n.º 10
0
static int request_parse_status_line(calipso_request_t *request, char *line)
{
    char *method = NULL;
    char *uri = NULL;
    char *lastword = NULL;
    char *querystring = NULL;
/*TODO: fix me */
    /* Method */
    method = line;
    calipso_request_set_method(request, method);
    while (*line && !isspace((int )*line) && ++line)
        ;
    if (*line == 0)
        return (1);
    *line++ = 0;

    uri = line;
    if (*uri == 0)
        return (1);

    lastword = NULL;
    while (*line) {
        if (isspace((int)*line) && *(line + 1) && !isspace((int )*(line + 1)))
            lastword = line + 1;
        ++line;
    }

    if (lastword) {
        *(lastword - 1) = 0;
        calipso_request_set_version(request, lastword);

        /* remove tailing spaces */
        while (*lastword && ++lastword)
            ;
        --lastword;
        while (isspace((int)*lastword) && (*lastword-- = 0) == 0)
            ;
    }

    while (*uri && isspace((int )*uri) && ++uri)
        ;

    uri = cpo_strtok(uri, "?");
    querystring = cpo_strtok( NULL, "?");

    if (querystring) {
	char *new_querystring = cpo_pool_strdup(request->pool, querystring);
        calipso_request_set_querystring(request, new_querystring);
    }

    if (uri && *uri == '/') {
    	char *new_uri = cpo_pool_strdup(request->pool, uri);
        calipso_request_set_uri(request, new_uri);
        /* remove tailing spaces */
        /*
         while (*uri && ++uri)
         ;
         --uri;
         while (isspace((int)*uri) && (*uri-- = 0) == 0)
         ;
         */
    } else {
    	calipso_reply_set_status(request->reply,
                                                HTTP_BAD_REQUEST);
    }

    return (1);
}
Exemplo n.º 11
0
static int calipso_request_read_header(calipso_request_t *request)
{
    int n;
    char p;
    char *end;
    calipso_client_t *client = request->client;

    chunk_buf_t * c = request->header_buf;

    calipso_socket_t *listener = calipso_client_get_listener(client);

    for (;;) {

        if ((INPUTBUFSZ - 1) <= c->size) {
            *(c->b + c->size) = '\0';
            client->done = CPO_OK;
            return calipso_reply_set_status(request->reply,
                                            HTTP_REQUEST_URI_TOO_LARGE);
        }

        n = listener->r(client, &p, 1);

        if (n <= 0) {
            if (errno == EAGAIN) {
                TRACE("EAGAIN\n");
                break;
            } else {
                *(c->b + c->size) = '\0';
                cpo_log_error(calipso->log, "connection error %s",
                              strerror(errno));
                calipso_client_connection_error(client);
                return CPO_ERR;
            }
        } else {
            //printf("read_char 0x%X - %c\n", p, p);
            if (p < 0x9 || p > 0x7e) {
                *(c->b + c->size) = '\0';
                client->done = CPO_OK;
                cpo_log_error(calipso->log, "Non printable char -> 0x%X", p);
                return calipso_reply_set_status(request->reply,
                                                HTTP_BAD_REQUEST);
            }

            *(c->b + c->size) = p;
            c->size++;
            *(c->b + c->size) = '\0';
        }

        if (c->size > 4) {

            end = (c->b + (c->size - 4));

            if (!strcmp(end, EOLCR EOLCR)) {
                return CPO_OK;
            }

            end = (c->b + (c->size - 2));

            if (!strcmp(end, EOL EOL)) {
                return CPO_OK;
            }
        }

    }

    return NOK;
}