• goahead下载文件


    声明:本文的代码部分为网上代码,但文章属作者原创。

    最近在要使用到goahead上传下载功能,然后发现网上有不少上传文件的教程了,但是下载这块就不是讲的很详细,所以在这里大致讲一下。

    虚拟机版本:ubuntu14.02

    goahead版本:goahead-4.0.2

    goahead文件下载需要添加的源码

    首先我们需要在goahead.c文件中添加部分代码,代码如下:

    1.声明部分

     

    static char   *websIndex;                   /* Default page name */

     

    static char   *websDocuments;               /* Default Web page directory */

     

    PUBLIC void split(char *src, const char *separator, char **dest, int *num)

     

    {

     

    char *pNext;

    int count = 0;

     

     if (src == NULL || strlen(src) == 0) return;

     

    if (separator == NULL || strlen(separator) == 0) return; 

     

    pNext = strtok(src,separator);

     

    while(pNext != NULL)

     

    {

     

    *dest++ = pNext;

     

    ++count;

     

    pNext = strtok(NULL,separator);

     

    }

     

    *num = count;

     

    }

     

    PUBLIC char *getUrlLastSplit(char *s, const char * separator)

     

    {

     

    char    *buf;

     

    //char src[] = "C:\aaa\Wildlife8888.wmv";

     

    char *dest[64];

     

    char *dest2[64];

     

    int num = 0; 

     

    if (separator == NULL || strlen(separator) == 0)

     

    return ""; 

     

    split(s,separator,dest,&num);

     

    if (num>1){

     

    if (dest[num-1] == NULL) {

     

    dest[num-1] = "";

     

    }

     

    buf = walloc(strlen(dest[num-1]) + 1);

     

    strcpy(buf, dest[num-1]);

     

    }else{

     

    buf = walloc(strlen("") + 1);

     

    strcpy(buf, "");

     

    }

     

    return buf;

     

    }

     

    //下载文件

     

    static void fileWriteEvent(Webs *wp);

     

    static void actionDownLoad(Webs *wp, char *path, char *query);

    2.在goahead.c文件中的main函数中websServiceEvents(&finished);之前添加

    websDefineAction("down", actionDownLoad);//下载文件来实现它

    3.函数

     

    static bool avolfileHandler(Webs *wp)

     

    {

     

    WebsFileInfo    info;

     

    char            *tmp, *date;

     

    ssize           nchars;

     

    int             code;

     

     

     

    char *pathfilename; //带路径的文件名 

     

    char *filenameExt; //文件扩展名 

     

    char *filename; //下载后保存的文件名

     

    char *disposition; //临时保存 附件 标识

     

     

     

    assert(websValid(wp));//确保路径的正确性

     

    assert(wp->method);

     

    assert(wp->filename && wp->filename[0]);

     

     

     

    pathfilename = websGetVar(wp, "video", NULL);

     

    if (pathfilename==NULL)

     

    return 1;

     

     

     

    //取文件名和扩展名

     

    filename =sclone(getUrlLastSplit(sclone(pathfilename),"\"));

     

    filenameExt =sclone(getUrlLastSplit(sclone(filename),"."));

     

     

     

    if (wp->ext) wfree(wp->ext);

     

     

     

    wp->ext=walloc(1+strlen(filenameExt)+1);

     

    sprintf(wp->ext,".%s",sclone(filenameExt));

     

    free(filenameExt);

     

    filenameExt=NULL;

     

     

     

    if (wp->filename) wfree(wp->filename);

     

    wp->filename=sclone(pathfilename);

     

    if (wp->path) wfree(wp->path); 

     

    wp->path=sclone(pathfilename);

     

      

     

    #if !BIT_ROM

     

        if (smatch(wp->method, "DELETE")) {

     

            if (unlink(wp->filename) < 0) {

     

                websError(wp, HTTP_CODE_NOT_FOUND, "Can't delete the URI");

     

            } else {

     

                /* No content */

     

                websResponse(wp, 204, 0);

     

            }

     

        } else if (smatch(wp->method, "PUT")) {

     

            /* Code is already set for us by processContent() */

     

            websResponse(wp, wp->code, 0);

     

     

     

        } else

     

    #endif /* !BIT_ROM */

     

        {

     

            /*

     

                If the file is a directory, redirect using the nominated default page

     

             */

     

            if (websPageIsDirectory(wp)) {

     

                nchars = strlen(wp->path);

     

                if (wp->path[nchars - 1] == '/' || wp->path[nchars - 1] == '\') {

     

                    wp->path[--nchars] = '';

     

                }

     

                tmp = sfmt("%s/%s", wp->path, websIndex);

     

                websRedirect(wp, tmp);

     

                wfree(tmp);

     

                return 1;

     

            }

     

            if (websPageOpen(wp, O_RDONLY | O_BINARY, 0666) < 0) {

     

    #if BIT_DEBUG

     

                if (wp->referrer) {

     

                    trace(1, "From %s", wp->referrer);

     

                }

     

    #endif

     

                websError(wp, HTTP_CODE_NOT_FOUND, "Cannot open document for: %s", wp->path);

     

                return 1;

     

            }

     

            if (websPageStat(wp, &info) < 0) {

     

                websError(wp, HTTP_CODE_NOT_FOUND, "Cannot stat page for URL");

     

                return 1;

     

            }

     

            code = 200;

     

            if (wp->since && info.mtime <= wp->since) {

     

                code = 304;

     

            }

     

            websSetStatus(wp, code);

     

            websWriteHeaders(wp, info.size, 0);

     

     

     

    // 为了下载文件时保存为真正的文件名称

     

    disposition = walloc(20+strlen(filename)+1);

     

    sprintf(disposition,"attachment;filename=%s",sclone(filename));

     

    websWriteHeader(wp, "Content-Disposition", sclone(disposition));

     

    free(filename);

     

    free(disposition);

     

    filename=NULL;

     

    disposition=NULL;

     

     

     

            if ((date = websGetDateString(&info)) != NULL) {

     

                websWriteHeader(wp, "Last-modified", "%s", date);

     

                wfree(date);

     

            }

     

            websWriteEndHeaders(wp);

     

     

     

            /*

     

                All done if the browser did a HEAD request

     

             */

     

            if (smatch(wp->method, "HEAD")) {

     

                websDone(wp);

     

                return 1;

     

            }

     

            websSetBackgroundWriter(wp, fileWriteEvent);

     

        }

     

        return 1;

     

    }

     

    static void avolfileClose()

     

    {

     

    wfree(websIndex);

     

    websIndex = NULL;

     

    wfree(websDocuments);

     

    websDocuments = NULL;

     

    }

     

    //static WebsHash handlers = -1;

     

    static void actionDownLoad(Webs *wp, char *path, char *query)

     

    {

     

     

     

    (*wp).route->handler->close = (*avolfileClose);

     

    (*wp).route->handler->service =(*avolfileHandler);

     

    (*wp).route->handler->service(wp);

     

     

     

    }

     

     

     

     

     

    static void fileWriteEvent(Webs *wp)

     

    {

     

        char    *buf;

     

        ssize   len, wrote; 

     

        assert(wp);

     

        assert(websValid(wp));

     

        /*

     

            Note: websWriteSocket may return less than we wanted. It will return -1 on a socket error.

     

         */

     

        if ((buf = walloc(BIT_GOAHEAD_LIMIT_BUFFER)) == NULL) {

     

            websError(wp, HTTP_CODE_INTERNAL_SERVER_ERROR, "Can't get memory");

     

            return;

     

        }

     

        while ((len = websPageReadData(wp, buf, BIT_GOAHEAD_LIMIT_BUFFER)) > 0) {

     

            if ((wrote = websWriteSocket(wp, buf, len)) < 0) {

     

                break;

     

            }

     

            if (wrote != len) {

     

                websPageSeek(wp, - (len - wrote), SEEK_CUR);

     

                break;

     

            }

     

        }

     

        wfree(buf);

     

        if (len <= 0) {

     

            websDone(wp);

     

        }

     

    }

    在goahead-linux-static-me.h中添加上下面这部分代码

    #ifndef BIT_GOAHEAD_LIMIT_BUFFER

        #define BIT_GOAHEAD_LIMIT_BUFFER 8192

    #endif

     

    4.重新编译goahead,然后在终端中进入goahead可运行文件的目录,然后运行goahead。返回浏览器

    输入假设我们开启的是0.0.0.0:8080端口

     

    http://0.0.0.0:8080/action?video=/tmp/111.jpg    //  tmp是我们访问goahead的那个目录下的一个子目录

    111.jpg是我们要下载的文件

  • 相关阅读:
    算法总结——二分法(binary-search)
    Codeforces Round #296 (Div. 2)——B——Error Correct System
    Codeforces Round #296 (Div. 2)——A——Playing with Paper
    广工校赛——GCD,LCM——我是好人
    广工校赛——并查集——变形金刚
    广工校赛——DP——悦动达人
    广工校赛——slamdunk正在做菜
    广工校赛——LCS——完美串
    区间DP——石子合并问题
    贪心 Codeforces Round #109 (Div. 2) B. Combination
  • 原文地址:https://www.cnblogs.com/sun-tbs/p/9877052.html
Copyright © 2020-2023  润新知