Ejemplo n.º 1
0
int Webserver::process(FILE* f) {
    char buf[4096];
    char *method;
    char *path;
    char *protocol;
              
    if (!fgets(buf, sizeof(buf), f)) 
       return -1;
    printf("%s", buf);

    char* bufp = buf;
    method = strsep(&bufp, " ");
    path = strsep(&bufp, " ");
    protocol = strsep(&bufp, "\r");
    if (!method || !path || !protocol) 
        return -1;
    
    // Extract request
    HTTPRequest request;
    request.method = string(method);
    request.path = string(path);
    request.readHeaders(f);
    request.writeHeaders(stdout);
    request.readParams(f);
    request.setBody(f);
    // Find and execute action
    Action* action = actions[path];
    if (action == NULL) {
        action = file_action;
    }
    HTTPResponse response = action->execute(request);   
    response.addHeader("Server", string("RayGay Renderslave ") + string(VERSION));
    request.addHeader("Date", WebUtil::formatDate(time(NULL)));
    
    // Send response
    fseek(f, 0, SEEK_CUR); // Force change of stream direction    
    fprintf(f, "HTTP/1.0 %d %s\r\n", response.status, response.statusString().c_str());
    response.writeHeaders(f);
    response.writeBody(f);
    return 0;
}
Ejemplo n.º 2
0
HTTPResponse FileAction::execute(const HTTPRequest& request)
{ 
    HTTPResponse response;
    struct stat statbuf;
    char md5_hex[33];
    string path = document_root + request.path;
    // TODO: Sanitize path, ie. remove ".." and leading "/"
    if (request.method == "GET" || request.method == "HEAD") {
        if (stat(path.c_str(), &statbuf) >= 0) {
            ostringstream os;
            os << statbuf.st_size;         
            response = HTTPResponse(200, WebUtil::pathToMimetype(path));
            response.addHeader("Content-Length",os.str());
            response.addHeader("Last-Modified",WebUtil::formatDate(statbuf.st_mtime));
            FILE* f = fopen(path.c_str(), "r");
            md5_stream_hex(f,md5_hex);
            md5_hex[32] = '\0';
            response.addHeader("Content-MD5",string(md5_hex));
            if (request.method == "GET") {
               rewind(f);
               response.setBody(f);
            } else {
               fclose(f);            
            }
        } else {
            response = HTTPResponse(404, "text/plain");
        }
    } else if (request.method == "DELETE") {
        // This method isn't strictly HTTP1.1, but we need it
        // and I don't want to implement a complete WebDAV stack.    
        unlink(path.c_str());
        response = HTTPResponse(200, "text/plain");
    } else if (request.method == "PUT") {
        long size = atoi(request.getHeader("Content-length").c_str());
        // TODO: If no content-header is sent, return "411 Length required" as per the RFC. 
        bool exists = stat(path.c_str(), &statbuf) != -1;
        FILE* f = fopen(path.c_str(), "w");
        WebUtil::copy(request.bodyFILE, f, size);
        fclose(f);
        if (exists) {
            response = HTTPResponse(200, "text/plain");
            response.setBody("File modified");
        } else {
            response = HTTPResponse(201, "text/plain");
            response.setBody("File created");
        }
    } else if (request.method == "MKCOL") {    
        // This method isn't strictly HTTP1.1, but we need it
        // and I don't want to implement a complete WebDAV stack.
        if (mkdir(path.c_str(), 0777) == -1) {
            response = HTTPResponse(201, "text/plain");
            response.setBody("Dir not created");
        } else {
            response = HTTPResponse(201, "text/plain");
            response.setBody("Dir created");
            printf("Dir %s created\n", path.c_str());
        }
    } else {
        cout << "Unknown method " << request.method << endl;    
        response = HTTPResponse(405, "text/plain");
        response.addHeader("Allow", "PUT, GET, HEAD, DELETE, MKCOL");
    }
    return response;
}