通过HTTP发送文件

我在服务器的本地文件系统上设置了一个包含文件(我们称之为hello_world.txt)的服务器,例如/home/yak/hello_world.txt

我想通过HTTP请求来检索该文件。 不只是打印文件的内容,而是发送实际的文件。

在一本关于Apache模块开发的书中,我已经find了一个非常基本的模块的教程来做到这一点 – 这是代码的结果:

 /* * A module that delivers a file */ #include <httpd.h> #include <http_protocol.h> #include <http_config.h> #include <http_log.h> #include <apr_time.h> /* The handler that will actually process the request */ static int file_delivery_handler(request_rec *r) { apr_file_t *file; apr_size_t size; apr_status_t rv; /* * Checks to ensure that this request is for this module */ /* If this isn't the handler for this request, decline */ if(!r->handler || (strcmp(r->handler, "file_delivery") != 0)) { return DECLINED; } /* If this is not a GET request, return the appropriate HTTP response */ if(r->method_number != M_GET) { return HTTP_METHOD_NOT_ALLOWED; } /* * If the file name and info are not set in the request, * then this is an error */ if(r->filename==NULL) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "No file info"); return HTTP_INTERNAL_SERVER_ERROR; } /* Set the desired content type */ ap_set_content_type(r, "text/html;charset=ascii"); /* Set the content length */ ap_set_content_length(r, r->finfo.size); /* Provide timestamp of last modification in response header */ if(r->finfo.mtime) { char *datestring = apr_palloc(r->pool, APR_RFC822_DATE_LEN); apr_rfc822_date(datestring, r->finfo.mtime); apr_table_setn(r->headers_out, "Last Modified", datestring); } /* Open the file */ rv=apr_file_open(&file, r->filename, APR_READ|APR_SHARELOCK|APR_SENDFILE_ENABLED, APR_OS_DEFAULT, r->pool); if(rv != APR_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Cannot open %s", r->filename); return HTTP_NOT_FOUND; } /* Send the file */ ap_send_fd(file, r, 0, r->finfo.size, &size); ap_rputs("I sent a file!", r); /* * Note that because the file is associated with the request pool (by * the apr_file_open function) there is no need to close it. When the * request is finished, the pool will take care of closing the file. */ return OK; } /* The function that registers the hooks for request processing */ static void register_hooks(apr_pool_t *p) { ap_hook_handler(file_delivery_handler, NULL, NULL, APR_HOOK_MIDDLE); } /* This section declares the module */ module AP_MODULE_DECLARE_DATA file_delivery_module = { STANDARD20_MODULE_STUFF, NULL, NULL, NULL, NULL, NULL, register_hooks }; 

而在httpd.conf文件中,我有:

 LoadModule file_delivery_module /path/to/module.so <Location /get_file> SetHandler "file_delivery" </Location> 

现在,只要inputhttp://myipaddress:port/get_file就会显示“我发送了一个文件!” 只有当我注释掉试图打开和发送文件的部分。 否则,我得到一个404 not found页面,就像我提供了一个无效的文件名。

这里的问题是,我input的URL,我没有提供一个文件名,所以为什么我不能看到HTTP_INTERNAL_SERVER_ERROR的错误文档?

我相信问题是我不知道如何提供我想要检索的文件名,除了像这样的URL的一部分通常的方式:

HTTP:// myipaddress:端口/path/到/文件

但是这只有在文件位于服务器的文档根目录下时才起作用,并且实际上并不发送文件,只是显示它的内容。

我没有看到HTTP文档中的任何内容,在过去的几天中我一直在关注这些内容,我觉得我错过了一些基本的信息,这本书必须考虑明显或超出范围,因为它没有甚至显示正在使用的模块的示例。