static void http_verify_path(WEBBLK *webblk, char *path) { char resolved_path[HTTP_PATH_LENGTH]; char pathname[HTTP_PATH_LENGTH]; #if 0 int i; for (i = 0; path[i]; i++) if (!isalnum((int)path[i]) && !strchr("/.-_", path[i])) http_error(webblk, "404 File Not Found","", "Illegal character in filename"); #endif if (!realpath( path, resolved_path )) http_error(webblk, "404 File Not Found","", "Invalid pathname"); hostpath(pathname, resolved_path, sizeof(pathname)); // The following verifies the specified file does not lie // outside the specified httproot (Note: http_serv.httproot // was previously resolved to an absolute path by config.c) if (strncmp( http_serv.httproot, pathname, strlen(http_serv.httproot))) http_error(webblk, "404 File Not Found","", "Invalid pathname"); }
/* parse one line of header input */ NTSTATUS http_parse_header(struct websrv_context *web, const char *line) { if (line[0] == 0) { web->input.end_of_headers = true; } else if (strncasecmp(line,"GET ", 4)==0) { web->input.url = talloc_strndup(web, &line[4], strcspn(&line[4], " \t")); } else if (strncasecmp(line,"POST ", 5)==0) { web->input.post_request = true; web->input.url = talloc_strndup(web, &line[5], strcspn(&line[5], " \t")); } else if (strchr(line, ':') == NULL) { http_error(web, "400 Bad request", "This server only accepts GET and POST requests"); return NT_STATUS_INVALID_PARAMETER; } else if (strncasecmp(line, "Content-Length: ", 16)==0) { web->input.content_length = strtoul(&line[16], NULL, 10); } else { struct http_header *hdr = talloc_zero(web, struct http_header); char *colon = strchr(line, ':'); if (colon == NULL) { http_error(web, "500 Internal Server Error", "invalidly formatted header"); return NT_STATUS_INVALID_PARAMETER; } hdr->name = talloc_strndup(hdr, line, colon-line); hdr->value = talloc_strdup(hdr, colon+1); DLIST_ADD(web->input.headers, hdr); } /* ignore all other headers for now */ return NT_STATUS_OK; }
/* DDS3.2.6: Get Rotation */ void get_rotation(const struct electorate *elec) { struct http_vars *reply; unsigned int i; char ecodestr[INT_CHARS]; struct http_vars request[] = { { (char*)"ecode", ecodestr }, { NULL, NULL } }; sprintf(ecodestr, "%u", elec->code); reply = http_exchange(SERVER_ADDRESS, SERVER_PORT, ROBSON_CGI,request); if (!reply) display_error(ERR_SERVER_UNREACHABLE); /* Some error occurred? */ if (http_error(reply)) display_error(http_error(reply)); for (i = 0; i < elec->num_seats; i++) { char varname[strlen("rotation") + sizeof(STRINGIZE(MAX_ELECTORATE_SEATS))]; const char *val; sprintf(varname, "rotation%u", i); val = http_string(reply, varname); current_rotation.rotations[i] = atoi(val); assert(current_rotation.rotations[i] < elec->num_seats); } /* DDS3.2.6: Save Rotation */ current_rotation.size = elec->num_seats; http_free(reply); }
int http_request(int fd) { int file; struct stat file_stat; char buffer[DEFAULT_BUFFER_SIZE] ={0}; char method[32] ={0}; char version[32] ={0}; // ignore char uri[DEFAULT_BUFFER_SIZE] = {0}; char path[DEFAULT_BUFFER_SIZE] = {0}; //char cgiargs[DEFAULT_BUFFER_SIZE]; if (read_method(fd, buffer, sizeof buffer) < 0) { http_error(fd, hst_bad_request); return -1; } //printf("first line : %s\n", buffer); sscanf(buffer, "%s %s %s", method, uri, version); if (strcasecmp(method, method_GET) != 0) { http_error(fd, hst_no_implemented); return -1; } printf("mathod is GET, uri is %s\n", uri); read_headers(fd, buffer, sizeof buffer); // ignore all hreaders //printf("DEBUG\n"); if (parse_uri(uri, path) < 0) { http_error(fd, hst_not_found); return -1; } printf("file path is %s\n", path); if (stat(path, &file_stat) < 0) { http_error(fd, hst_not_found); return -1; } if((file = open(path, O_RDONLY)) < 0) { http_error(fd, hst_uknown); return -1; } if(send_file(fd, file) < 0){ return -1; } return 0; }
static int hc_image(http_connection_t *hc, const char *remain, void *opaque, http_cmd_t method) { htsbuf_queue_t out; pixmap_t *pm; char errbuf[200]; const char *content; image_meta_t im = {0}; im.im_no_decoding = 1; rstr_t *url = rstr_alloc(remain); pm = backend_imageloader(url, &im, NULL, errbuf, sizeof(errbuf), NULL, NULL, NULL); rstr_release(url); if(pm == NULL) return http_error(hc, 404, "Unable to load image %s : %s", remain, errbuf); if(!pixmap_is_coded(pm)) { pixmap_release(pm); return http_error(hc, 404, "Unable to load image %s : Original data not available", remain); } htsbuf_queue_init(&out, 0); htsbuf_append(&out, pm->pm_data, pm->pm_size); switch(pm->pm_type) { case PIXMAP_JPEG: content = "image/jpeg"; break; case PIXMAP_PNG: content = "image/png"; break; case PIXMAP_GIF: content = "image/gif"; break; default: content = "image"; break; } pixmap_release(pm); return http_send_reply(hc, 0, content, NULL, NULL, 0, &out); }
/* * Handles a HTTP request. */ void http_handle_request(socket_t s, const struct http_request_s *request) { http_buffer_t content = http_lookup_content(request->name); if (content == NULL) { http_error(s, 404, request); return; } bool success = http_send_response(s, 200, content, request); http_buffer_close(content); if (!success) { http_error(s, 500, request); } }
int http_show_dir(int client, char *filepath) { DIR *dp; struct dirent *dirp; struct stat st; struct passwd *filepasswd; int num = 1; char files[MAXLINE], buf[MAXLINE], name[LINE], img[LINE], mtime[LINE], dir[LINE]; char *p; p = strrchr(filepath, '/'); ++p; strcpy(dir, p); strcat(dir, "/"); if ((dp =opendir(filepath))== NULL){ http_error(client); return -1; } sprintf (files, "<HTML><TITLE>Dir Browser</TITLE>"); sprintf (files, "%s<style type = ""text/css""> a:link{text-decoration:none;} </style>", files); sprintf (files, "%s<body bgcolor=""ffffff"" font-family=Arial color=#fff font-size=14px}\r\n", files); while ((dirp=readdir(dp))!=NULL){ if (strcmp(dirp->d_name, ".") == 0 || strcmp(dirp->d_name, "..")==0) continue; sprintf (name, "%s/%s", filepath, dirp->d_name); stat(name, &st); filepasswd = getpwuid(st.st_uid); if (S_ISDIR(st.st_mode)) sprintf (img, "<img src=""dir.png"" width=""24px"" height=""24px"">"); else if(S_ISFIFO(st.st_mode)) sprintf (img, "<img src=""fifo.png"" width=""24px"" height=""24px"">"); else if (S_ISLNK(st.st_mode)) sprintf (img, "<img src=""link.png"" width=""24px"" height=""24px"">"); else if (S_ISSOCK(st.st_mode)) sprintf (img, "<img src=""sock.png"" width=""24px"" height=""24px"">"); else sprintf (img, "<img src=""file.png"" width=""24px"" height=""24px"">"); sprintf (files, "%s<p><pre>%-2d %s ""<a href=%s%s"">%-15s</a>%-10s%10d %24s</pre></p>\r\n", files, num++, img, dir, dirp->d_name, dirp->d_name, filepasswd->pw_name, (int)st.st_size, tmmodify(st.st_mode, mtime)); } closedir(dp); sprintf (files, "%s</BODY></HTML>", files); sprintf (buf, "HTTP/1.0 200 OK \r\n"); sprintf (buf, "%sServer: "SERVER"\r\n", buf); sprintf (buf, "%sContent-length: %ld\r\n", buf, strlen(files)); sprintf (buf, "%sContent-type: text/html\r\n", buf); sprintf (buf, "%s\r\n", buf); http_send(client, buf); http_send(client, files); return 0; }
int main(int ac, char **av) { char buf[200]; char url[200]; int status; char *sFrontpage = "/usr/local/lib/rman/http-rman.html"; /* check arguments */ if (ac > 1) sFrontpage = av[1]; /* just read in one line from stdin and make sure it is a GET command */ if (gets(buf)) { /* read rest of command (just for the sake of it) */ while (gets(url) && url[0] != '\r') ; /* command should be GET <url> [HTTP/1.0] */ if (sscanf(buf, "GET %s", url) == 1) { status = http_rman(url); if (status < 0) { sprintf(buf, "cat %s", sFrontpage); if (system(buf) == 0) status = 0; } if (status < 0) http_error(404); } else http_error(400); } fflush(stdout); exit(0); }
static void http_download(WEBBLK *webblk, char *filename) { char buffer[HTTP_PATH_LENGTH]; char tbuf[80]; int fd, length; char *filetype; char fullname[HTTP_PATH_LENGTH]; struct stat st; MIMETAB *mime_type = mime_types; strlcpy( fullname, http_serv.httproot, sizeof(fullname) ); strlcat( fullname, filename, sizeof(fullname) ); http_verify_path(webblk,fullname); if(stat(fullname,&st)) http_error(webblk, "404 File Not Found","", strerror(errno)); if(!S_ISREG(st.st_mode)) http_error(webblk, "404 File Not Found","", "The requested file is not a regular file"); fd = HOPEN(fullname,O_RDONLY|O_BINARY,0); if (fd == -1) http_error(webblk, "404 File Not Found","", strerror(errno)); hprintf(webblk->sock,"HTTP/1.0 200 OK\n"); if ((filetype = strrchr(filename,'.'))) for(mime_type++;mime_type->suffix && strcasecmp(mime_type->suffix,filetype + 1); mime_type++); if(mime_type->type) hprintf(webblk->sock,"Content-Type: %s\n", mime_type->type); hprintf(webblk->sock,"Expires: %s\n", http_timestring(tbuf,sizeof(tbuf),time(NULL)+HTML_STATIC_EXPIRY_TIME)); hprintf(webblk->sock,"Content-Length: %d\n\n", (int)st.st_size); while ((length = read(fd, buffer, sizeof(buffer))) > 0) hwrite(webblk->sock,buffer, length); close(fd); http_exit(webblk); }
/* Send body of HTTP error message */ int send_http_code_body(t_session *session) { char ecode[5], len[10]; const char *emesg; size_t ecode_len, emesg_len; ecode[4] = '\0'; snprintf(ecode, 4, "%d", session->return_code); ecode_len = strlen(ecode); if ((emesg = http_error(session->return_code)) == NULL) { emesg = unknown_http_code; } emesg_len = strlen(emesg); len[9] = '\0'; snprintf(len, 9, "%d", (int)((2 * emesg_len) + (2 * ecode_len) + 3 + ec_doctype_len + ec_head_len + ec_body1_len + ec_body2_len + ec_tail_len)); if (send_buffer(session, hs_conlen, 16) == -1) { return -1; } else if (send_buffer(session, len, strlen(len)) == -1) { return -1; } else if (send_buffer(session, "\r\n", 2) == -1) { return -1; } else if (send_buffer(session, hs_contyp, 14) == -1) { return -1; } else if (send_buffer(session, "text/html\r\n\r\n", 13) == -1) { return -1; } session->header_sent = true; if (session->request_method == HEAD) { return 0; } if (send_buffer(session, ec_doctype, ec_doctype_len) == -1) { return -1; } else if (send_buffer(session, ec_head, ec_head_len) == -1) { return -1; } else if (send_buffer(session, ecode, ecode_len) == -1) { return -1; } else if (send_buffer(session, " - ", 3) == -1) { return -1; } else if (send_buffer(session, emesg, emesg_len) == -1) { return -1; } else if (send_buffer(session, ec_body1, ec_body1_len) == -1) { return -1; } else if (send_buffer(session, emesg, emesg_len) == -1) { return -1; } else if (send_buffer(session, ec_body2, ec_body2_len) == -1) { return -1; } else if (send_buffer(session, ecode, ecode_len) == -1) { return -1; } else if (send_buffer(session, ec_tail, ec_tail_len) == -1) { return -1; } return 0; }
PHP_HTTP_API STATUS _http_start_ob_etaghandler(TSRMLS_D) { /* already running? */ if (php_ob_handler_used("ob_etaghandler" TSRMLS_CC)) { http_error(HE_WARNING, HTTP_E_RUNTIME, "ob_etaghandler can only be used once"); return FAILURE; } HTTP_G->etag.started = 1; return php_start_ob_buffer_named("ob_etaghandler", HTTP_G->send.buffer_size, 0 TSRMLS_CC); }
static int read_request(int fd, struct request *req) { memset(req->buf, 0, sizeof(req->buf)); while(1) { ssize_t n; n = read(fd, req->buf + req->buf_i, sizeof(req->buf) - req->buf_i); if(n < 0) { syslog(LOG_ERR, "read: %m"); return -1; } req->buf_i += n; if(memmem(req->buf, req->buf_i, "\r\n\r\n", 4)) return 0; if(req->buf_i >= 6) { // Search for an HTTP/0.9 request if(strncmp("GET ", req->buf, 4) == 0) { int i; for(i = 5; i < req->buf_i; i++) { if(req->buf[i] == ' ' || req->buf[i] == '\r' || req->buf[i] == '\n') break; } if(req->buf[i] == '\r' || req->buf[i] == '\n') return 0; } } if(req->buf_i == sizeof(req->buf)) { if(memmem(req->buf, req->buf_i, "\r\n", 2)) http_error(fd, 414, "HTTP/1.0"); else http_error(fd, 413, "HTTP/1.0"); return -1; } if(n == 0) { http_error(fd, 400, "HTTP/1.0"); return -1; } } }
PHP_HTTP_API STATUS _http_start_ob_etaghandler(TSRMLS_D) { /* already running? */ #ifdef PHP_OUTPUT_NEWAPI STATUS rv; if (php_output_handler_conflict(ZEND_STRL("ob_etaghandler"), ZEND_STRL("ob_etaghandler") TSRMLS_CC)) { return FAILURE; } #else if (php_ob_handler_used("ob_etaghandler" TSRMLS_CC)) { http_error(HE_WARNING, HTTP_E_RUNTIME, "ob_etaghandler can only be used once"); return FAILURE; } #endif HTTP_G->etag.started = 1; #ifdef PHP_OUTPUT_NEWAPI return php_output_start_internal(ZEND_STRL("ob_etaghandler"), _http_ob_etaghandler, HTTP_G->send.buffer_size, 0 TSRMLS_CC); #else return php_start_ob_buffer_named("ob_etaghandler", HTTP_G->send.buffer_size, 0 TSRMLS_CC); #endif }
static inline void _http_send_response_data_plain(void **buffer, const char *data, size_t data_len TSRMLS_DC) { if (HTTP_G->send.deflate.response && HTTP_G->send.deflate.encoding) { #ifdef HTTP_HAVE_ZLIB char *encoded; size_t encoded_len; http_encoding_stream *s = *((http_encoding_stream **) buffer); http_encoding_deflate_stream_update(s, data, data_len, &encoded, &encoded_len); if (HTTP_G->send.buffer_size) { phpstr_chunked_output((phpstr **) &s->storage, encoded, encoded_len, HTTP_G->send.buffer_size, _http_flush, NULL TSRMLS_CC); } else { http_flush(encoded, encoded_len); } efree(encoded); #else http_error(HE_ERROR, HTTP_E_RESPONSE, "Attempt to send GZIP response despite being able to do so; please report this bug"); #endif } else if (HTTP_G->send.buffer_size) { phpstr_chunked_output((phpstr **) buffer, data, data_len, HTTP_G->send.buffer_size, _http_flush, NULL TSRMLS_CC); } else { http_flush(data, data_len); } }
static void work_http( connection* conn ) { int i; virtual_host * host; //check if the connection cannot work. if( conn->state != C_READY ) return; conn->state = C_REQUESTING; http_request( conn ); if( conn->state != C_REQUESTING ) return; //response conn->code = 200; conn->state = C_RESPONSING; /* Check Host and then set root directory. */ host = loop_search( &conn->server->loop_vhost, conn->host, vhost_searcher ); if( !host ){ host = loop_search( &conn->server->loop_vhost, "*", vhost_searcher ); } if( host ){ //read root conn->root_dir = host->root_dir; if( !loop_is_empty( &host->loop_rewrite ) ) loop_search( &host->loop_rewrite, (void*)conn, loop_rewrite_match ); http_parse_uri( conn ); DBG("[%s]%s%s", conn->client->ip_string, conn->host, conn->uri ); _RESPONSE: http_parse_path( conn ); conn->document_type = http_doctype( conn->server, conn->extension ); if( !conn->document_type ){ http_error( conn, 404, "<h1>File not found.</h1>" ); }else if( conn->extension[0] && strstr( conn->server->asp_exts, conn->extension ) ) { //php do ... exec_asp( conn ); }else if( host->proxy && ( !host->proxy_exts[0] || strstr( host->proxy_exts, conn->extension ) ) ) { // uses proxy server proxy_request( conn, host->proxy_ip, host->proxy_port ); }else if( access(conn->full_path, 0)==0 ){ if( is_dir(conn->full_path) ){ char* tmp; NEW( tmp, PATH_LEN+32 ); if( conn->script_name[strlen(conn->script_name)-1] != '/' ){ //Are you sure that script starts with '/'? sprintf( tmp, "http://%s%s/", conn->host, conn->script_name ); http_redirect( conn, tmp ); }else{ if( tmp ){ for( i = 0; i<10; i++ ) { if( !conn->server->default_pages[i][0] ) { i=10; break; } sprintf( tmp, "%s/%s", conn->full_path, conn->server->default_pages[i] ); if( access( tmp, 0 ) == 0 ) { //091004 by Huang Guan. sprintf( conn->script_name, "%s%s", conn->script_name, conn->server->default_pages[i] ); DEL( tmp ); goto _RESPONSE; } } } if( i == 10 ){ // List Directory if( host->list ){ int ret; NEW( conn->data_send, MAX_DATASEND+4 ); strcpy( conn->extension, "html" ); conn->document_type = http_doctype( conn->server, conn->extension ); ret = listdir( conn->data_send, MAX_DATASEND, conn->full_path, conn->script_name ); conn->data_size = ret; }else{ http_error( conn, 403, "<h1>Forbidden</h1>" ); } } } DEL( tmp ); }else{ http_sendfile( conn, conn->full_path ); } }else if( strncmp(conn->current_dir, "/system", 7)==0 && conn->root_dir==host->root_dir ){ strcpy(conn->script_name, conn->script_name+7); conn->root_dir = conn->client->server->root_dir; goto _RESPONSE; }else{ http_error( conn, 404, "<h1>File not found.</h1>" ); } }else{ http_error( conn, 403, "<h1>Unknown host name.</h1>" ); } if( conn->state == C_RESPONSING ) http_response( conn ); conn->requests ++; if( conn->form_data ) DEL( conn->form_data ); if( conn->data_send ) DEL( conn->data_send ); if( conn->session ) conn->session->reference --; conn->session = NULL; //next request if( conn->keep_alive ){ conn->state = C_READY; }else{ conn->state = C_END; } }
int soap_fresponse(struct soap *soap, int status, size_t count) { //int err; //std::cout << "DEBUG soap_fresponse" << std::endl; //if ((err = soap->fposthdr(soap, "Access-Control-Allow-Origin", "*"))) // return err; //if ((err = soap->fposthdr(soap, "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, CONNECT"))) // return err; //if ((err = soap->fposthdr(soap, "Access-Control-Allow-Headers", "X-Requested-With, Content-Type"))) // return err; //if ((err = soap->fposthdr(soap, "Access-Control-Allow-Credentials", "true"))) // return err; //int ret = old_freponse(soap, soap_error_code, count); //return ret; std::cout << "debug status=" << status << std::endl; status = 200; register int err; #ifdef WMW_RPM_IO if (soap->rpmreqid) httpOutputEnable(soap->rpmreqid); #endif if (strlen(soap->http_version) > 4) return soap->error = SOAP_EOM; if (!status || status == SOAP_HTML || status == SOAP_FILE) { const char *s; if (count || ((soap->omode & SOAP_IO) == SOAP_IO_CHUNK)) s = "200 OK"; else s = "202 ACCEPTED"; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Status = %s\n", s)); #ifdef WMW_RPM_IO if (soap->rpmreqid || soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* RPM behaves as if standalone */ #else if (soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* standalone application (socket) or CGI (stdin/out)? */ #endif { sprintf(soap->tmpbuf, "HTTP/%s %s", soap->http_version, s); if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL))) return err; } else if ((err = soap->fposthdr(soap, "Status", s))) /* CGI header */ return err; } else if (status >= 200 && status < 600) { sprintf(soap->tmpbuf, "HTTP/%s %d %s", soap->http_version, status, http_error(soap, status)); if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL))) return err; #ifndef WITH_LEAN if (status == 401) { sprintf(soap->tmpbuf, "Basic realm=\"%s\"", (soap->authrealm && strlen(soap->authrealm) < sizeof(soap->tmpbuf) - 14) ? soap->authrealm : "gSOAP Web Service"); if ((err = soap->fposthdr(soap, "WWW-Authenticate", soap->tmpbuf))) return err; } else if ((status >= 301 && status <= 303) || status == 307) { if ((err = soap->fposthdr(soap, "Location", soap->endpoint))) return err; } #endif } else { const char *s = *soap_faultcode(soap); //std::cout << "DEBUG status=" << status << std::endl; //std::cout << "DEBUG SOAP_GET_METHOD=" << SOAP_GET_METHOD << std::endl; //std::cout << "DEBUG SOAP_HTTP_METHOD=" << SOAP_HTTP_METHOD << std::endl; if (status >= SOAP_GET_METHOD && status <= SOAP_HTTP_METHOD) s = "405 Method Not Allowed"; else if (soap->version == 2 && (!s || !strcmp(s, "SOAP-ENV:Sender"))) s = "400 Bad Request"; else s = "500 Internal Server Error"; DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Error %s (status=%d)\n", s, status)); #ifdef WMW_RPM_IO if (soap->rpmreqid || soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* RPM behaves as if standalone */ #else if (soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* standalone application */ #endif { sprintf(soap->tmpbuf, "HTTP/%s %s", soap->http_version, s); if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL))) return err; } else if ((err = soap->fposthdr(soap, "Status", s))) /* CGI */ return err; } if ((err = soap->fposthdr(soap, "Server", "gSOAP/2.7")) || (err = soap_puthttphdr(soap, status, count))) return err; #ifdef WITH_COOKIES if (soap_putsetcookies(soap)) return soap->error; #endif //if ((err = soap->fposthdr(soap, "Access-Control-Allow-Origin", "*"))) // return err; //if ((err = soap->fposthdr(soap, "Access-Control-Allow-Credentials", "true"))) // return err; //if ((err = soap->fposthdr(soap, "Access-Control-Allow-Headers", "origin,x-requested-with,access-control-request-headers,content-type,access-control-request-method,accept"))) // return err; //if ((err = soap->fposthdr(soap, "Access-Control-Allow-Methods", "POST,HEAD,GET,PUT,DELETE,OPTIONS"))) // return err; //if ((err = soap->fposthdr(soap, "Allow", "HEAD,GET,PUT,DELETE,OPTIONS"))) // return err; return soap->fposthdr(soap, NULL, NULL); }
static void *http_request(void* arg) { WEBBLK *webblk; int authok = !http_serv.httpauth; char line[HTTP_PATH_LENGTH]; char *url = NULL; char *pointer; char *strtok_str = NULL; CGITAB *cgient; int content_length = 0; int sock = (int) (uintptr_t) arg; if(!(webblk = malloc(sizeof(WEBBLK)))) http_exit(webblk); memset(webblk,0,sizeof(WEBBLK)); webblk->sock = sock; while (hgets(line, sizeof(line), webblk->sock)) { if (*line == '\r' || *line == '\n') break; if((pointer = strtok_r(line," \t\r\n",&strtok_str))) { if(!strcasecmp(pointer,"GET")) { if((pointer = strtok_r(NULL," \t\r\n",&strtok_str))) { webblk->request_type = REQTYPE_GET; url = strdup(pointer); } } else if(!strcasecmp(pointer,"POST")) { if((pointer = strtok_r(NULL," \t\r\n",&strtok_str))) { webblk->request_type = REQTYPE_POST; url = strdup(pointer); } } else if(!strcasecmp(pointer,"PUT")) { http_error(webblk,"400 Bad Request", "", "This server does not accept PUT requests"); } else if(!strcasecmp(pointer,"Authorization:")) { if((pointer = strtok_r(NULL," \t\r\n",&strtok_str))) authok = http_authenticate(webblk,pointer, strtok_r(NULL," \t\r\n",&strtok_str)); } else if(!strcasecmp(pointer,"Cookie:")) { if((pointer = strtok_r(NULL,"\r\n",&strtok_str))) http_interpret_variable_string(webblk, pointer, VARTYPE_COOKIE); } else if(!strcasecmp(pointer,"Content-Length:")) { if((pointer = strtok_r(NULL," \t\r\n",&strtok_str))) content_length = atoi(pointer); } } } webblk->request = url; if(webblk->request_type == REQTYPE_POST && content_length != 0) { char *post_arg; if((pointer = post_arg = malloc(content_length + 1))) { int i; for(i = 0; i < content_length; i++) { *pointer = hgetc(webblk->sock); if(*pointer != '\n' && *pointer != '\r') pointer++; } *pointer = '\0'; http_interpret_variable_string(webblk, post_arg, VARTYPE_POST); free(post_arg); } } if (!authok) { http_error(webblk, "401 Authorization Required", "WWW-Authenticate: Basic realm=\"HERCULES\"\n", "You must be authenticated to use this service"); } if (!url) { http_error(webblk,"400 Bad Request", "", "You must specify a GET or POST request"); } /* anything following a ? in the URL is part of the get arguments */ if ((pointer=strchr(url,'?'))) { *pointer++ = 0; http_interpret_variable_string(webblk, pointer, VARTYPE_GET); } while(url[0] == '/' && url[1] == '/') url++; webblk->baseurl = url; if(!strcasecmp("/",url)) url = HTTP_WELCOME; if(strncasecmp("/cgi-bin/",url,9)) http_download(webblk,url); else url += 9; while(*url == '/') url++; #if 0 http_dump_cgi_variables(webblk); #endif for(cgient = cgidir; cgient->path; cgient++) { if(!strcmp(cgient->path, url)) { char tbuf[80]; hprintf(webblk->sock,"HTTP/1.0 200 OK\nConnection: close\n"); hprintf(webblk->sock,"Date: %s\n", http_timestring(tbuf,sizeof(tbuf),time(NULL))); (cgient->cgibin) (webblk); http_exit(webblk); } } #if defined(OPTION_DYNAMIC_LOAD) { zz_cgibin dyncgi; if( (dyncgi = HDL_FINDSYM(webblk->baseurl)) ) { char tbuf[80]; hprintf(webblk->sock,"HTTP/1.0 200 OK\nConnection: close\n"); hprintf(webblk->sock,"Date: %s\n", http_timestring(tbuf,sizeof(tbuf),time(NULL))); dyncgi(webblk); http_exit(webblk); } } #endif /*defined(OPTION_DYNAMIC_LOAD)*/ http_error(webblk, "404 File Not Found","", "The requested file was not found"); return NULL; }
int main(int argc, char *argv[]) { //initialize Key-Value store-------------------------------------------------- kv_t **vhost_ptr = (kv_t**)get_env(argv, US_VHOST_DATA), //persistent ptr *forum_store = 0; //convenience pointer (var->m instead of (*var)->m) if (vhost_ptr && !*vhost_ptr) { *vhost_ptr = (kv_t*)malloc(sizeof(kv_t)); //threads and posts stored here kv_init(*vhost_ptr, "forum_store", 1024, 0, 0, 0); } forum_store = *vhost_ptr; //---------------------------------------------------------------------------- //setup GET and POST variables------------------------------------------------ char *act = "", *id = "", *title = "", *body = ""; get_arg("act=", &act, argc, argv); //action ('t' or 'p') get_arg("id=", &id, argc, argv); //id of thread get_arg("title=", &title, argc, argv); //title of thread get_arg("body=", &body, argc, argv); //body of post char *end = 0; u64 int_id = strtoll(id, &end, 10); //string to integer if (*end) int_id = 0; //require a numeric ID //---------------------------------------------------------------------------- //response sent to browser is stored here------------------------------------- //templates are rendered into this buffer xbuf_t *reply = get_reply(argv); xbuf_cat(reply, base_tpl); //set base template //---------------------------------------------------------------------------- //HTTP state of a connection http_t *http = (http_t*)get_env(argv, HTTP_HEADERS); redirect: //simulate HTTP, <meta>, or JavaScript redirect without page reload //choose what to do based on the value of 'act'------------------------------- switch (*act) { //regarding a post case 'p': { switch (http->h_method) //GET or POST { //new post-------------------------------------------------------------- case HTTP_POST: { //get the thread to which this post belongs Thread *thread = (Thread*)kv_get(forum_store, (char*)&int_id, sizeof(int_id)); if (!thread) //thread not found { xbuf_repl(reply, "<!--tpl-->", http_error(404)); return 404; } //allocate memory Post *post = calloc(1, sizeof(*post)); //initialize members xbuf_init(&post->body); //define members post->id = thread->posts.nbr_items + 1; xbuf_cat(&post->body, *body ? body : " "); //add post to thread kv_add(&thread->posts, &(kv_item) { .key = (char*)&post->id, .klen = sizeof(post->id), .val = (char*)post, .flags = 0, }); //setup redirect http->h_method = HTTP_GET; *act = 't'; goto redirect; } break; //---------------------------------------------------------------------- } } break; //regarding a thread case 't': { switch (http->h_method) { //view a thread--------------------------------------------------------- case HTTP_GET: { Thread *thread = (Thread*)kv_get(forum_store, (char*)&int_id, sizeof(int_id)); if (!thread) { xbuf_repl(reply, "<!--tpl-->", http_error(404)); return 404; } //replace template variables with dynamic values xbuf_repl(reply, "<!--form-->", post_form); xbuf_repl(reply, "<!--title-->", thread->title.ptr); xbuf_repl(reply, "<!--id-->", id); //for each post, render its template and insert it into reply kv_do(&thread->posts, 0, 0, (kv_proc_t)&list_posts, (void*)reply); } break; //---------------------------------------------------------------------- //create a thread------------------------------------------------------- case HTTP_POST: { Thread *thread = calloc(1, sizeof(*thread)); xbuf_init(&thread->title); kv_init(&thread->posts, "posts", 1024, 0, 0, 0); thread->id = forum_store->nbr_items + 1; xbuf_cat(&thread->title, *title ? title : " "); //add thread to KV store kv_add(forum_store, &(kv_item) { .key = (char*)&thread->id, .klen = sizeof(thread->id), .val = (char*)thread, .flags = 0, }); http->h_method = HTTP_GET; *act = 0; goto redirect; } break; //---------------------------------------------------------------------- } } break;
int http_analyze(int cfd, threadpool_t *tpool) { char method[20],version[20], url[MAXURL], query[MAXQUERY], line[MAXLINE], *pos; int ret=0, iscgi=0; if ((ret = http_getline(cfd, line, MAXLINE))==0){ struct sockaddr_in saddr; socklen_t len; getsockname(cfd, (struct sockaddr*)&saddr, &len); char buf[100]; sprintf (buf, "%s ip:%s create an error connection", __FUNCTION__, inet_ntoa(saddr.sin_addr)); errlog(buf); return -1; } sscanf(line, "%s %s %s", method, url, version); if (strncasecmp(method, "GET", 3) !=0 && strncasecmp(method, "POST", 4) !=0){ http_not_support(cfd); return 0; } pos = url; while(*pos != '?' && *pos != '\0') pos++; if (*pos == '?'){ iscgi=1; *pos='\0'; pos++; strncpy(query, pos, strlen(pos)+1); } struct sockaddr_in addr; socklen_t socklen; getsockname(cfd, (struct sockaddr*)&addr, &socklen); time_t t = time(NULL); char* tmpbuf = (char*)malloc(50); sprintf (tmpbuf, "%s----", ctime(&t)); sprintf (tmpbuf, "%sIP:%s", tmpbuf, inet_ntoa(addr.sin_addr)); db_store(walker_db, (const char*)tmpbuf, (const char*)url, DB_INSERT); free(tmpbuf); if (strncasecmp(method, "GET", 3)==0){ char *filepath; filepath = (char *)malloc(strlen(walkerconf[ROOT].value)+strlen(url)+1); strcpy(filepath, walkerconf[ROOT].value); strcat(filepath, url); while((ret = http_getline(cfd, line, MAXLINE))>0); struct stat st; if (stat(filepath, &st) == -1){ http_not_found(cfd); return 0; } if (access(filepath, R_OK)){ http_error(cfd); return 0; } if ((S_ISDIR(st.st_mode) || S_ISREG(st.st_mode)) && !iscgi){ struct http_job* job = http_make_job(cfd, filepath); //threadpool_add(tpool, http_thread_work, (void*)job, 0); http_thread_work((void*)job); return 0; }else if (S_ISREG(st.st_mode) && iscgi){ }else{ http_error(cfd); return 0; } }else if (strncasecmp(method, "POST", 4) == 0){ int pi[2], pid, content_length; char *p; char *filepath; filepath = (char *)malloc(strlen(walkerconf[ROOT].value)+strlen(url)+1); strcpy(filepath, walkerconf[ROOT].value); strcat(filepath, url); content_length=-1; while((ret=http_getline(cfd, line, MAXLINE)) !=0){ if (strncasecmp(line, "Content-Length:", 15) == 0){ p = &line[15]; p += strspn(p, " \t"); content_length = atoi(p); } } if (content_length != -1){ recv(cfd, postdata, content_length, 0); } socketpair(AF_UNIX, SOCK_STREAM, 0, pi); pid = fork(); if (pid==0){ dup2(pi[0], 0); dup2(pi[1], 1); close(pi[0]); close(pi[1]); char meth_env[255]; char length_env[255]; sprintf (meth_env, "REQUEST_METHOD=%s", method); putenv(meth_env); sprintf (length_env, "CONTENT_LENGTH=%d", content_length); putenv(length_env); execl("/usr/bin/php-cgi", "php-cgi", filepath, NULL); exit(0); }else{ char recvdata[MAXLINE], packet[MAXLINE]; write(pi[0], postdata, content_length); if ((ret = read(pi[0], recvdata, MAXLINE))>0){ recvdata[ret]='\0'; //sprintf(packet, "%sContent-Type: text/html\r\n", packet); sprintf(packet, "HTTP/1.1 200 OK\r\n"); sprintf(packet, "%sContent-Length: %d\r\n\r\n", packet, ret); sprintf(packet, "%s%s", packet, recvdata); send(cfd, packet, MAXLINE, 0); //send(cfd, recvdata, MAXLINE, 0); } close(pi[0]); close(pi[1]); free(filepath); waitpid(pid, NULL, 0); } } return 0; }
static struct discovery* discover_refs(const char *service) { struct strbuf buffer = STRBUF_INIT; struct discovery *last = last_discovery; char *refs_url; int http_ret, is_http = 0, proto_git_candidate = 1; if (last && !strcmp(service, last->service)) return last; free_discovery(last); strbuf_addf(&buffer, "%sinfo/refs", url); if (!prefixcmp(url, "http://") || !prefixcmp(url, "https://")) { is_http = 1; if (!strchr(url, '?')) strbuf_addch(&buffer, '?'); else strbuf_addch(&buffer, '&'); strbuf_addf(&buffer, "service=%s", service); } refs_url = strbuf_detach(&buffer, NULL); http_ret = http_get_strbuf(refs_url, &buffer, HTTP_NO_CACHE); /* try again with "plain" url (no ? or & appended) */ if (http_ret != HTTP_OK && http_ret != HTTP_NOAUTH) { free(refs_url); strbuf_reset(&buffer); proto_git_candidate = 0; strbuf_addf(&buffer, "%sinfo/refs", url); refs_url = strbuf_detach(&buffer, NULL); http_ret = http_get_strbuf(refs_url, &buffer, HTTP_NO_CACHE); } switch (http_ret) { case HTTP_OK: break; case HTTP_MISSING_TARGET: die("%s not found: did you run git update-server-info on the" " server?", refs_url); case HTTP_NOAUTH: die("Authentication failed"); default: http_error(refs_url, http_ret); die("HTTP request failed"); } last= xcalloc(1, sizeof(*last_discovery)); last->service = service; last->buf_alloc = strbuf_detach(&buffer, &last->len); last->buf = last->buf_alloc; if (is_http && proto_git_candidate && 5 <= last->len && last->buf[4] == '#') { /* smart HTTP response; validate that the service * pkt-line matches our request. */ struct strbuf exp = STRBUF_INIT; if (packet_get_line(&buffer, &last->buf, &last->len) <= 0) die("%s has invalid packet header", refs_url); if (buffer.len && buffer.buf[buffer.len - 1] == '\n') strbuf_setlen(&buffer, buffer.len - 1); strbuf_addf(&exp, "# service=%s", service); if (strbuf_cmp(&exp, &buffer)) die("invalid server response; got '%s'", buffer.buf); strbuf_release(&exp); /* The header can include additional metadata lines, up * until a packet flush marker. Ignore these now, but * in the future we might start to scan them. */ strbuf_reset(&buffer); while (packet_get_line(&buffer, &last->buf, &last->len) > 0) strbuf_reset(&buffer); last->proto_git = 1; } free(refs_url); strbuf_release(&buffer); last_discovery = last; return last; }
/* * Launch a http server that listens on the given port. */ void http_server(uint16_t port, void (*callback)(struct http_user_vars_s *), bool launch) { socket_t s_listen = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); if (s_listen == INVALID_SOCKET) { error("unable to create a socket for the configuration server"); } struct sockaddr_in6 listen_addr; memset(&listen_addr, 0x0, sizeof(listen_addr)); listen_addr.sin6_family = AF_INET6; listen_addr.sin6_port = htons(port); listen_addr.sin6_addr = in6addr_any; int on = 1; setsockopt(s_listen, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)); // For Windows we must explicitly allow IPv4 connections on = 0; if (setsockopt(s_listen, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&on, sizeof(on)) != 0) { warning("unable to allow incoming IPv4 connections to configuration " "server"); } if (bind(s_listen, (const void *)&listen_addr, sizeof(listen_addr)) != 0) { error("unable to create configuation server; failed to bind to " "address localhost:%u", port); } if (listen(s_listen, 1) != 0) { error("unable to create configuation server; failed to listen to " "address localhost:%u", port); } // Launch the UI: if (launch) { launch_ui(port); } // Main server loop: while (true) { struct sockaddr_in6 accept_addr; socklen_t accept_len = sizeof(accept_addr); socket_t s = accept(s_listen, (struct sockaddr *)&accept_addr, &accept_len); if (s == INVALID_SOCKET) { warning("unable to accept incoming connection to configuration " "server localhost:%u", port); close_socket(s); continue; } static const struct in6_addr in6addr_loopbackv4 = {{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 127, 0, 0, 1}}}; if (memcmp(&accept_addr.sin6_addr, &in6addr_loopback, sizeof(in6addr_loopback)) != 0 && memcmp(&accept_addr.sin6_addr, &in6addr_loopbackv4, sizeof(in6addr_loopbackv4) - 3) != 0) { warning("unable to accept incoming connection to configuration " "server localhost:%u from non-local address", port); close_socket(s); continue; } char request[MAX_REQUEST_BUFF_SIZE]; struct http_parser_s parser; http_parser_init(&parser); do { size_t n = recv(s, request, sizeof(request)-1, 0); if (n <= 0) { http_user_vars_free(&parser.request.vars); warning("unable to read request for configuration server " "localhost:%u", port); close_socket(s); break; } request[n] = '\0'; http_parse_request(request, n, &parser); switch (parser.state) { case HTTP_STATE_FINAL: break; case HTTP_STATE_ERROR: http_user_vars_free(&parser.request.vars); warning("unable to parse request to configuration server " "localhost:%u", port); close_socket(s); break; default: continue; } http_callback_func_t generate; if (parser.request.method == HTTP_METHOD_GET && (generate = http_lookup_callback(parser.request.name)) != NULL) { http_buffer_t content = http_buffer_open(); if (generate(content)) { bool success = http_send_response(s, 200, content, &parser.request); if (!success) { http_error(s, 500, &parser.request); } } else { http_error(s, 404, &parser.request); } http_buffer_close(content); } else { callback(&parser.request.vars); http_handle_request(s, &parser.request); } shutdown(s, SHUT_RDWR); http_user_vars_free(&parser.request.vars); close_socket(s); } while (false); } }
/** Send a HTTP header to the client. Header is not closed by this function. @param t_session *session Current Session. @return int -1 on failure, 0 on success. */ int send_header(t_session *session) { char timestr[TIMESTR_SIZE], buf[100]; time_t t; struct tm *s; /* Send HTTP header. */ session->data_sent = true; /* HTTP version */ if (((session->http_version != NULL)) && (*(session->http_version + 7) == '0')) { if (send_buffer(session, hs_http10, 9) == -1) { return -1; } } else { if (send_buffer(session, hs_http11, 9) == -1) { return -1; } } /* HTTP code */ snprintf(buf,sizeof(buf)-1,"%d %s\r\n",session->return_code,http_error(session->return_code)); if (send_buffer(session, buf, strlen(buf)) == -1) { return -1; } /* Date */ if (time(&t) == -1) { return -1; } else if ((s = gmtime(&t)) == NULL) { return -1; } else if (strftime(timestr, TIMESTR_SIZE, "%a, %d %b %Y %X GMT\r\n", s) == 0) { return -1; } else if (send_buffer(session, "Date: ", 6) == -1) { return -1; } else if (send_buffer(session, timestr, strlen(timestr)) == -1) { return -1; } /* Server */ if (session->config->server_string != NULL) { snprintf(buf,sizeof(buf)-1,"%s%s\r\n",hs_server,session->config->server_string); /* Let's reuse our char buffer. */ if (send_buffer(session, buf, strlen(buf)) == -1) { return -1; } } /* Range */ if ((session->cgi_type == no_cgi) && (session->uri_is_dir == false)) { if (send_buffer(session, hs_range, 22) == -1) { return -1; } } /* Connection */ if (send_buffer(session, hs_conn, 12) == -1) { return -1; } else if (session->keep_alive) { if (send_buffer(session, hs_conka, 12) == -1) { return -1; } } else if (send_buffer(session, hs_concl, 7) == -1) { return -1; } /* Content-Encoding */ if (session->encode_gzip) { if (send_buffer(session, hs_gzip, 24) == -1) { return -1; } } /* Content-Type */ if (session->mimetype != NULL) { snprintf(buf,sizeof(buf)-1,"%s%s\r\n",hs_contyp,session->mimetype); /* Let's reuse our char buffer. */ if (send_buffer(session, buf, strlen(buf)) == -1) { return -1; } } /* Expires */ if ((session->expires > -1) && (session->return_code == 200)) { if (time(&t) == -1) { return -1; } t += (time_t)session->expires; if ((s = gmtime(&t)) == NULL) { return -1; } else if (send_buffer(session, hs_expires, 9) == -1) { return -1; } else if (strftime(timestr, TIMESTR_SIZE, "%a, %d %b %Y %X GMT\r\n", s) == 0) { return -1; } else if (send_buffer(session, timestr, strlen(timestr)) == -1) { return -1; } } return 0; }
static struct ref *get_refs_via_curl(struct transport *transport, int for_push) { struct strbuf buffer = STRBUF_INIT; char *data, *start, *mid; char *ref_name; char *refs_url; int i = 0; int http_ret; struct ref *refs = NULL; struct ref *ref = NULL; struct ref *last_ref = NULL; struct walker *walker; if (for_push) return NULL; if (!transport->data) transport->data = get_http_walker(transport->url, transport->remote); walker = transport->data; refs_url = xmalloc(strlen(transport->url) + 11); sprintf(refs_url, "%s/info/refs", transport->url); http_ret = http_get_strbuf(refs_url, &buffer, HTTP_NO_CACHE); switch (http_ret) { case HTTP_OK: break; case HTTP_MISSING_TARGET: die("%s not found: did you run git update-server-info on the" " server?", refs_url); default: http_error(refs_url, http_ret); die("HTTP request failed"); } data = buffer.buf; start = NULL; mid = data; while (i < buffer.len) { if (!start) start = &data[i]; if (data[i] == '\t') mid = &data[i]; if (data[i] == '\n') { data[i] = 0; ref_name = mid + 1; ref = xmalloc(sizeof(struct ref) + strlen(ref_name) + 1); memset(ref, 0, sizeof(struct ref)); strcpy(ref->name, ref_name); get_sha1_hex(start, ref->old_sha1); if (!refs) refs = ref; if (last_ref) last_ref->next = ref; last_ref = ref; start = NULL; } i++; } strbuf_release(&buffer); ref = alloc_ref("HEAD"); if (!walker->fetch_ref(walker, ref) && !resolve_remote_symref(ref, refs)) { ref->next = refs; refs = ref; } else { free(ref); } strbuf_release(&buffer); free(refs_url); return refs; }
static void http_io(IOCHAN i, int event) { struct http_channel *hc = iochan_getdata(i); while (event) { if (event == EVENT_INPUT) { int res, reqlen; struct http_buf *htbuf; htbuf = http_buf_create(hc->http_server); res = recv(iochan_getfd(i), htbuf->buf, HTTP_BUF_SIZE -1, 0); if (res == -1 && errno == EAGAIN) { http_buf_destroy(hc->http_server, htbuf); return; } if (res <= 0) { #if HAVE_SYS_TIME_H if (hc->http_server->record_file) { struct timeval tv; gettimeofday(&tv, 0); fprintf(hc->http_server->record_file, "%lld %lld %lld 0\n", (long long) tv.tv_sec, (long long) tv.tv_usec, (long long) iochan_getfd(i)); } #endif http_buf_destroy(hc->http_server, htbuf); fflush(hc->http_server->record_file); http_channel_destroy(i); return; } htbuf->buf[res] = '\0'; htbuf->len = res; http_buf_enqueue(&hc->iqueue, htbuf); while (1) { if (hc->state == Http_Busy) return; reqlen = request_check(hc->iqueue); if (reqlen <= 2) return; // we have a complete HTTP request nmem_reset(hc->nmem); #if HAVE_SYS_TIME_H if (hc->http_server->record_file) { struct timeval tv; int sz = 0; struct http_buf *hb; for (hb = hc->iqueue; hb; hb = hb->next) sz += hb->len; gettimeofday(&tv, 0); fprintf(hc->http_server->record_file, "%lld %lld %lld %d\n", (long long) tv.tv_sec, (long long) tv.tv_usec, (long long) iochan_getfd(i), sz); for (hb = hc->iqueue; hb; hb = hb->next) fwrite(hb->buf, 1, hb->len, hc->http_server->record_file); } #endif if (!(hc->request = http_parse_request(hc, &hc->iqueue, reqlen))) { yaz_log(YLOG_WARN, "Failed to parse request"); http_error(hc, 400, "Bad Request"); return; } hc->response = 0; yaz_log(YLOG_LOG, "Request: %s %s%s%s", hc->request->method, hc->request->path, *hc->request->search ? "?" : "", hc->request->search); if (hc->request->content_buf) yaz_log(YLOG_LOG, "%s", hc->request->content_buf); if (http_weshouldproxy(hc->request)) http_proxy(hc->request); else { // Execute our business logic! hc->state = Http_Busy; http_command(hc); } } } else if (event == EVENT_OUTPUT) { event = 0; if (hc->oqueue) { struct http_buf *wb = hc->oqueue; int res; res = send(iochan_getfd(hc->iochan), wb->buf + wb->offset, wb->len, 0); if (res <= 0) { yaz_log(YLOG_WARN|YLOG_ERRNO, "write"); http_channel_destroy(i); return; } if (res == wb->len) { hc->oqueue = hc->oqueue->next; http_buf_destroy(hc->http_server, wb); } else { wb->len -= res; wb->offset += res; } if (!hc->oqueue) { if (!hc->keep_alive) { http_channel_destroy(i); return; } else { iochan_clearflag(i, EVENT_OUTPUT); if (hc->iqueue) event = EVENT_INPUT; } } } if (!hc->oqueue && hc->proxy && !hc->proxy->iochan) http_channel_destroy(i); // Server closed; we're done } else { yaz_log(YLOG_WARN, "Unexpected event on connection"); http_channel_destroy(i); event = 0; } } }
void method_delete(struct kreq *r) { struct state *st = r->arg; int rc; const char *digest; int64_t tag; char *ep; if (NULL == st->cfg) { kerrx("%s: DELETE from non-calendar " "collection", st->prncpl->name); http_error(r, KHTTP_403); return; } digest = NULL; if (NULL != r->reqmap[KREQU_IF_MATCH]) { digest = r->reqmap[KREQU_IF_MATCH]->val; tag = strtoll(digest, &ep, 10); if (digest == ep || '\0' != *ep) digest = NULL; else if (tag == LLONG_MIN && errno == ERANGE) digest = NULL; else if (tag == LLONG_MAX && errno == ERANGE) digest = NULL; if (NULL == digest) kerrx("%s: bad numeric digest", st->prncpl->name); } if (NULL != digest && '\0' != st->resource[0]) { rc = db_resource_delete (st->resource, tag, st->cfg->id); if (0 == rc) { kerrx("%s: cannot deleted: %s", st->prncpl->name, r->fullpath); http_error(r, KHTTP_403); } else { kinfo("%s: resource deleted: %s", st->prncpl->name, r->fullpath); http_error(r, KHTTP_204); } return; } else if (NULL == digest && '\0' != st->resource[0]) { rc = db_resource_remove (st->resource, st->cfg->id); if (0 == rc) { kerrx("%s: cannot deleted: %s", st->prncpl->name, r->fullpath); http_error(r, KHTTP_403); } else { kinfo("%s: resource (unsafe) deleted: %s", st->prncpl->name, r->fullpath); http_error(r, KHTTP_204); } return; } if (0 == db_collection_remove(st->cfg->id, st->prncpl)) { kinfo("%s: cannot delete: %s", st->prncpl->name, r->fullpath); http_error(r, KHTTP_505); } else { kinfo("%s: collection unlinked: %s", st->prncpl->name, r->fullpath); http_error(r, KHTTP_204); } }
static int hc_image(http_connection_t *hc, const char *remain, void *opaque, http_cmd_t method) { htsbuf_queue_t out; image_t *img; char errbuf[200]; const char *content; image_meta_t im = {0}; im.im_no_decoding = 1; rstr_t *url; const char *u = http_arg_get_req(hc, "url"); if(u != NULL) { url = rstr_alloc(u); url_deescape(rstr_data(url)); } else { if(remain == NULL) { return 404; } url = rstr_alloc(remain); } img = backend_imageloader(url, &im, NULL, errbuf, sizeof(errbuf), NULL, NULL); rstr_release(url); if(img == NULL) return http_error(hc, 404, "Unable to load image %s : %s", remain, errbuf); const image_component_t *ic = image_find_component(img, IMAGE_CODED); if(ic == NULL) { image_release(img); return http_error(hc, 404, "Unable to load image %s : Original data not available", remain); } const image_component_coded_t *icc = &ic->coded; htsbuf_queue_init(&out, 0); htsbuf_append(&out, buf_cstr(icc->icc_buf), buf_len(icc->icc_buf)); switch(icc->icc_type) { case IMAGE_JPEG: content = "image/jpeg"; break; case IMAGE_PNG: content = "image/png"; break; case IMAGE_GIF: content = "image/gif"; break; default: content = "image"; break; } image_release(img); return http_send_reply(hc, 0, content, NULL, NULL, 0, &out); }
/** Send a HTTP code to the client. Used in case of an error. @param t_session *session Current Session. @return int -1 on failure, 0 on success. */ int send_code(t_session *session) { int default_port; char port[10]; if (session->return_code == -1) { session->return_code = 500; } /* Send simple HTTP error message. */ session->mimetype = NULL; if (send_header(session) == -1) { return -1; } switch (session->return_code) { case 301: if (send_buffer(session, hs_lctn, 10) == -1) { return -1; } if (session->cause_of_301 == location) { if (session->location != NULL) { if (send_buffer(session, session->location, strlen(session->location)) == -1) { return -1; } } if (send_buffer(session, "\r\n", 2) == -1) { return -1; } break; } #ifdef HAVE_SSL if (session->binding->use_ssl || (session->cause_of_301 == require_ssl)) { if (send_buffer(session, hs_https, 8) == -1) { return -1; } } else #endif if (send_buffer(session, hs_http, 7) == -1) { return -1; } if (session->hostname != NULL) { if (send_buffer(session, session->hostname, strlen(session->hostname)) == -1) { return -1; } } else if (send_buffer(session, *(session->host->hostname.item), strlen(*(session->host->hostname.item))) == -1) { return -1; } if (session->cause_of_301 != require_ssl) { #ifdef HAVE_SSL if (session->binding->use_ssl) { default_port = 443; } else #endif default_port = 80; if (session->binding->port != default_port) { /*port[9] = '\0';*/ snprintf(port, 9, ":%d", session->binding->port); if (send_buffer(session, port, strlen(port)) == -1) { return -1; } } } if (send_buffer(session, session->uri, session->uri_len) == -1) { return -1; } if (session->cause_of_301 == missing_slash) { if (send_buffer(session, "/", 1) == -1) { return -1; } } if (session->vars != NULL) { if (send_buffer(session, "?", 1) == -1) { return -1; } else if (send_buffer(session, session->vars, strlen(session->vars)) == -1) { return -1; } } if (send_buffer(session, "\r\n", 2) == -1) { return -1; } break; case 401: if (session->host->auth_method == basic) { send_basic_auth(session); } else { send_digest_auth(session); } break; } const char *emesg = http_error(session->return_code); char cbuf[1024], hbuf[256]; /* Content and Header Buffer */ snprintf(cbuf, 1024,"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\"><html><head><title>%d - %s</title><style type=\"text/css\">body{font-family:Arial,Helvetica,sans-serif;background-color:#441;font-size:12px;line-height:2em;color:#000;}h1{font-size:2em;margin-bottom:.4em;font-weight:normal;}a{color:#0088b5;text-decoration:underline;}a:hover{color:#8ab54a;text-decoration:none;}.bc{padding:30px 45px 45px 30px;margin:100px auto 0 auto;border:6px solid #000;background-color:#fff;width:450px}.tc{padding:20px 50px 0 65px;text-align:center;}.f{margin-top:50px;font-size:8pt;text-align:right;}</style></head><body><div class=bc><div class=tc><h1>%d - %s</h1></div><div class=f> © 2010-2011 <a href=\"http://koppin22.com\">Koppin22 Media DA.</a> All rights reserved.</div></div></body></html>",session->return_code,emesg,session->return_code,emesg); snprintf(hbuf, 256, "Content-Length: %d\r\n%stext/html\r\n\r\n",(int)strlen(cbuf),hs_contyp); /* Send Header */ if (send_buffer(session, hbuf, (int)strlen(hbuf)) == -1) { return -1; } session->header_sent = true; if (session->request_method == HEAD) { return 0; } /* Send Error page Content */ if (send_buffer(session, cbuf, (int)strlen(cbuf)) == -1) { return -1; } return 0; }
static void url_enc(char *s, int f, int chunk) { for(; *s; s++) { char *c = (char[4]){ *s, 0 }; if(!isalnum(*s) && *s != '-' && *s != '_' && *s != '.' && *s != '~' && *s != '/') sprintf(c, "%%%.2X", (unsigned)*s); if(chunk) dprintf(f, "%x\r\n%s\r\n", (int)strlen(c), c); else dprintf(f, "%s", c); } } static int alphasort_q(const void *a, const void *b) { return alphasort((const struct dirent**)a, (const struct dirent**)b); } static void do_dir_list(char *s, int c, int f, char *http) { DIR *d = fdopendir(f); struct dirent *de, **names=0, **tmp; size_t cnt=0, len=0; int chunk = 0; if(!d) { http_error(c, 503, http); close(f); return; } while((errno=0), (de = readdir(d))) { if(de->d_name[0] == '.') continue; if(cnt >= len) { len = 2*len+1; if (len > SIZE_MAX/sizeof *names) break; tmp = realloc(names, len * sizeof *names); if (!tmp) break; names = tmp; } names[cnt] = malloc(de->d_reclen); if (!names[cnt]) break; memcpy(names[cnt++], de, de->d_reclen); } if(errno) { closedir(d); http_error(c, 503, http); if (names) while(cnt-->0) free(names[cnt]); free(names); } qsort(names, cnt, sizeof *names, alphasort_q); if(strcmp(http, "HTTP/1.1") == 0) chunk = 1; dprintf(c, "%s<!DOCTYPE html>\r\n%s", chunk ? "11\r\n" : "", chunk ? "\r\n" : ""); for(size_t i = 0; i < cnt; i++) { dprintf(c, "%s<a href=\"/%s", chunk ? "a\r\n" : "", chunk ? "\r\n" : ""); url_enc(s, c, chunk); dprintf(c, "%s/%s", chunk ? "1\r\n" : "", chunk ? "\r\n" : ""); url_enc(names[i]->d_name, c, chunk); dprintf(c, "%s\">%s", chunk ? "2\r\n" : "", chunk ? "\r\n" : ""); for(size_t j = 0; names[i]->d_name[j]; j++) { switch(names[i]->d_name[j]) { case '<': dprintf(c, "%s<%s", chunk ? "4\r\n" : "", chunk ? "\r\n" : ""); break; case '>': dprintf(c, "%s>%s", chunk ? "4\r\n" : "", chunk ? "\r\n" : ""); break; case '&': dprintf(c, "%s&%s", chunk ? "5\r\n" : "", chunk ? "\r\n" : ""); break; case '"': dprintf(c, "%s"%s", chunk ? "6\r\n" : "", chunk ? "\r\n" : ""); break; case '\'': dprintf(c, "%s'%s", chunk ? "6\r\n" : "", chunk ? "\r\n" : ""); break; default: dprintf(c, "%s%c%s", chunk ? "1\r\n" : "", names[i]->d_name[j], chunk ? "\r\n" : ""); } } dprintf(c, "%s</a><br/>\r\n%s", chunk ? "b\r\n" : "", chunk ? "\r\n" : ""); free(names[i]); } if(chunk) dprintf(c, "0\r\n\r\n"); free(names); closedir(d); }
/* Send a HTTP header to the client. Header is not closed by this function. */ int send_header(t_session *session) { #ifdef ENABLE_SSL char random_header[MAX_RANDOM_HEADER_LENGTH + 13]; char *rand_set = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789PR"; unsigned long length, i; int random; #endif char ecode[5], timestr[TIMESTR_SIZE]; const char *emesg; time_t t; struct tm s; t_keyvalue *header; /* Send HTTP header. */ ecode[4] = '\0'; snprintf(ecode, 4, "%d", session->return_code); if ((emesg = http_error(session->return_code)) == NULL) { emesg = unknown_http_code; } session->data_sent = true; /* HTTP version */ if (session->http_version != NULL) { if (*(session->http_version + 7) == '0') { if (send_buffer(session, hs_http10, 9) == -1) { return -1; } } else { if (send_buffer(session, hs_http11, 9) == -1) { return -1; } } } else { if (send_buffer(session, hs_http11, 9) == -1) { return -1; } } /* HTTP code */ if (send_buffer(session, ecode, 3) == -1) { return -1; } else if (send_buffer(session, " ", 1) == -1) { return -1; } else if (send_buffer(session, emesg, strlen(emesg)) == -1) { return -1; } else if (send_buffer(session, hs_eol, 2) == -1) { return -1; } /* Date */ if (time(&t) == -1) { return -1; } else if (gmtime_r(&t, &s) == NULL) { return -1; } else if (strftime(timestr, TIMESTR_SIZE, "%a, %d %b %Y %X GMT\r\n", &s) == 0) { return -1; } else if (send_buffer(session, "Date: ", 6) == -1) { return -1; } else if (send_buffer(session, timestr, strlen(timestr)) == -1) { return -1; } /* Server */ if (session->config->server_string != NULL) { if (send_buffer(session, hs_server, 8) == -1) { return -1; } else if (send_buffer(session, session->config->server_string, strlen(session->config->server_string)) == -1) { return -1; } else if (send_buffer(session, hs_eol, 2) == -1) { return -1; } } /* Range */ if ((session->cgi_type == no_cgi) && (session->uri_is_dir == false)) { if (send_buffer(session, hs_range, 22) == -1) { return -1; } } /* Connection */ if (send_buffer(session, hs_conn, 12) == -1) { return -1; } else if (session->keep_alive) { if (send_buffer(session, hs_conka, 12) == -1) { return -1; } } else if (send_buffer(session, hs_concl, 7) == -1) { return -1; } /* Content-Encoding */ if (session->encode_gzip) { if (send_buffer(session, hs_gzip, 24) == -1) { return -1; } } /* Content-Type */ if (session->mimetype != NULL) { if (send_buffer(session, hs_contyp, 14) == -1) { return -1; } else if (send_buffer(session, session->mimetype, strlen(session->mimetype)) == -1) { return -1; } else if (send_buffer(session, "\r\n", 2) == -1) { return -1; } } /* Expires */ if ((session->expires > -1) && (session->return_code == 200)) { if (time(&t) == -1) { return -1; } t += (time_t)session->expires; if (gmtime_r(&t, &s) == NULL) { return -1; } else if (send_buffer(session, hs_caco, 15) == -1) { return -1; } if (session->caco_private) { if (send_buffer(session, hs_private, 9) == -1) { return -1; } } else { if (send_buffer(session, hs_public, 8) == -1) { return -1; } } if (send_buffer(session, hs_expires, 9) == -1) { return -1; } else if (strftime(timestr, TIMESTR_SIZE, "%a, %d %b %Y %X GMT\r\n", &s) == 0) { return -1; } else if (send_buffer(session, timestr, strlen(timestr)) == -1) { return -1; } } /* Custom headers */ header = session->host->custom_headers; while (header != NULL) { if (send_buffer(session, header->key, strlen(header->key)) == -1) { return -1; } else if (send_buffer(session, ": ", 2) == -1) { return -1; } else if (send_buffer(session, header->value, strlen(header->value)) == -1) { return -1; } else if (send_buffer(session, "\r\n", 2) == -1) { return -1; } header = header->next; } #ifdef ENABLE_SSL /* Random header */ if ((session->host->random_header_length > -1) && session->binding->use_ssl) { sprintf(random_header, "X-Random: "); length = (session->host->random_header_length * ((unsigned int)rand() & MAX_RANDOM_HEADER_LENGTH_MASK)) / MAX_RANDOM_HEADER_LENGTH_MASK; if (length == 0) { length = 1; } sprintf(random_header + 10 + length, "\r\n"); random = rand() & 63; for (i = 0; i < length; i++) { random_header[10 + i] = rand_set[random]; } if (send_buffer(session, random_header, 12 + length) == -1) { return -1; } } /* HTTP Strict Transport Security */ if ((session->host->hsts_time != NULL) && session->binding->use_ssl) { if (send_buffer(session, hs_hsts, 35) == -1) { return -1; } if (send_buffer(session, session->host->hsts_time, strlen(session->host->hsts_time)) == -1) { return -1; } if (send_buffer(session, "\r\n", 2) == -1) { return -1; } } #endif return 0; }