コード例 #1
0
ファイル: handler.c プロジェクト: arssivka/naomech
static void
handleFile(TSession *const sessionP,
           const char *const fileName,
           time_t const fileModTime,
           MIMEType *const mimeTypeP) {
/*----------------------------------------------------------------------------
   This is an HTTP request handler for a GET.  It does the classic
   web server thing: send the file named in the URL to the client.
-----------------------------------------------------------------------------*/
    TFile *fileP;
    bool success;

    success = FileOpen(&fileP, fileName, O_BINARY | O_RDONLY);
    if (!success)
        ResponseStatusErrno(sessionP);
    else {
        if (notRecentlyModified(sessionP, fileModTime)) {
            ResponseStatus(sessionP, 304);
            ResponseWriteStart(sessionP);
        } else
            sendFileAsResponse(sessionP, fileP,
                               fileName, fileModTime, mimeTypeP);

        FileClose(fileP);
    }
}
コード例 #2
0
static abyss_bool
ServerDefaultHandlerFunc(TSession * const sessionP) {

    struct _TServer * const srvP = ConnServer(sessionP->conn)->srvP;

    char *p;
    char z[4096];
    TFileStat fs;
    unsigned int i;
    abyss_bool endingslash=FALSE;

    if (!RequestValidURIPath(sessionP)) {
        ResponseStatus(sessionP, 400);
        return TRUE;
    }

    /* Must check for * (asterisk uri) in the future */
    if (sessionP->request_info.method == m_options) {
        ResponseAddField(sessionP, "Allow", "GET, HEAD");
        ResponseContentLength(sessionP, 0);
        ResponseStatus(sessionP, 200);
        return TRUE;
    }

    if ((sessionP->request_info.method != m_get) &&
        (sessionP->request_info.method != m_head)) {
        ResponseAddField(sessionP, "Allow", "GET, HEAD");
        ResponseStatus(sessionP, 405);
        return TRUE;
    }

    strcpy(z, srvP->filespath);
    strcat(z, sessionP->request_info.uri);

    p = z + strlen(z) - 1;
    if (*p == '/') {
        endingslash = TRUE;
        *p = '\0';
    }

#ifdef WIN32
    p = z;
    while (*p) {
        if ((*p) == '/')
            *p= '\\';

        ++p;
    }
#endif  /* WIN32 */

    if (!FileStat(z, &fs)) {
        ResponseStatusErrno(sessionP);
        return TRUE;
    }

    if (fs.st_mode & S_IFDIR) {
        /* Redirect to the same directory but with the ending slash
        ** to avoid problems with some browsers (IE for examples) when
        ** they generate relative urls */
        if (!endingslash) {
            strcpy(z, sessionP->request_info.uri);
            p = z+strlen(z);
            *p = '/';
            *(p+1) = '\0';
            ResponseAddField(sessionP, "Location", z);
            ResponseStatus(sessionP, 302);
            ResponseWrite(sessionP);
            return TRUE;
        }

        *p = DIRECTORY_SEPARATOR[0];
        ++p;

        i = srvP->defaultfilenames.size;
        while (i-- > 0) {
            *p = '\0';        
            strcat(z, (srvP->defaultfilenames.item[i]));
            if (FileStat(z, &fs)) {
                if (!(fs.st_mode & S_IFDIR))
                    return ServerFileHandler(sessionP, z, fs.st_mtime,
                                             srvP->mimeTypeP);
            }
        }

        *(p-1) = '\0';
        
        if (!FileStat(z, &fs)) {
            ResponseStatusErrno(sessionP);
            return TRUE;
        }
        return ServerDirectoryHandler(sessionP, z, fs.st_mtime,
                                      srvP->mimeTypeP);
    } else
        return ServerFileHandler(sessionP, z, fs.st_mtime,
                                 srvP->mimeTypeP);
}
コード例 #3
0
static abyss_bool
ServerFileHandler(TSession * const r,
                  char *     const z,
                  time_t     const fileModTime,
                  MIMEType * const mimeTypeP) {

    const char * mediatype;
    TFile file;
    uint64_t filesize;
    uint64_t start;
    uint64_t end;
    TDate date;
    char * p;
    TDate filedate;
    
    mediatype = MIMETypeGuessFromFile2(mimeTypeP, z);

    if (!FileOpen(&file,z,O_BINARY | O_RDONLY)) {
        ResponseStatusErrno(r);
        return TRUE;
    }

    fileDate(r, fileModTime, &filedate);

    p = RequestHeaderValue(r, "if-modified-since");
    if (p) {
        if (DateDecode(p,&date)) {
            if (DateCompare(&filedate, &date) <= 0) {
                ResponseStatus(r, 304);
                ResponseWrite(r);
                return TRUE;
            } else
                r->ranges.size = 0;
        }
    }
    filesize = FileSize(&file);

    switch (r->ranges.size) {
    case 0:
        ResponseStatus(r, 200);
        break;

    case 1: {
        abyss_bool decoded;
        decoded = RangeDecode((char *)(r->ranges.item[0]), filesize,
                              &start, &end);
        if (!decoded) {
            ListFree(&(r->ranges));
            ResponseStatus(r, 200);
            break;
        }
        
        sprintf(z, "bytes %llu-%llu/%llu", start, end, filesize);

        ResponseAddField(r, "Content-range", z);
        ResponseContentLength(r, end - start + 1);
        ResponseStatus(r, 206);
    } break;

    default:
        ResponseContentType(r, "multipart/ranges; boundary=" BOUNDARY);
        ResponseStatus(r, 206);
        break;
    }
    
    if (r->ranges.size == 0) {
        ResponseContentLength(r, filesize);
        ResponseContentType(r, mediatype);
    }
    
    if (DateToString(&filedate, z))
        ResponseAddField(r, "Last-Modified", z);

    ResponseWrite(r);

    if (r->request_info.method != m_head)
        sendBody(r, &file, filesize, mediatype, start, end, z);

    FileClose(&file);

    return TRUE;
}