Changeset 21 in Main for trunk/Server/server.c


Ignore:
Timestamp:
Sep 14, 2024, 9:39:39 PM (2 months ago)
Author:
Nishi
Message:

can send file now

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Server/server.c

    r20 r21  
    1515#include <stdbool.h>
    1616#include <stdarg.h>
     17#include <sys/stat.h>
    1718
    1819#include <cm_string.h>
    1920#include <cm_log.h>
     21#include <cm_dir.h>
    2022
    2123#ifdef __MINGW32__
    2224#include <winsock2.h>
    2325#include <process.h>
    24 #define NO_IPV6
    2526#else
    2627#include <sys/select.h>
     
    3738int sockcount = 0;
    3839
    39 #ifdef NO_IPV6
    40 #define SOCKADDR struct sockaddr_in
    41 #else
    42 #define SOCKADDR struct sockaddr_in6
    43 #endif
    4440SOCKADDR addresses[MAX_PORTS];
    4541int sockets[MAX_PORTS];
     
    152148            "</html>\n"
    153149
    154 void tw_process_page(SSL* ssl, int sock, const char* status, const char* type, const unsigned char* doc, size_t size) {
     150void tw_process_page(SSL* ssl, int sock, const char* status, const char* type, FILE* f, const unsigned char* doc, size_t size) {
    155151        char construct[512];
    156152        sprintf(construct, "%llu", (unsigned long long)size);
     
    170166        size_t incr = 0;
    171167        while(1) {
    172                 tw_write(ssl, sock, (unsigned char*)doc + incr, size < 128 ? size : 128);
     168                if(f != NULL){
     169                        char buffer[128];
     170                        fread(buffer, size < 128 ? size : 128, 1, f);
     171                        tw_write(ssl, sock, buffer, size < 128 ? size : 128);
     172                }else{
     173                        tw_write(ssl, sock, (unsigned char*)doc + incr, size < 128 ? size : 128);
     174                }
    173175                incr += 128;
    174176                if(size <= 128) break;
     
    216218void tw_http_error(SSL* ssl, int sock, int error, char* name, int port) {
    217219        char* str = tw_http_default_error(error, name, port);
    218         tw_process_page(ssl, sock, tw_http_status(error), "text/html", str, strlen(str));
     220        tw_process_page(ssl, sock, tw_http_status(error), "text/html", NULL, str, strlen(str));
    219221        free(str);
    220222}
     
    240242                                free(tmp);
    241243                                free(h);
     244                        } else if(add[i] == 'l') {
     245                                char* h = cm_url_escape(va_arg(va, const char*));
     246                                char* tmp = *str;
     247                                *str = cm_strcat(tmp, h);
     248                                free(tmp);
     249                                free(h);
    242250                        } else if(add[i] == 'd') {
    243251                                int n = va_arg(va, int);
     
    266274        int port;
    267275        bool ssl;
     276        SOCKADDR addr;
    268277};
    269278
     
    272281        bool ssl = ((struct pass_entry*)ptr)->ssl;
    273282        int port = ((struct pass_entry*)ptr)->port;
     283        SOCKADDR addr = ((struct pass_entry*)ptr)->addr;
    274284        free(ptr);
    275285#else
    276 void tw_server_pass(int sock, bool ssl, int port) {
     286void tw_server_pass(int sock, bool ssl, int port, SOCKADDR addr) {
    277287#endif
    278288        char* name = config.hostname;
     
    295305        int ret = tw_http_parse(s, sock, &req);
    296306        if(ret == 0) {
     307                char* vhost = cm_strdup(config.hostname);
    297308                int i;
     309                for(i = 0; req.headers[i] != NULL; i += 2){
     310                        if(cm_strcaseequ(req.headers[i], "Host")){
     311                                free(vhost);
     312                                vhost = req.headers[i + 1];
     313                                break;
     314                        }
     315                }
     316                cm_log("Server", "Host is %s", vhost);
     317                int port = s == NULL ? 80 : 443;
     318                char* host = cm_strdup(vhost);
     319                for(i = 0; vhost[i] != 0; i++){
     320                        if(vhost[i] == ':'){
     321                                host[i] = 0;
     322                                port = atoi(host + i + 1);
     323                                break;
     324                        }
     325                }
     326                cm_log("Server", "Hostname is `%s', port is `%d'", host, port);
     327                struct tw_config_entry* vhost_entry = tw_vhost_match(host, port);
    298328                for(i = 0; i < config.module_count; i++) {
    299329                        tw_mod_request_t mod_req = (tw_mod_request_t)tw_module_symbol(config.modules[i], "mod_request");
     
    313343                }
    314344                if(!res._processed) {
    315                         char* str = malloc(1);
    316                         str[0] = 0;
    317                         addstring(&str, "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n");
    318                         addstring(&str, "<html>\n");
    319                         addstring(&str, "       <head>\n");
    320                         addstring(&str, "               <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n");
    321                         addstring(&str, "               <title>Index of %h</title>\n", req.path);
    322                         addstring(&str, "       </head>\n");
    323                         addstring(&str, "       <body>\n");
    324                         addstring(&str, "               <h1>Index of %h</h1>\n", req.path);
    325                         addstring(&str, "               <hr>\n");
    326                         addstring(&str, "               <table border=\"0\">\n");
    327                         addstring(&str, "                       <tr>\n");
    328                         addstring(&str, "                               <th></th>\n");
    329                         addstring(&str, "                               <th>Filename</th>\n");
    330                         addstring(&str, "                       </tr>\n");
    331                         addstring(&str, "               </table>\n");
    332                         addstring(&str, "               <hr>\n");
    333                         addstring(&str, "               <address>%s Server at %s Port %d</address>\n", tw_server, name, port);
    334                         addstring(&str, "       </body>\n");
    335                         addstring(&str, "</html>\n");
    336                         tw_process_page(s, sock, tw_http_status(200), "text/html", str, strlen(str));
    337                         free(str);
    338                 }
     345                        cm_log("Server", "Document root is %s", vhost_entry->root == NULL ? "not set" : vhost_entry->root);
     346                        char* path = cm_strcat(vhost_entry->root == NULL ? "" : vhost_entry->root, req.path);
     347                        cm_log("Server", "Filesystem path is %s", path);
     348                        struct stat st;
     349                        if(stat(path, &st) == 0){
     350                                if(!tw_permission_allowed(path, addr, req, vhost_entry)){
     351                                        tw_http_error(s, sock, 403, name, port);
     352                                }else if(S_ISDIR(st.st_mode)){
     353                                        char* str = malloc(1);
     354                                        str[0] = 0;
     355                                        char** items = cm_scandir(path);
     356                                        addstring(&str, "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n");
     357                                        addstring(&str, "<html>\n");
     358                                        addstring(&str, "       <head>\n");
     359                                        addstring(&str, "               <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n");
     360                                        addstring(&str, "               <title>Index of %h</title>\n", req.path);
     361                                        addstring(&str, "       </head>\n");
     362                                        addstring(&str, "       <body>\n");
     363                                        addstring(&str, "               <h1>Index of %h</h1>\n", req.path);
     364                                        addstring(&str, "               <hr>\n");
     365                                        addstring(&str, "               <table border=\"0\">\n");
     366                                        addstring(&str, "                       <tr>\n");
     367                                        addstring(&str, "                               <th></th>\n");
     368                                        addstring(&str, "                               <th>Filename</th>\n");
     369                                        addstring(&str, "                       </tr>\n");
     370                                        if(items != NULL){
     371                                                for(i = 0; items[i] != NULL; i++){
     372                                                        addstring(&str, "<tr>\n");
     373                                                        addstring(&str, "       <td></td>\n");
     374                                                        addstring(&str, "       <td><a href=\"%l\">%h</a></td>\n", items[i], items[i]);
     375                                                        addstring(&str, "</tr>\n");
     376                                                }
     377                                        }
     378                                        addstring(&str, "               </table>\n");
     379                                        addstring(&str, "               <hr>\n");
     380                                        addstring(&str, "               <address>%s Server at %s Port %d</address>\n", tw_server, name, port);
     381                                        addstring(&str, "       </body>\n");
     382                                        addstring(&str, "</html>\n");
     383                                        tw_process_page(s, sock, tw_http_status(200), "text/html", NULL, str, strlen(str));
     384                                        free(str);
     385                                }else{
     386                                        char* mime = "application/octet-stream";
     387                                        bool set = false;
     388                                        char* ext = NULL;
     389                                        for(i = strlen(req.path) - 1; i >= 0; i--){
     390                                                if(req.path[i] == '.'){
     391                                                        ext = cm_strdup(req.path + i);
     392                                                        break;
     393                                                }
     394                                        }
     395                                        for(i = 0; i < vhost_entry->mime_count; i++){
     396                                                if(strcmp(vhost_entry->mimes[i].ext, "all") == 0 || (ext != NULL && strcmp(vhost_entry->mimes[i].ext, ext) == 0)){
     397                                                        mime = vhost_entry->mimes[i].mime;
     398                                                        set = true;
     399                                                }
     400                                        }
     401                                        if(!set){
     402                                                for(i = 0; i < config.root.mime_count; i++){
     403                                                        if(strcmp(config.root.mimes[i].ext, "all") == 0 || (ext != NULL && strcmp(config.root.mimes[i].ext, ext) == 0)){
     404                                                                mime = config.root.mimes[i].mime;
     405                                                                set = true;
     406                                                        }
     407                                                }
     408                                        }
     409                                        if(ext != NULL) free(ext);
     410                                        FILE* f = fopen(path, "rb");
     411                                        tw_process_page(s, sock, tw_http_status(200), mime, f, NULL, st.st_size);
     412                                        fclose(f);
     413                                }
     414                        }else{
     415                                tw_http_error(s, sock, 404, name, port);
     416                        }
     417                        free(path);
     418                }
     419                free(vhost);
     420                free(host);
    339421        } else {
    340422                tw_http_error(s, sock, 400, name, port);
     
    379461                                        e->ssl = config.ports[i] & (1ULL << 32);
    380462                                        e->port = config.ports[i];
     463                                        e->addr = claddr;
    381464                                        thread = (HANDLE)_beginthreadex(NULL, 0, tw_server_pass, e, 0, NULL);
    382465#else
    383466                                        pid_t pid = fork();
    384467                                        if(pid == 0) {
    385                                                 tw_server_pass(sock, config.ports[i] & (1ULL << 32), config.ports[i]);
     468                                                tw_server_pass(sock, config.ports[i] & (1ULL << 32), config.ports[i], claddr);
    386469                                                _exit(0);
    387470                                        } else {
Note: See TracChangeset for help on using the changeset viewer.