static void http_header_base(struct evkeyvalq *headers, int last_modified) { char dbuf[80]; http_date(dbuf, sizeof(dbuf), tick); evhttp_add_header(headers, "Server", verstr_http); evhttp_add_header(headers, "Date", dbuf); if (last_modified) { http_date(dbuf, sizeof(dbuf), last_modified); evhttp_add_header(headers, "Last-Modified", dbuf); } }
static struct curl_slist * add_date_header_if_missing(struct curl_slist * headers) { if (!get_header(headers, "Date:", 5)) { char dateheader[36]; memset(dateheader, 0, sizeof(dateheader)); strcpy(dateheader, "Date: "); http_date(&dateheader[6], 30); headers = curl_slist_append(headers, dateheader); } return headers; }
bool connection_base::print_error(std::streambuf &buf, http_error const &http) const { std::ostream stream(&buf); stream << http_status(http.code()); stream << http_date(boost::posix_time::second_clock::universal_time()); stream << http_header::server(); stream << http_header::connection_close(); stream << http_header("Content-Type", "text/plain; charset=utf-8"); stream << http_constants<char>::endl; return true; }
U32 http_finfo (U8 *fname) { /* Read last modification time of a file. Return lm time in UTC format. */ FINFO *info; U32 utc; info = (FINFO *)alloc_mem (sizeof (FINFO)); info->fileID = 0; utc = 0; if (ffind ((const char *)fname, info) == 0) { /* File found, save creation date in UTC format. */ utc = http_date (&info->time); } free_mem ((OS_FRAME *)info); return (utc); }
void connection_base::print_common_headers(std::string const &content_type, std::streambuf &buf) const { std::ostream stream(&buf); stream << http_date(boost::posix_time::second_clock::universal_time()); stream << http_header::server(); stream << http_header("Content-Type", content_type.c_str()); if (headers_ && !headers_->empty()) { response_impl::headers_data_type::const_iterator it = headers_->begin(), end = headers_->end(); for (; it != end; ++it) { stream << http_header(it->first.c_str(), it->second.c_str()); } } }
/* if ( (r < 0) && (ERRNO == EAGAIN) ) goto sel_again; * / if ( r <= 0 ) return so; r = write(server_so, b, r);//, conf.time_out[HTTP]); if ( r <= 0 ) return server_so;// goto done; } } done: return -1; } */ inline static void analyze_header(char *p, struct server_answ *a) { char *t; // my_xlog(OOPS_LOG_HTTP|OOPS_LOG_DBG, "analyze_header(): ---> `%s'.\n", p); if ( !a->status_code ) { /* check HTTP/X.X XXX */ if ( !strncasecmp(p, "HTTP/", 5) ) { int httpv_major, httpv_minor; if ( sscanf(p+5, "%d.%d", &httpv_major, &httpv_minor) == 2 ) { a->httpv_major = httpv_major; a->httpv_minor = httpv_minor; } t = strchr(p, ' '); if ( !t ) { my_xlog(OOPS_LOG_NOTICE|OOPS_LOG_DBG|OOPS_LOG_INFORM, "analyze_header(): Wrong_header: %s\n", p); return; } a->status_code = atoi(t); my_xlog(OOPS_LOG_DBG, "analyze_header(): Status code: %d\n", a->status_code); } return; } if ( !strncasecmp(p, "Content-length: ", 16) ) { char *x; /* length */ x=p + 16; /* strlen("content-length: ") */ while( *x && IS_SPACE(*x) ) x++; a->content_len = atoi(x); return; } if ( !strncasecmp(p, "Date: ", 6) ) { char *x; /* length */ x=p + 6; /* strlen("date: ") */ while( *x && IS_SPACE(*x) ) x++; a->times.date = global_sec_timer; if (http_date(x, &a->times.date) ) my_xlog(OOPS_LOG_DBG|OOPS_LOG_INFORM, "analyze_header(): Can't parse date: %s\n", x); return; } if ( !strncasecmp(p, "Last-Modified: ", 15) ) { char *x; /* length */ x=p + 15; /* strlen("date: ") */ while( *x && IS_SPACE(*x) ) x++; if (http_date(x, &a->times.last_modified) ) my_xlog(OOPS_LOG_DBG|OOPS_LOG_INFORM, "analyze_header(): Can't parse date: %s\n", x); else a->flags |= ANSW_LAST_MODIFIED; return; } if ( !strncasecmp(p, "Pragma: ", 8) ) { char *x; /* length */ x=p + 8; /* strlen("Pragma: ") */ if ( strstr(x, "no-cache") ) a->flags |= ANSW_NO_STORE; return; } if ( !strncasecmp(p, "Age: ", 5) ) { char *x; /* length */ x=p + 5; /* strlen("Age: ") */ a->times.age = atoi(x); return; } if ( !strncasecmp(p, "Cache-Control: ", 15) ) { char *x; /* length */ x=p + 15; /* strlen("Cache-Control: ") */ while( *x && IS_SPACE(*x) ) x++; if ( strstr(x, "no-store") ) a->flags |= ANSW_NO_STORE; if ( strstr(x, "no-cache") ) a->flags |= ANSW_NO_STORE; if ( strstr(x, "private") ) a->flags |= ANSW_NO_STORE; if ( strstr(x, "must-revalidate") ) a->flags |= ANSW_MUST_REVALIDATE; if ( !strncasecmp(x, "proxy-revalidate", 15) ) a->flags |= ANSW_PROXY_REVALIDATE; if ( sscanf(x, "max-age = %d", (int*)&a->times.max_age) == 1 ) a->flags |= ANSW_HAS_MAX_AGE; } if ( !strncasecmp(p, "Connection: ", 12) ) { char *x; /* length */ x = p + 12; /* strlen("Connection: ") */ while( *x && IS_SPACE(*x) ) x++; if ( !strncasecmp(x, "keep-alive", 10) ) a->flags |= ANSW_KEEP_ALIVE; if ( !strncasecmp(x, "close", 5) ) a->flags &= ~ANSW_KEEP_ALIVE; } if ( !TEST(a->flags, ANSW_HAS_EXPIRES) && !strncasecmp(p, "Expires: ", 9) ) { char *x; /* length */ x = p + 9; /* strlen("Expires: ") */ while( *x && IS_SPACE(*x) ) x++; a->times.expires = time(NULL); if (http_date(x, &a->times.expires)) { my_xlog(OOPS_LOG_DBG|OOPS_LOG_INFORM, "analyze_header(): Can't parse date: %s\n", x); return; } a->flags |= ANSW_HAS_EXPIRES; return; } }
static void http_route_static(struct evhttp_request *r, const char *uri) { struct http_static_t *cmdp; struct stat st; char fname[HTTP_FNAME_LEN]; char last_modified[128]; char *contenttype; int fd; int file_size; char *buf; struct evkeyvalq *req_headers; const char *ims; for (cmdp = http_static_files; cmdp->name != NULL; cmdp++) if (strcmp(cmdp->name, uri) == 0) break; if (cmdp->name == NULL) { hlog(LOG_DEBUG, "HTTP: 404"); evhttp_send_error(r, HTTP_NOTFOUND, "Not found"); return; } snprintf(fname, HTTP_FNAME_LEN, "%s/%s", webdir, cmdp->filename); //hlog(LOG_DEBUG, "static file request %s", uri); fd = open(fname, 0, O_RDONLY); if (fd < 0) { if (errno == ENOENT) { /* don't complain about missing motd.html - it's optional. */ int level = LOG_ERR; if (strcmp(cmdp->filename, "motd.html") == 0) level = LOG_DEBUG; hlog(level, "http static file '%s' not found", fname); evhttp_send_error(r, HTTP_NOTFOUND, "Not found"); return; } hlog(LOG_ERR, "http static file '%s' could not be opened for reading: %s", fname, strerror(errno)); evhttp_send_error(r, HTTP_INTERNAL, "Could not access file"); return; } if (fstat(fd, &st) == -1) { hlog(LOG_ERR, "http static file '%s' could not fstat() after opening: %s", fname, strerror(errno)); evhttp_send_error(r, HTTP_INTERNAL, "Could not access file"); if (close(fd) < 0) hlog(LOG_ERR, "http static file '%s' could not be closed after failed stat: %s", fname, strerror(errno)); return; } http_date(last_modified, sizeof(last_modified), st.st_mtime); contenttype = http_content_type(cmdp->filename); //hlog(LOG_DEBUG, "found content-type %s", contenttype); struct evkeyvalq *headers = evhttp_request_get_output_headers(r); http_header_base(headers, st.st_mtime); evhttp_add_header(headers, "Content-Type", contenttype); /* Consider an IMS hit */ req_headers = evhttp_request_get_input_headers(r); ims = evhttp_find_header(req_headers, "If-Modified-Since"); if ((ims) && strcasecmp(ims, last_modified) == 0) { hlog(LOG_DEBUG, "http static file '%s' IMS hit", fname); evhttp_send_reply(r, HTTP_NOTMODIFIED, "Not modified", NULL); if (close(fd) < 0) hlog(LOG_ERR, "http static file '%s' could not be closed after failed stat: %s", fname, strerror(errno)); return; } file_size = st.st_size; /* yes, we are not going to serve large files. */ buf = hmalloc(file_size); int n = read(fd, buf, file_size); if (close(fd) < 0) { hlog(LOG_ERR, "http static file '%s' could not be closed after reading: %s", fname, strerror(errno)); evhttp_send_error(r, HTTP_INTERNAL, "Could not access file"); hfree(buf); return; } if (n != file_size) { hlog(LOG_ERR, "http static file '%s' could only read %d of %d bytes", fname, n, file_size); evhttp_send_error(r, HTTP_INTERNAL, "Could not access file"); hfree(buf); return; } int allow_compress; if (strncmp(contenttype, "image/", 6) == 0) allow_compress = 0; else allow_compress = 1; http_send_reply_ok(r, headers, buf, n, allow_compress); hfree(buf); }
/* * We have a connection. Identify what type of request GET, HEAD, CGI, etc * and do what needs to be done */ void http_request(void) { int fd, lg, i; int cmd = 0; char *p, *par; const char *filename, *c, *ext, *type; struct stat file_status; char req[1024]; char buff[8192]; lg = read(con_sock, req, 1024); if ((p=strstr(req,"\n"))) *p=0; if ((p=strstr(req,"\r"))) *p=0; log_line(req); c = strtok(req, " "); /* Error msg if request is nothing */ if (c == NULL) { http_output(http_404[0]); http_output(http_404[1]); goto end_request; } if (strncmp(c, "GET", 3) == 0) cmd = 1; if (strncmp(c, "HEAD", 4) == 0) cmd = 2; /* Do error msg for any other type of request */ if (cmd == 0) { http_output(http_405[0]); http_output(http_405[1]); goto end_request; } filename = strtok(NULL, " "); c = strtok(NULL, " "); if (fetch_mode != NULL) filename=fetch_mode; if (filename == NULL || strlen(filename)==1) filename="/index.html"; while (filename[0]== '/') filename++; /* CGI handling. Untested */ if (!strncmp(filename,"cgi-bin/",8)) { par=0; if ((par=strstr(filename,"?"))) { *par=0; par++; } if (access(filename,X_OK)) goto conti; stat (filename,&file_status); if (setuid(file_status.st_uid)) return; if (seteuid(file_status.st_uid)) return; if (!fork()) { close(1); dup(con_sock); /*printf("HTTP/1.0 200 OK\nContent-type: text/html\n\n\n");*/ printf("HTTP/1.0 200 OK\r\n"); /* Plug in environment variable, others in log_line */ setenv("SERVER_SOFTWARE", "FreeBSD/PicoBSD", 1); execlp (filename,filename,par,(char *)0); } wait(&i); return; } conti: if (filename == NULL) { http_output(http_405[0]); http_output(http_405[1]); goto end_request; } /* End of CGI handling */ /* Reject any request with '..' in it, bad hacker */ c = filename; while (*c != '\0') if (c[0] == '.' && c[1] == '.') { http_output(http_404[0]); http_output(http_404[1]); goto end_request; } else c++; /* Open filename */ fd = open(filename, O_RDONLY); if (fd < 0) { http_output(http_404[0]); http_output(http_404[1]); goto end_request; } /* Get file status information */ if (fstat(fd, &file_status) < 0) { http_output(http_404[0]); http_output(http_404[1]); goto end_request2; } /* Is it a regular file? */ if (!S_ISREG(file_status.st_mode)) { http_output(http_404[0]); http_output(http_404[1]); goto end_request2; } /* Past this point we are serving either a GET or HEAD */ /* Print all the header info */ http_output(http_200); http_output(httpd_server_ident); http_date(); sprintf(buff, "Content-length: %jd\r\n", (intmax_t)file_status.st_size); write(con_sock, buff, strlen(buff)); strcpy(buff, "Content-type: "); type = default_mime_type; if ((ext = strrchr(filename, '.')) != NULL) { for (i = mime_type_max; i >= 0; i--) if (strcmp(ext + 1, mime_type[i][0]) == 0) { type = mime_type[i][1]; break; } } strcat(buff, type); http_output(buff); strftime(buff, 50, "Last-Modified: %a, %d %h %Y %H:%M:%S %Z\r\n\r\n", gmtime(&file_status.st_mtime)); write(con_sock, buff, strlen(buff)); /* Send data only if GET request */ if (cmd == 1) { while ((lg = read(fd, buff, 8192)) > 0) write(con_sock, buff, lg); } end_request2: close(fd); end_request: close(con_sock); }