⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 httpd.c

📁 HTTPD server. AVR platform
💻 C
📖 第 1 页 / 共 2 页
字号:

        urll = strlen(req->req_url);
        if ((index = NutHeapAllocClear(urll + 12)) == 0) {
            NutHttpSendError(stream, req, 500);
            return;
        }
        if (urll)
            strcpy(index, req->req_url);
        if (urll && index[urll - 1] != '/')
            strcat(index, "/");
        strcat(index, "index.html");

        if (http_root) {
            filename = NutHeapAlloc(strlen(http_root) + strlen(index) + 1);
            strcpy(filename, http_root);
        } else {
            filename = NutHeapAlloc(strlen(index) + 6);
            strcpy(filename, "UROM:");
        }
        strcat(filename, index);

        NutHeapFree(index);

        fd = _open(filename, _O_BINARY | _O_RDONLY);
        NutHeapFree(filename);
        if (fd == -1) {
            NutHttpSendError(stream, req, 404);
            return;
        }
    }
    file_len = _filelength(fd);
    NutHttpSendHeaderTop(stream, req, 200, "Ok");
    NutHttpSendHeaderBot(stream, NutGetMimeType(req->req_url), file_len);
    if (req->req_method != METHOD_HEAD) {
        size = 512;
        if ((data = NutHeapAlloc(size)) != 0) {
            while (file_len) {
                if (file_len < 512L)
                    size = (int) file_len;

                n = _read(fd, data, size);
                fwrite(data, 1, n, stream);
                file_len -= (long) n;
            }
            NutHeapFree(data);
        }
    }
    _close(fd);
}

/*!
 *
 */
static char *NextWord(char *str)
{
    while (*str && *str != ' ' && *str != '\t')
        str++;
    if (*str)
        *str++ = 0;
    while (*str == ' ' || *str == '\t')
        str++;
    return str;
}

/*!
 *
 */
static REQUEST *CreateRequestInfo(void)
{
    return NutHeapAllocClear(sizeof(REQUEST));
}

/*!
 *
 */
static void DestroyRequestInfo(REQUEST * req)
{
    if (req->req_url)
        NutHeapFree(req->req_url);
    if (req->req_query)
        NutHeapFree(req->req_query);
    if (req->req_type)
        NutHeapFree(req->req_type);
    if (req->req_cookie)
        NutHeapFree(req->req_cookie);
    if (req->req_auth)
        NutHeapFree(req->req_auth);
    if (req->req_agent)
        NutHeapFree(req->req_agent);
    NutHeapFree(req);
}

/*!
 * \brief Register the HTTP server's root directory.
 *
 * Only one root directory is supported. Subsequent calls will
 * override previous settings.
 *
 * \param path Pathname of the root directory. Must include the
 *             device name followed by a colon followed by a
 *             directory path followed by a trailing slash.
 *
 * \return 0 on success, -1 otherwise.
 */
int NutRegisterHttpRoot(char *path)
{
    int len;

    if (http_root)
        NutHeapFree(http_root);
    if (path && (len = strlen(path)) != 0) {
        if ((http_root = NutHeapAlloc(len + 1)) != 0)
            strcpy(http_root, path);
    } else
        http_root = 0;

    return 0;
}

/*!
 * \brief Process the next HTTP request.
 *
 * Waits for the next HTTP request on an established connection
 * and processes it.
 *
 * \param stream Stream of the socket connection, previously opened for 
 *               binary read and write.
 */
void NutHttpProcessRequest(FILE * stream)
{
    REQUEST *req;
    char *method;
    char *path;
    char *line;
    char *protocol;
    char *cp;

    /*
     * Parse the first line of the request.
     * <method> <path> <protocol>
     */
    if ((req = CreateRequestInfo()) == 0)
        return;
    if ((method = NutHeapAlloc(256)) == 0) {
        DestroyRequestInfo(req);
        return;
    }
    fgets(method, 256, stream);
    if ((cp = strchr(method, '\r')) != 0)
        *cp = 0;
    if ((cp = strchr(method, '\n')) != 0)
        *cp = 0;

    /*
     * Parse remaining request headers.
     */
    if ((line = NutHeapAlloc(256)) == 0) {
        NutHeapFree(method);
        DestroyRequestInfo(req);
        return;
    }
    for (;;) {
        if (fgets(line, 256, stream) == 0)
            break;
        if ((cp = strchr(line, '\r')) != 0)
            *cp = 0;
        if ((cp = strchr(line, '\n')) != 0)
            *cp = 0;
        if (*line == 0)
            break;
        if (strncasecmp(line, "Authorization:", 14) == 0) {
            if (req->req_auth == 0) {
                cp = &line[14];
                while (*cp == ' ' || *cp == '\t')
                    cp++;
                if ((req->req_auth = NutHeapAlloc(strlen(cp) + 1)) == 0)
                    break;
                strcpy(req->req_auth, cp);
            }
        } else if (strncasecmp(line, "Content-Length:", 15) == 0)
            req->req_length = 0 /*atoi(&line[15]) */ ;
        else if (strncasecmp(line, "Content-Type:", 13) == 0) {
            if (req->req_type == 0) {
                cp = &line[13];
                while (*cp == ' ' || *cp == '\t')
                    cp++;
                if ((req->req_type = NutHeapAlloc(strlen(cp) + 1)) == 0)
                    break;
                strcpy(req->req_type, cp);
            }
        } else if (strncasecmp(line, "Cookie:", 7) == 0) {
            if (req->req_cookie == 0) {
                cp = &line[7];
                while (*cp == ' ' || *cp == '\t')
                    cp++;
                if ((req->req_cookie = NutHeapAlloc(strlen(cp) + 1)) == 0)
                    break;
                strcpy(req->req_cookie, cp);
            }
        } else if (strncasecmp(line, "User-Agent:", 11) == 0) {
            if (req->req_agent == 0) {
                cp = &line[11];
                while (*cp == ' ' || *cp == '\t')
                    cp++;
                if ((req->req_agent = NutHeapAlloc(strlen(cp) + 1)) == 0)
                    break;
                strcpy(req->req_agent, cp);
            }
        }
    }
    NutHeapFree(line);

    path = NextWord(method);
    protocol = NextWord(path);
    NextWord(protocol);

    if (strcasecmp(method, "GET") == 0)
        req->req_method = METHOD_GET;
    else if (strcasecmp(method, "HEAD") == 0)
        req->req_method = METHOD_HEAD;
    else if (strcasecmp(method, "POST") == 0)
        req->req_method = METHOD_POST;
    else {
        NutHeapFree(method);
        DestroyRequestInfo(req);
        NutHttpSendError(stream, req, 501);
        return;
    }
    if (*path == 0 || *protocol == 0) {
        NutHeapFree(method);
        DestroyRequestInfo(req);
        NutHttpSendError(stream, req, 400);
        return;
    }

    req->req_version = 10;
    if (strcasecmp(protocol, "HTTP/0.9") == 0)
        req->req_version = 9;

    if ((cp = strchr(path, '?')) != 0) {
        *cp++ = 0;
        if ((req->req_query = NutHeapAlloc(strlen(cp) + 1)) == 0) {
            NutHeapFree(method);
            DestroyRequestInfo(req);
            return;
        }
        strcpy(req->req_query, cp);
    }
    if ((req->req_url = NutHeapAlloc(strlen(path) + 1)) == 0) {
        NutHeapFree(method);
        DestroyRequestInfo(req);
        return;
    }
    strcpy(req->req_url, path);

    NutHeapFree(method);

    if (NutDecodePath(req->req_url) == 0)
        NutHttpSendError(stream, req, 400);
    else
        NutHttpProcessFileRequest(stream, req);

    DestroyRequestInfo(req);
}

/*@}*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -