Beispiel #1
0
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");
}
Beispiel #2
0
/*
  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;
}
Beispiel #3
0
/* 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);
}
Beispiel #4
0
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;
}
Beispiel #5
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);
}
Beispiel #6
0
/*
 * 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);
    }
}
Beispiel #7
0
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; 

}
Beispiel #8
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);
}
Beispiel #9
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);
}
Beispiel #10
0
/* 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;
}
Beispiel #11
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);
}
Beispiel #12
0
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;
		}
	}
}
Beispiel #13
0
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
}
Beispiel #14
0
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);
	}
}
Beispiel #15
0
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;
	}
}
Beispiel #16
0
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);


}
Beispiel #17
0
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;
}
Beispiel #18
0
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;
Beispiel #19
0
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;
}
Beispiel #20
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;
}
Beispiel #21
0
/*
 * 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);
    }
}
Beispiel #22
0
/**
    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;
}
Beispiel #23
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;
}
Beispiel #24
0
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;
        }
    }
}
Beispiel #25
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);
	}
}
Beispiel #26
0
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);
}
Beispiel #27
0
/**
    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> &copy; 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;
}
Beispiel #28
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&lt;%s", chunk ? "4\r\n" : "",
						chunk ? "\r\n" : "");
				break;
			case '>':
				dprintf(c, "%s&gt;%s", chunk ? "4\r\n" : "",
						chunk ? "\r\n" : "");
				break;
			case '&':
				dprintf(c, "%s&amp;%s", chunk ? "5\r\n" : "",
						chunk ? "\r\n" : "");
				break;
			case '"':
				dprintf(c, "%s&quot;%s", chunk ? "6\r\n" : "",
						chunk ? "\r\n" : "");
				break;
			case '\'':
				dprintf(c, "%s&apos;%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);
}
Beispiel #29
0
/* 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;
}