/
Inicio :: Foros

 F.A.Q.F.A.Q.                  Conéctese para revisar sus mensajesConéctese para revisar sus mensajes   

Comunicación HTTP

 
      Índice del Foro elrincondelc.com -> Programación en Servidores
Ver tema anterior :: Ver siguiente tema  
AutorMensaje
Sorancio



Registrado: 29 May 2009
Mensajes: 1157
Ubicación: España

MensajePublicado: 22/08/2009 1:10 pm
Título: Comunicación HTTP

¡Hola! Estoy intentando hacer un pequeño navegador para practicar un poco, pero me he encallado en comunicación con el servidor. Yo le envío los datos, pero no contesta, creo que es un problema en la creación de la salida. Estoy usando C bajo el entorno Code::Blocks en Ubuntu, con el compilador GCC.

Aquí dejo el código:

network/httpmessages.c
Código:

struct http_message *build_http_message(const u8 type, const char *fline)
{
        struct http_message *msg = cmalloc(sizeof(*msg));
        msg->type = type;

        u16 it = 0;
        u16 tmpit = 0;

        char tmp[80];

        while (fline[it]){
                if(fline[it] == ' '){
                        if(tmpit){
                                msg->params[0] = cmalloc(tmpit);
                                memcpy(msg->params[0], tmp, tmpit);

                                tmpit = 0;
                        }

                        it++;
                        continue;
                }

                tmp[tmpit] = fline[it];
                tmpit++;
                it++;
        }

        msg->params[1] = cmalloc(tmpit);
        memcpy(msg->params[1], tmp, tmpit);

        msg->headers = malloc(sizeof(*msg->headers));
        msg->hlen = 0;

        return msg;
}

void add_http_header(struct http_message *message, const char *hstr)
{
        struct http_header *header = cmalloc(sizeof(*header));
        u32 len = strchr(hstr, ':');

        if(!len){
                clog_open_write();
                clog_write("\tMalformed HTTP Header.\nMessage: %i %s %s\nHeader:"
                " %s", message->type, message->params[0], message->params[1],
                hstr);
                clog_close();

                free(header);
                return;
        }

        len -= (u32)hstr;
        header->header = cmalloc(len);
        memcpy(header->header, hstr, len);

        char *strit = hstr + len + 2; // the next char of ':'

        while (*strit == ' ' || *strit == '\t'
            || *strit == _CR || *strit == _LF && *strit){
                strit++;
        }

        len = strlen(strit);
        header->value = cmalloc(len);
        memcpy(header->value, strit, len);

        message->headers[message->hlen] = header;
        message->hlen++;

}

void set_http_body(struct http_message *message,
                   const char *type, const char *body)
{
        if (message->body){
                free(message->body->type);
                free(message->body->output);
                free(message->body);
        }

        message->body = cmalloc(sizeof(*message->body));
        message->body->type = cmalloc(strlen(type));
        strcpy(message->body->type, type);

        message->body->length = strlen(body);
        message->body->output = cmalloc(message->body->length);
        strcpy(message->body->output, body);
}

void send_http_message(const csocket const socket,
                   const struct http_message *msg)
{
        const char endline[2] = {_CR, _LF};
        char output[HTTP_MAX_OUTPUT];

        switch (msg->type){
        case HTTP_METHOD_GET:
                strcat(output, "GET ");
        break;
        case HTTP_METHOD_HEAD:
                strcat(output, "HEAD ");
        break;
        case HTTP_METHOD_POST:
                strcat(output, "POST ");
        break;
        }

        strcat(output, msg->params[0]);
        strcat(output, " ");
        strcat(output, msg->params[1]);
        strcat(output, endline);

        u8 hit = 0;

        while (hit < msg->hlen){
                strcat(output, msg->headers[hit]->header);
                strcat(output, ": ");
                strcat(output, msg->headers[hit]->value);
                strcat(output, endline);

                hit++;
        }

        if (msg->body){
                strcat(output, "Content-Type: ");
                strcat(output, msg->body->type);

                strcat(output, endline);

                strcat(output, "Content-Length: ");

                char tmp[10];
                sprintf(tmp, "%u", msg->body->length);

                strcat(output, tmp);
                strcat(output, endline);
                strcat(output, endline);

                strcat(output, msg->body->output);
        }

        csocket_write(socket, strlen(output), output);
}


core/socket.c
Código:

csocket csocket_open(const char const *address, const u16 const port)
{
   struct sockaddr_in sockinfo;
   csocket sock = socket(PF_INET, SOCK_STREAM, 0);

   if (sock == -1){
      return -3;
   }

   sockinfo.sin_family = AF_INET;
   sockinfo.sin_port = htons(port);

   struct hostent *hinf = gethostbyname(address);

   if (!hinf){
           close(sock);
           return -2;
   }

        sockinfo.sin_addr = *(struct in_addr*) hinf->h_addr;

   if (connect(sock, &sockinfo, sizeof(sockinfo)) == -1){
      close(sock);
      return -1;
   }

   return sock;
}


void csocket_close(csocket socket)
{
   shutdown(socket, SHUT_RDWR);
   close(socket);
}

void csocket_write(csocket socket, const u16 const length, void *buf)
{
   register u16 it = 0;

   while (it < length){
      it += write(socket, buf + it, length - it);
   }
}

void    csocket_read(csocket socket, const u16 const length, void *buf)
{
   register u16 it = 0;

   while (it < length){
      it += read(socket, buf + it, length - it);
   }

}


La función main

Código:

int main()
{
        csocket socket = csocket_open("www.google.es", HTTP_DEFAULT_PORT);
        struct http_message *msg = build_http_message(HTTP_METHOD_GET,
                                        "/index.html HTTP/1.1");

        add_http_header(msg, "User-agent: Symphony/0.1");
        send_http_message(socket, msg);

        char tmp[8000];
        csocket_read(socket, 8000, tmp);

        printf("%s", tmp);
}


Muchas gracias de antemano.
Volver arriba
uniom



Registrado: 14 Dic 2009
Mensajes: 5

MensajePublicado: 23/12/2009 8:35 am
Título:

wenas, yo tambien tengo que implementar un servidor web basico y un cliente http, con protocolo http-rc.
Mi S.O. es linux (ubuntu). No se como empezar a hacerlo. Me podrias echar una mano porfavor? esque soy novato y se me hace muy dificil esto.
Venga muchas gracias de adelantado.
Volver arriba
eagleoneraptor



Registrado: 20 May 2008
Mensajes: 187
Ubicación: Buenos Aires(Argentina)

MensajePublicado: 28/12/2009 9:42 pm
Título:

Por lo que veo en la función send_http_message la línea vacía que debería estar entre el encabezado y el cuerpo de la petición SOLO la escribes cuando hay un cuerpo (body) para envíarle al servidor por lo que este no te responderá hasta que envíes el encabezado completo (con la línea vacía al final), creo que si le envías algo de cuerpo (un byte o algo) debería andarte.

Espero que te ayude
Un Saludo!
_________________
"Aquel que hace una bestia de si mismo se libra del dolor de ser un hombre". Dr. Johnson
Volver arriba
      Índice del Foro elrincondelc.com -> Programación en Servidores
Página 1 de 1Todas las horas están en GMT - 8 Horas

 
No puede crear mensajes
No puede responder temas
No puede editar sus mensajes
No puede borrar sus mensajes
No puede votar en encuestas

(c) ElRincondelC.com

Un proyecto de UrlanHeat.com