C socket Webserver not displaying html in browser, only sending HTTP response









up vote
0
down vote

favorite












I am relatively new to C, and trying to play around with some code a professor gave me, and then modifying it since then, to help me along with a server project. I cant figure out how to actually be able to see the HTML in lynx, i just get the HTTP response. (i can curl it and see what I am trying to send, but the browser will not load the HTML body) I have been checking everything I can think of, but at this point I have to admit I don't know enough about HTTP responses and could use a step in the right direction as to where I stepped off the path.



#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>

#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define BUFFER_SIZE 9999
#define HTTP_METHOD "HTTP/1.1 "
#define HTTP__OK "200 OKrn"
#define HTTP__NOT_FOUND "404 Not Foundrn"
#define SERVER_NAME "Server: ECE435rn"

/* Default port to listen on */
#define DEFAULT_PORT 8080 //modify port to listen on 8080

int main(int argc, char **argv)

int socket_fd,new_socket_fd;
struct sockaddr_in server_addr, client_addr;
int port=DEFAULT_PORT;
int n;
socklen_t client_len;
char buffer[BUFFER_SIZE];

printf("Starting server on port %dn",port);

/* Open a socket to listen on */
/* AF_INET means an IPv4 connection */
/* SOCK_STREAM means reliable two-way connection (TCP) */
socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if (socket_fd<0)
fprintf(stderr,"Error opening socket! %sn",
strerror(errno));
exit(1);


/* Set up the server address to listen on */
/* The memset stes the address to 0.0.0.0 which means */
/* listen on any interface. */
memset(&server_addr,0,sizeof(struct sockaddr_in));
server_addr.sin_family=AF_INET;

/* Convert the port we want to network byte order */
server_addr.sin_port=htons(port);

/* Bind to the port */
if (bind(socket_fd, (struct sockaddr *) &server_addr,
sizeof(server_addr)) <0)
fprintf(stderr,"Error binding! %sn", strerror(errno));
fprintf(stderr,"Probably in time wait, have to wait 60s if you ^C to closen");
exit(1);


/* Tell the server we want to listen on the port */
/* Second argument is backlog, how many pending connections can */
/* build up */
listen(socket_fd,5);


wait_for_connection:


/* Call accept to create a new file descriptor for an incoming */
/* connection. It takes the oldest one off the queue */
/* We're blocking so it waits here until a connection happens */
client_len=sizeof(client_addr);
new_socket_fd = accept(socket_fd,
(struct sockaddr *)&client_addr,&client_len);
if (new_socket_fd<0)
fprintf(stderr,"Error accepting! %sn",strerror(errno));
exit(1);


while(1)
/* Someone connected! Let's try to read BUFFER_SIZE-1 bytes */
memset( buffer, 0, BUFFER_SIZE );
n = read( new_socket_fd, buffer, ( BUFFER_SIZE-1 ) );
if (n==0)
fprintf( stderr, "Connection to client lostnn" );
break;

else if( n < 0 )
fprintf(stderr,"Error reading from socket %sn",
strerror(errno));


/* Print the message we received */
printf("Message received: %sn" ,buffer);


const char *PATTERN1 = "GET /"; //first cut to make on buffer
const char *PATTERN2 = " HTTP"; //second cut to make on buffer
char *target = NULL; //variable to hold the slice we're taking
char *start, *end; //defining variables to hold start and end positions
if ( start = strstr( buffer, PATTERN1 ) ) //code to grab a slice of buffer
start += strlen( PATTERN1 );

if ( end = strstr( start, PATTERN2 ) )
target = ( char * )malloc( end - start + 1 );
memcpy( target, start, end - start );
target[end - start] = '';


if ( target ) printf( "Client requested: %sn", target ); //code is working to this point. I can tell what file to get.

time_t rawtime;
struct tm info;
time( &rawtime );
struct tm * timeinfo;
char timestamp[100];
time_t now = time(0);
struct tm tm = *gmtime(&now);
strftime(timestamp, sizeof( timestamp ) , "%a, %d %b %Y %H:%M:%S %Z", &tm);
//printf("Time is: [%s]n", timestamp);

struct stat file_info; //define statistics structure for file info
stat( target, &file_info ); //initiate file_info as the stat structure for target


char send_client[9999];


sprintf( send_client, "HTTP/1.0 %s%srnServer: ECE435rnLast-Modified: Fri, 08 Sep 2017 04:31:47 GMTrnContent-Length: 85rnContent-Type: text/htmlrnrn", HTTP__OK, timestamp );

char file_path[256]; //limited to 256 char for now
sprintf( file_path, "./%s", target); //this is how you can combine char arrays: puts "./" + 'target' into 'file_path'

//int fd;

//printf( "%ldrn" , file_info.st_size ); //this should print the File Size


char source[BUFFER_SIZE + 1];
FILE *fp = fopen( file_path, "r");
if (fp != NULL)
size_t newLen = fread(source, sizeof(char), BUFFER_SIZE, fp);
if (newLen == 0)
fputs("Error reading file", stderr);
else
source[newLen] = ''; /* Just to be safe. */


fclose(fp);

strcat( send_client, source);


/* Send a response */
printf( "rn%srn" , send_client ); //print response before sending
n = write( new_socket_fd, send_client , strlen(send_client) ) ;
if( n < 0 )
fprintf( stderr, "Error writing. %sn", strerror(errno));




close(new_socket_fd);

printf("Done connection, go back and wait for anothernn");

goto wait_for_connection;

/* Try to avoid TIME_WAIT */
// sleep(1);

/* Close the sockets */
close(socket_fd);

return 0;










share|improve this question

















  • 1




    This code is not even close to being a viable HTTP server. It is not following any of the rules of the HTTP spec (RFC 2616, and later RFCs 7230-7235). And it makes classic newbie mistakes, like treating the output of recv() as a null-terminated string when it isn't, not implementing any kind of buffering to handle message framing in either direction, etc...
    – Remy Lebeau
    Nov 9 at 23:09











  • In any case, the reason a browser can't display your HTML is because you are sending a malformed HTTP response. For instance, your timestamp is being sent as-is without any header name. You are sending 3 rn in between the headers and file body when you need to send only 2. And you are opening the file in text mode instead of binary mode, and not ensuring that the number of bytes you send for the file matches the Content-Length header you are sending.
    – Remy Lebeau
    Nov 9 at 23:09















up vote
0
down vote

favorite












I am relatively new to C, and trying to play around with some code a professor gave me, and then modifying it since then, to help me along with a server project. I cant figure out how to actually be able to see the HTML in lynx, i just get the HTTP response. (i can curl it and see what I am trying to send, but the browser will not load the HTML body) I have been checking everything I can think of, but at this point I have to admit I don't know enough about HTTP responses and could use a step in the right direction as to where I stepped off the path.



#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>

#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define BUFFER_SIZE 9999
#define HTTP_METHOD "HTTP/1.1 "
#define HTTP__OK "200 OKrn"
#define HTTP__NOT_FOUND "404 Not Foundrn"
#define SERVER_NAME "Server: ECE435rn"

/* Default port to listen on */
#define DEFAULT_PORT 8080 //modify port to listen on 8080

int main(int argc, char **argv)

int socket_fd,new_socket_fd;
struct sockaddr_in server_addr, client_addr;
int port=DEFAULT_PORT;
int n;
socklen_t client_len;
char buffer[BUFFER_SIZE];

printf("Starting server on port %dn",port);

/* Open a socket to listen on */
/* AF_INET means an IPv4 connection */
/* SOCK_STREAM means reliable two-way connection (TCP) */
socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if (socket_fd<0)
fprintf(stderr,"Error opening socket! %sn",
strerror(errno));
exit(1);


/* Set up the server address to listen on */
/* The memset stes the address to 0.0.0.0 which means */
/* listen on any interface. */
memset(&server_addr,0,sizeof(struct sockaddr_in));
server_addr.sin_family=AF_INET;

/* Convert the port we want to network byte order */
server_addr.sin_port=htons(port);

/* Bind to the port */
if (bind(socket_fd, (struct sockaddr *) &server_addr,
sizeof(server_addr)) <0)
fprintf(stderr,"Error binding! %sn", strerror(errno));
fprintf(stderr,"Probably in time wait, have to wait 60s if you ^C to closen");
exit(1);


/* Tell the server we want to listen on the port */
/* Second argument is backlog, how many pending connections can */
/* build up */
listen(socket_fd,5);


wait_for_connection:


/* Call accept to create a new file descriptor for an incoming */
/* connection. It takes the oldest one off the queue */
/* We're blocking so it waits here until a connection happens */
client_len=sizeof(client_addr);
new_socket_fd = accept(socket_fd,
(struct sockaddr *)&client_addr,&client_len);
if (new_socket_fd<0)
fprintf(stderr,"Error accepting! %sn",strerror(errno));
exit(1);


while(1)
/* Someone connected! Let's try to read BUFFER_SIZE-1 bytes */
memset( buffer, 0, BUFFER_SIZE );
n = read( new_socket_fd, buffer, ( BUFFER_SIZE-1 ) );
if (n==0)
fprintf( stderr, "Connection to client lostnn" );
break;

else if( n < 0 )
fprintf(stderr,"Error reading from socket %sn",
strerror(errno));


/* Print the message we received */
printf("Message received: %sn" ,buffer);


const char *PATTERN1 = "GET /"; //first cut to make on buffer
const char *PATTERN2 = " HTTP"; //second cut to make on buffer
char *target = NULL; //variable to hold the slice we're taking
char *start, *end; //defining variables to hold start and end positions
if ( start = strstr( buffer, PATTERN1 ) ) //code to grab a slice of buffer
start += strlen( PATTERN1 );

if ( end = strstr( start, PATTERN2 ) )
target = ( char * )malloc( end - start + 1 );
memcpy( target, start, end - start );
target[end - start] = '';


if ( target ) printf( "Client requested: %sn", target ); //code is working to this point. I can tell what file to get.

time_t rawtime;
struct tm info;
time( &rawtime );
struct tm * timeinfo;
char timestamp[100];
time_t now = time(0);
struct tm tm = *gmtime(&now);
strftime(timestamp, sizeof( timestamp ) , "%a, %d %b %Y %H:%M:%S %Z", &tm);
//printf("Time is: [%s]n", timestamp);

struct stat file_info; //define statistics structure for file info
stat( target, &file_info ); //initiate file_info as the stat structure for target


char send_client[9999];


sprintf( send_client, "HTTP/1.0 %s%srnServer: ECE435rnLast-Modified: Fri, 08 Sep 2017 04:31:47 GMTrnContent-Length: 85rnContent-Type: text/htmlrnrn", HTTP__OK, timestamp );

char file_path[256]; //limited to 256 char for now
sprintf( file_path, "./%s", target); //this is how you can combine char arrays: puts "./" + 'target' into 'file_path'

//int fd;

//printf( "%ldrn" , file_info.st_size ); //this should print the File Size


char source[BUFFER_SIZE + 1];
FILE *fp = fopen( file_path, "r");
if (fp != NULL)
size_t newLen = fread(source, sizeof(char), BUFFER_SIZE, fp);
if (newLen == 0)
fputs("Error reading file", stderr);
else
source[newLen] = ''; /* Just to be safe. */


fclose(fp);

strcat( send_client, source);


/* Send a response */
printf( "rn%srn" , send_client ); //print response before sending
n = write( new_socket_fd, send_client , strlen(send_client) ) ;
if( n < 0 )
fprintf( stderr, "Error writing. %sn", strerror(errno));




close(new_socket_fd);

printf("Done connection, go back and wait for anothernn");

goto wait_for_connection;

/* Try to avoid TIME_WAIT */
// sleep(1);

/* Close the sockets */
close(socket_fd);

return 0;










share|improve this question

















  • 1




    This code is not even close to being a viable HTTP server. It is not following any of the rules of the HTTP spec (RFC 2616, and later RFCs 7230-7235). And it makes classic newbie mistakes, like treating the output of recv() as a null-terminated string when it isn't, not implementing any kind of buffering to handle message framing in either direction, etc...
    – Remy Lebeau
    Nov 9 at 23:09











  • In any case, the reason a browser can't display your HTML is because you are sending a malformed HTTP response. For instance, your timestamp is being sent as-is without any header name. You are sending 3 rn in between the headers and file body when you need to send only 2. And you are opening the file in text mode instead of binary mode, and not ensuring that the number of bytes you send for the file matches the Content-Length header you are sending.
    – Remy Lebeau
    Nov 9 at 23:09













up vote
0
down vote

favorite









up vote
0
down vote

favorite











I am relatively new to C, and trying to play around with some code a professor gave me, and then modifying it since then, to help me along with a server project. I cant figure out how to actually be able to see the HTML in lynx, i just get the HTTP response. (i can curl it and see what I am trying to send, but the browser will not load the HTML body) I have been checking everything I can think of, but at this point I have to admit I don't know enough about HTTP responses and could use a step in the right direction as to where I stepped off the path.



#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>

#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define BUFFER_SIZE 9999
#define HTTP_METHOD "HTTP/1.1 "
#define HTTP__OK "200 OKrn"
#define HTTP__NOT_FOUND "404 Not Foundrn"
#define SERVER_NAME "Server: ECE435rn"

/* Default port to listen on */
#define DEFAULT_PORT 8080 //modify port to listen on 8080

int main(int argc, char **argv)

int socket_fd,new_socket_fd;
struct sockaddr_in server_addr, client_addr;
int port=DEFAULT_PORT;
int n;
socklen_t client_len;
char buffer[BUFFER_SIZE];

printf("Starting server on port %dn",port);

/* Open a socket to listen on */
/* AF_INET means an IPv4 connection */
/* SOCK_STREAM means reliable two-way connection (TCP) */
socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if (socket_fd<0)
fprintf(stderr,"Error opening socket! %sn",
strerror(errno));
exit(1);


/* Set up the server address to listen on */
/* The memset stes the address to 0.0.0.0 which means */
/* listen on any interface. */
memset(&server_addr,0,sizeof(struct sockaddr_in));
server_addr.sin_family=AF_INET;

/* Convert the port we want to network byte order */
server_addr.sin_port=htons(port);

/* Bind to the port */
if (bind(socket_fd, (struct sockaddr *) &server_addr,
sizeof(server_addr)) <0)
fprintf(stderr,"Error binding! %sn", strerror(errno));
fprintf(stderr,"Probably in time wait, have to wait 60s if you ^C to closen");
exit(1);


/* Tell the server we want to listen on the port */
/* Second argument is backlog, how many pending connections can */
/* build up */
listen(socket_fd,5);


wait_for_connection:


/* Call accept to create a new file descriptor for an incoming */
/* connection. It takes the oldest one off the queue */
/* We're blocking so it waits here until a connection happens */
client_len=sizeof(client_addr);
new_socket_fd = accept(socket_fd,
(struct sockaddr *)&client_addr,&client_len);
if (new_socket_fd<0)
fprintf(stderr,"Error accepting! %sn",strerror(errno));
exit(1);


while(1)
/* Someone connected! Let's try to read BUFFER_SIZE-1 bytes */
memset( buffer, 0, BUFFER_SIZE );
n = read( new_socket_fd, buffer, ( BUFFER_SIZE-1 ) );
if (n==0)
fprintf( stderr, "Connection to client lostnn" );
break;

else if( n < 0 )
fprintf(stderr,"Error reading from socket %sn",
strerror(errno));


/* Print the message we received */
printf("Message received: %sn" ,buffer);


const char *PATTERN1 = "GET /"; //first cut to make on buffer
const char *PATTERN2 = " HTTP"; //second cut to make on buffer
char *target = NULL; //variable to hold the slice we're taking
char *start, *end; //defining variables to hold start and end positions
if ( start = strstr( buffer, PATTERN1 ) ) //code to grab a slice of buffer
start += strlen( PATTERN1 );

if ( end = strstr( start, PATTERN2 ) )
target = ( char * )malloc( end - start + 1 );
memcpy( target, start, end - start );
target[end - start] = '';


if ( target ) printf( "Client requested: %sn", target ); //code is working to this point. I can tell what file to get.

time_t rawtime;
struct tm info;
time( &rawtime );
struct tm * timeinfo;
char timestamp[100];
time_t now = time(0);
struct tm tm = *gmtime(&now);
strftime(timestamp, sizeof( timestamp ) , "%a, %d %b %Y %H:%M:%S %Z", &tm);
//printf("Time is: [%s]n", timestamp);

struct stat file_info; //define statistics structure for file info
stat( target, &file_info ); //initiate file_info as the stat structure for target


char send_client[9999];


sprintf( send_client, "HTTP/1.0 %s%srnServer: ECE435rnLast-Modified: Fri, 08 Sep 2017 04:31:47 GMTrnContent-Length: 85rnContent-Type: text/htmlrnrn", HTTP__OK, timestamp );

char file_path[256]; //limited to 256 char for now
sprintf( file_path, "./%s", target); //this is how you can combine char arrays: puts "./" + 'target' into 'file_path'

//int fd;

//printf( "%ldrn" , file_info.st_size ); //this should print the File Size


char source[BUFFER_SIZE + 1];
FILE *fp = fopen( file_path, "r");
if (fp != NULL)
size_t newLen = fread(source, sizeof(char), BUFFER_SIZE, fp);
if (newLen == 0)
fputs("Error reading file", stderr);
else
source[newLen] = ''; /* Just to be safe. */


fclose(fp);

strcat( send_client, source);


/* Send a response */
printf( "rn%srn" , send_client ); //print response before sending
n = write( new_socket_fd, send_client , strlen(send_client) ) ;
if( n < 0 )
fprintf( stderr, "Error writing. %sn", strerror(errno));




close(new_socket_fd);

printf("Done connection, go back and wait for anothernn");

goto wait_for_connection;

/* Try to avoid TIME_WAIT */
// sleep(1);

/* Close the sockets */
close(socket_fd);

return 0;










share|improve this question













I am relatively new to C, and trying to play around with some code a professor gave me, and then modifying it since then, to help me along with a server project. I cant figure out how to actually be able to see the HTML in lynx, i just get the HTTP response. (i can curl it and see what I am trying to send, but the browser will not load the HTML body) I have been checking everything I can think of, but at this point I have to admit I don't know enough about HTTP responses and could use a step in the right direction as to where I stepped off the path.



#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>

#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define BUFFER_SIZE 9999
#define HTTP_METHOD "HTTP/1.1 "
#define HTTP__OK "200 OKrn"
#define HTTP__NOT_FOUND "404 Not Foundrn"
#define SERVER_NAME "Server: ECE435rn"

/* Default port to listen on */
#define DEFAULT_PORT 8080 //modify port to listen on 8080

int main(int argc, char **argv)

int socket_fd,new_socket_fd;
struct sockaddr_in server_addr, client_addr;
int port=DEFAULT_PORT;
int n;
socklen_t client_len;
char buffer[BUFFER_SIZE];

printf("Starting server on port %dn",port);

/* Open a socket to listen on */
/* AF_INET means an IPv4 connection */
/* SOCK_STREAM means reliable two-way connection (TCP) */
socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if (socket_fd<0)
fprintf(stderr,"Error opening socket! %sn",
strerror(errno));
exit(1);


/* Set up the server address to listen on */
/* The memset stes the address to 0.0.0.0 which means */
/* listen on any interface. */
memset(&server_addr,0,sizeof(struct sockaddr_in));
server_addr.sin_family=AF_INET;

/* Convert the port we want to network byte order */
server_addr.sin_port=htons(port);

/* Bind to the port */
if (bind(socket_fd, (struct sockaddr *) &server_addr,
sizeof(server_addr)) <0)
fprintf(stderr,"Error binding! %sn", strerror(errno));
fprintf(stderr,"Probably in time wait, have to wait 60s if you ^C to closen");
exit(1);


/* Tell the server we want to listen on the port */
/* Second argument is backlog, how many pending connections can */
/* build up */
listen(socket_fd,5);


wait_for_connection:


/* Call accept to create a new file descriptor for an incoming */
/* connection. It takes the oldest one off the queue */
/* We're blocking so it waits here until a connection happens */
client_len=sizeof(client_addr);
new_socket_fd = accept(socket_fd,
(struct sockaddr *)&client_addr,&client_len);
if (new_socket_fd<0)
fprintf(stderr,"Error accepting! %sn",strerror(errno));
exit(1);


while(1)
/* Someone connected! Let's try to read BUFFER_SIZE-1 bytes */
memset( buffer, 0, BUFFER_SIZE );
n = read( new_socket_fd, buffer, ( BUFFER_SIZE-1 ) );
if (n==0)
fprintf( stderr, "Connection to client lostnn" );
break;

else if( n < 0 )
fprintf(stderr,"Error reading from socket %sn",
strerror(errno));


/* Print the message we received */
printf("Message received: %sn" ,buffer);


const char *PATTERN1 = "GET /"; //first cut to make on buffer
const char *PATTERN2 = " HTTP"; //second cut to make on buffer
char *target = NULL; //variable to hold the slice we're taking
char *start, *end; //defining variables to hold start and end positions
if ( start = strstr( buffer, PATTERN1 ) ) //code to grab a slice of buffer
start += strlen( PATTERN1 );

if ( end = strstr( start, PATTERN2 ) )
target = ( char * )malloc( end - start + 1 );
memcpy( target, start, end - start );
target[end - start] = '';


if ( target ) printf( "Client requested: %sn", target ); //code is working to this point. I can tell what file to get.

time_t rawtime;
struct tm info;
time( &rawtime );
struct tm * timeinfo;
char timestamp[100];
time_t now = time(0);
struct tm tm = *gmtime(&now);
strftime(timestamp, sizeof( timestamp ) , "%a, %d %b %Y %H:%M:%S %Z", &tm);
//printf("Time is: [%s]n", timestamp);

struct stat file_info; //define statistics structure for file info
stat( target, &file_info ); //initiate file_info as the stat structure for target


char send_client[9999];


sprintf( send_client, "HTTP/1.0 %s%srnServer: ECE435rnLast-Modified: Fri, 08 Sep 2017 04:31:47 GMTrnContent-Length: 85rnContent-Type: text/htmlrnrn", HTTP__OK, timestamp );

char file_path[256]; //limited to 256 char for now
sprintf( file_path, "./%s", target); //this is how you can combine char arrays: puts "./" + 'target' into 'file_path'

//int fd;

//printf( "%ldrn" , file_info.st_size ); //this should print the File Size


char source[BUFFER_SIZE + 1];
FILE *fp = fopen( file_path, "r");
if (fp != NULL)
size_t newLen = fread(source, sizeof(char), BUFFER_SIZE, fp);
if (newLen == 0)
fputs("Error reading file", stderr);
else
source[newLen] = ''; /* Just to be safe. */


fclose(fp);

strcat( send_client, source);


/* Send a response */
printf( "rn%srn" , send_client ); //print response before sending
n = write( new_socket_fd, send_client , strlen(send_client) ) ;
if( n < 0 )
fprintf( stderr, "Error writing. %sn", strerror(errno));




close(new_socket_fd);

printf("Done connection, go back and wait for anothernn");

goto wait_for_connection;

/* Try to avoid TIME_WAIT */
// sleep(1);

/* Close the sockets */
close(socket_fd);

return 0;







c sockets http






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 9 at 22:51









Robert

11




11







  • 1




    This code is not even close to being a viable HTTP server. It is not following any of the rules of the HTTP spec (RFC 2616, and later RFCs 7230-7235). And it makes classic newbie mistakes, like treating the output of recv() as a null-terminated string when it isn't, not implementing any kind of buffering to handle message framing in either direction, etc...
    – Remy Lebeau
    Nov 9 at 23:09











  • In any case, the reason a browser can't display your HTML is because you are sending a malformed HTTP response. For instance, your timestamp is being sent as-is without any header name. You are sending 3 rn in between the headers and file body when you need to send only 2. And you are opening the file in text mode instead of binary mode, and not ensuring that the number of bytes you send for the file matches the Content-Length header you are sending.
    – Remy Lebeau
    Nov 9 at 23:09













  • 1




    This code is not even close to being a viable HTTP server. It is not following any of the rules of the HTTP spec (RFC 2616, and later RFCs 7230-7235). And it makes classic newbie mistakes, like treating the output of recv() as a null-terminated string when it isn't, not implementing any kind of buffering to handle message framing in either direction, etc...
    – Remy Lebeau
    Nov 9 at 23:09











  • In any case, the reason a browser can't display your HTML is because you are sending a malformed HTTP response. For instance, your timestamp is being sent as-is without any header name. You are sending 3 rn in between the headers and file body when you need to send only 2. And you are opening the file in text mode instead of binary mode, and not ensuring that the number of bytes you send for the file matches the Content-Length header you are sending.
    – Remy Lebeau
    Nov 9 at 23:09








1




1




This code is not even close to being a viable HTTP server. It is not following any of the rules of the HTTP spec (RFC 2616, and later RFCs 7230-7235). And it makes classic newbie mistakes, like treating the output of recv() as a null-terminated string when it isn't, not implementing any kind of buffering to handle message framing in either direction, etc...
– Remy Lebeau
Nov 9 at 23:09





This code is not even close to being a viable HTTP server. It is not following any of the rules of the HTTP spec (RFC 2616, and later RFCs 7230-7235). And it makes classic newbie mistakes, like treating the output of recv() as a null-terminated string when it isn't, not implementing any kind of buffering to handle message framing in either direction, etc...
– Remy Lebeau
Nov 9 at 23:09













In any case, the reason a browser can't display your HTML is because you are sending a malformed HTTP response. For instance, your timestamp is being sent as-is without any header name. You are sending 3 rn in between the headers and file body when you need to send only 2. And you are opening the file in text mode instead of binary mode, and not ensuring that the number of bytes you send for the file matches the Content-Length header you are sending.
– Remy Lebeau
Nov 9 at 23:09





In any case, the reason a browser can't display your HTML is because you are sending a malformed HTTP response. For instance, your timestamp is being sent as-is without any header name. You are sending 3 rn in between the headers and file body when you need to send only 2. And you are opening the file in text mode instead of binary mode, and not ensuring that the number of bytes you send for the file matches the Content-Length header you are sending.
– Remy Lebeau
Nov 9 at 23:09













1 Answer
1






active

oldest

votes

















up vote
1
down vote













 memset( buffer, 0, BUFFER_SIZE );
n = read( new_socket_fd, buffer, ( BUFFER_SIZE-1 ) );
if (n==0)
fprintf( stderr, "Connection to client lostnn" );
break;

else if( n < 0 )
fprintf(stderr,"Error reading from socket %sn",
strerror(errno));


/* Print the message we received */
printf("Message received: %sn" ,buffer);


When you call read on a TCP connection, you don't get a message. If you want to receive HTTP messages, you have to write code to do that. This is just broken.



sprintf( send_client, "HTTP/1.0 %s%srnServer: ECE435rn"
"Last-Modified: Fri, 08 Sep 2017 04:31:47 GMTrn"
"Content-Length: 85rnContent-Type: text/htmlrnrn", HTTP__OK, timestamp );


Unless the file just happens to contain exactly 85 bytes, sending a "Content-Length" header is not a particulary good idea.



You have a while(1) loop that seems to be trying to receive multiple messages over a single connection. But there's no code to determine when you've actually received an HTTP request, so that's definitely not going to work.



The HTTP protocol is complicated and writing code to implement it correctly requires going through the standard and implementing everything that is required by the standard. This code doesn't do that and if it actually does work, it will be mostly by luck.



You may get away with just modifying the "Content-Length" header to have the correct length. But you're still violating lots of rules. For example, you could easily wind up sending more than one response to a single request because you do not ensure that read returned an entire HTTP request.






share|improve this answer




















  • David, the read line there was how I was getting the file request from LYNX when I specifically request test.html using: localhost:8080/test.html It does actually provide me with the HTTP client request.
    – Robert
    Nov 9 at 23:36










  • @Robert As I said, if it works, it works by luck. It's not guaranteed to do that since a TCP read has no idea what an HTTP client request is.
    – David Schwartz
    Nov 9 at 23:36










  • I am really wondering why my professor started me with this then... Most of the connection structure other that the port modification was the framework he gave me. I can go in this weekend and attempt to implement everything the HTTP Protocol calls for, but I feel like my head is going to split from not being familiar with C doing that.
    – Robert
    Nov 9 at 23:53











  • @Robert Unfortunately, if you want to receive an HTTP request, you'll have to write code that receives an HTTP request. It's not simple. But the short version is that you need to keep calling read, appending the data onto a buffer, until the buffer contains a complete HTTP request. Depending on why you're doing this, it may make sense to use an existing HTTP parser.
    – David Schwartz
    Nov 9 at 23:56










Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53234273%2fc-socket-webserver-not-displaying-html-in-browser-only-sending-http-response%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
1
down vote













 memset( buffer, 0, BUFFER_SIZE );
n = read( new_socket_fd, buffer, ( BUFFER_SIZE-1 ) );
if (n==0)
fprintf( stderr, "Connection to client lostnn" );
break;

else if( n < 0 )
fprintf(stderr,"Error reading from socket %sn",
strerror(errno));


/* Print the message we received */
printf("Message received: %sn" ,buffer);


When you call read on a TCP connection, you don't get a message. If you want to receive HTTP messages, you have to write code to do that. This is just broken.



sprintf( send_client, "HTTP/1.0 %s%srnServer: ECE435rn"
"Last-Modified: Fri, 08 Sep 2017 04:31:47 GMTrn"
"Content-Length: 85rnContent-Type: text/htmlrnrn", HTTP__OK, timestamp );


Unless the file just happens to contain exactly 85 bytes, sending a "Content-Length" header is not a particulary good idea.



You have a while(1) loop that seems to be trying to receive multiple messages over a single connection. But there's no code to determine when you've actually received an HTTP request, so that's definitely not going to work.



The HTTP protocol is complicated and writing code to implement it correctly requires going through the standard and implementing everything that is required by the standard. This code doesn't do that and if it actually does work, it will be mostly by luck.



You may get away with just modifying the "Content-Length" header to have the correct length. But you're still violating lots of rules. For example, you could easily wind up sending more than one response to a single request because you do not ensure that read returned an entire HTTP request.






share|improve this answer




















  • David, the read line there was how I was getting the file request from LYNX when I specifically request test.html using: localhost:8080/test.html It does actually provide me with the HTTP client request.
    – Robert
    Nov 9 at 23:36










  • @Robert As I said, if it works, it works by luck. It's not guaranteed to do that since a TCP read has no idea what an HTTP client request is.
    – David Schwartz
    Nov 9 at 23:36










  • I am really wondering why my professor started me with this then... Most of the connection structure other that the port modification was the framework he gave me. I can go in this weekend and attempt to implement everything the HTTP Protocol calls for, but I feel like my head is going to split from not being familiar with C doing that.
    – Robert
    Nov 9 at 23:53











  • @Robert Unfortunately, if you want to receive an HTTP request, you'll have to write code that receives an HTTP request. It's not simple. But the short version is that you need to keep calling read, appending the data onto a buffer, until the buffer contains a complete HTTP request. Depending on why you're doing this, it may make sense to use an existing HTTP parser.
    – David Schwartz
    Nov 9 at 23:56














up vote
1
down vote













 memset( buffer, 0, BUFFER_SIZE );
n = read( new_socket_fd, buffer, ( BUFFER_SIZE-1 ) );
if (n==0)
fprintf( stderr, "Connection to client lostnn" );
break;

else if( n < 0 )
fprintf(stderr,"Error reading from socket %sn",
strerror(errno));


/* Print the message we received */
printf("Message received: %sn" ,buffer);


When you call read on a TCP connection, you don't get a message. If you want to receive HTTP messages, you have to write code to do that. This is just broken.



sprintf( send_client, "HTTP/1.0 %s%srnServer: ECE435rn"
"Last-Modified: Fri, 08 Sep 2017 04:31:47 GMTrn"
"Content-Length: 85rnContent-Type: text/htmlrnrn", HTTP__OK, timestamp );


Unless the file just happens to contain exactly 85 bytes, sending a "Content-Length" header is not a particulary good idea.



You have a while(1) loop that seems to be trying to receive multiple messages over a single connection. But there's no code to determine when you've actually received an HTTP request, so that's definitely not going to work.



The HTTP protocol is complicated and writing code to implement it correctly requires going through the standard and implementing everything that is required by the standard. This code doesn't do that and if it actually does work, it will be mostly by luck.



You may get away with just modifying the "Content-Length" header to have the correct length. But you're still violating lots of rules. For example, you could easily wind up sending more than one response to a single request because you do not ensure that read returned an entire HTTP request.






share|improve this answer




















  • David, the read line there was how I was getting the file request from LYNX when I specifically request test.html using: localhost:8080/test.html It does actually provide me with the HTTP client request.
    – Robert
    Nov 9 at 23:36










  • @Robert As I said, if it works, it works by luck. It's not guaranteed to do that since a TCP read has no idea what an HTTP client request is.
    – David Schwartz
    Nov 9 at 23:36










  • I am really wondering why my professor started me with this then... Most of the connection structure other that the port modification was the framework he gave me. I can go in this weekend and attempt to implement everything the HTTP Protocol calls for, but I feel like my head is going to split from not being familiar with C doing that.
    – Robert
    Nov 9 at 23:53











  • @Robert Unfortunately, if you want to receive an HTTP request, you'll have to write code that receives an HTTP request. It's not simple. But the short version is that you need to keep calling read, appending the data onto a buffer, until the buffer contains a complete HTTP request. Depending on why you're doing this, it may make sense to use an existing HTTP parser.
    – David Schwartz
    Nov 9 at 23:56












up vote
1
down vote










up vote
1
down vote









 memset( buffer, 0, BUFFER_SIZE );
n = read( new_socket_fd, buffer, ( BUFFER_SIZE-1 ) );
if (n==0)
fprintf( stderr, "Connection to client lostnn" );
break;

else if( n < 0 )
fprintf(stderr,"Error reading from socket %sn",
strerror(errno));


/* Print the message we received */
printf("Message received: %sn" ,buffer);


When you call read on a TCP connection, you don't get a message. If you want to receive HTTP messages, you have to write code to do that. This is just broken.



sprintf( send_client, "HTTP/1.0 %s%srnServer: ECE435rn"
"Last-Modified: Fri, 08 Sep 2017 04:31:47 GMTrn"
"Content-Length: 85rnContent-Type: text/htmlrnrn", HTTP__OK, timestamp );


Unless the file just happens to contain exactly 85 bytes, sending a "Content-Length" header is not a particulary good idea.



You have a while(1) loop that seems to be trying to receive multiple messages over a single connection. But there's no code to determine when you've actually received an HTTP request, so that's definitely not going to work.



The HTTP protocol is complicated and writing code to implement it correctly requires going through the standard and implementing everything that is required by the standard. This code doesn't do that and if it actually does work, it will be mostly by luck.



You may get away with just modifying the "Content-Length" header to have the correct length. But you're still violating lots of rules. For example, you could easily wind up sending more than one response to a single request because you do not ensure that read returned an entire HTTP request.






share|improve this answer












 memset( buffer, 0, BUFFER_SIZE );
n = read( new_socket_fd, buffer, ( BUFFER_SIZE-1 ) );
if (n==0)
fprintf( stderr, "Connection to client lostnn" );
break;

else if( n < 0 )
fprintf(stderr,"Error reading from socket %sn",
strerror(errno));


/* Print the message we received */
printf("Message received: %sn" ,buffer);


When you call read on a TCP connection, you don't get a message. If you want to receive HTTP messages, you have to write code to do that. This is just broken.



sprintf( send_client, "HTTP/1.0 %s%srnServer: ECE435rn"
"Last-Modified: Fri, 08 Sep 2017 04:31:47 GMTrn"
"Content-Length: 85rnContent-Type: text/htmlrnrn", HTTP__OK, timestamp );


Unless the file just happens to contain exactly 85 bytes, sending a "Content-Length" header is not a particulary good idea.



You have a while(1) loop that seems to be trying to receive multiple messages over a single connection. But there's no code to determine when you've actually received an HTTP request, so that's definitely not going to work.



The HTTP protocol is complicated and writing code to implement it correctly requires going through the standard and implementing everything that is required by the standard. This code doesn't do that and if it actually does work, it will be mostly by luck.



You may get away with just modifying the "Content-Length" header to have the correct length. But you're still violating lots of rules. For example, you could easily wind up sending more than one response to a single request because you do not ensure that read returned an entire HTTP request.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 9 at 23:02









David Schwartz

134k14139220




134k14139220











  • David, the read line there was how I was getting the file request from LYNX when I specifically request test.html using: localhost:8080/test.html It does actually provide me with the HTTP client request.
    – Robert
    Nov 9 at 23:36










  • @Robert As I said, if it works, it works by luck. It's not guaranteed to do that since a TCP read has no idea what an HTTP client request is.
    – David Schwartz
    Nov 9 at 23:36










  • I am really wondering why my professor started me with this then... Most of the connection structure other that the port modification was the framework he gave me. I can go in this weekend and attempt to implement everything the HTTP Protocol calls for, but I feel like my head is going to split from not being familiar with C doing that.
    – Robert
    Nov 9 at 23:53











  • @Robert Unfortunately, if you want to receive an HTTP request, you'll have to write code that receives an HTTP request. It's not simple. But the short version is that you need to keep calling read, appending the data onto a buffer, until the buffer contains a complete HTTP request. Depending on why you're doing this, it may make sense to use an existing HTTP parser.
    – David Schwartz
    Nov 9 at 23:56
















  • David, the read line there was how I was getting the file request from LYNX when I specifically request test.html using: localhost:8080/test.html It does actually provide me with the HTTP client request.
    – Robert
    Nov 9 at 23:36










  • @Robert As I said, if it works, it works by luck. It's not guaranteed to do that since a TCP read has no idea what an HTTP client request is.
    – David Schwartz
    Nov 9 at 23:36










  • I am really wondering why my professor started me with this then... Most of the connection structure other that the port modification was the framework he gave me. I can go in this weekend and attempt to implement everything the HTTP Protocol calls for, but I feel like my head is going to split from not being familiar with C doing that.
    – Robert
    Nov 9 at 23:53











  • @Robert Unfortunately, if you want to receive an HTTP request, you'll have to write code that receives an HTTP request. It's not simple. But the short version is that you need to keep calling read, appending the data onto a buffer, until the buffer contains a complete HTTP request. Depending on why you're doing this, it may make sense to use an existing HTTP parser.
    – David Schwartz
    Nov 9 at 23:56















David, the read line there was how I was getting the file request from LYNX when I specifically request test.html using: localhost:8080/test.html It does actually provide me with the HTTP client request.
– Robert
Nov 9 at 23:36




David, the read line there was how I was getting the file request from LYNX when I specifically request test.html using: localhost:8080/test.html It does actually provide me with the HTTP client request.
– Robert
Nov 9 at 23:36












@Robert As I said, if it works, it works by luck. It's not guaranteed to do that since a TCP read has no idea what an HTTP client request is.
– David Schwartz
Nov 9 at 23:36




@Robert As I said, if it works, it works by luck. It's not guaranteed to do that since a TCP read has no idea what an HTTP client request is.
– David Schwartz
Nov 9 at 23:36












I am really wondering why my professor started me with this then... Most of the connection structure other that the port modification was the framework he gave me. I can go in this weekend and attempt to implement everything the HTTP Protocol calls for, but I feel like my head is going to split from not being familiar with C doing that.
– Robert
Nov 9 at 23:53





I am really wondering why my professor started me with this then... Most of the connection structure other that the port modification was the framework he gave me. I can go in this weekend and attempt to implement everything the HTTP Protocol calls for, but I feel like my head is going to split from not being familiar with C doing that.
– Robert
Nov 9 at 23:53













@Robert Unfortunately, if you want to receive an HTTP request, you'll have to write code that receives an HTTP request. It's not simple. But the short version is that you need to keep calling read, appending the data onto a buffer, until the buffer contains a complete HTTP request. Depending on why you're doing this, it may make sense to use an existing HTTP parser.
– David Schwartz
Nov 9 at 23:56




@Robert Unfortunately, if you want to receive an HTTP request, you'll have to write code that receives an HTTP request. It's not simple. But the short version is that you need to keep calling read, appending the data onto a buffer, until the buffer contains a complete HTTP request. Depending on why you're doing this, it may make sense to use an existing HTTP parser.
– David Schwartz
Nov 9 at 23:56

















 

draft saved


draft discarded















































 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53234273%2fc-socket-webserver-not-displaying-html-in-browser-only-sending-http-response%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Darth Vader #20

How to how show current date and time by default on contact form 7 in WordPress without taking input from user in datetimepicker

Ondo