jamhttp.cpp
来自「This is a resource based on j2me embedde」· C++ 代码 · 共 672 行 · 第 1/2 页
CPP
672 行
/* * @(#)jamHttp.cpp 1.17 06/10/10 10:08:35 * * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. */#include "jam.hpp"#ifdef _WIN32_#include <winsock.h>#endif#ifdef _UNIX_#include <sys/time.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#include <ctype.h>#include <unistd.h>#include <fcntl.h>#include <errno.h>static void closesocket(int fd) { shutdown(fd, 2); close(fd);}#endif#ifdef __SYMBIAN32__#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>typedef size_t socklen_t;static void closesocket(int fd) { shutdown(fd, 2); close(fd); printf("[closed socket %d]", fd);}#endif#define DO_SEND(socket, buf, len, opt) { \ int _retries = 5, _retval; \ do { \ _retval = send(socket, buf, len, opt); \ if (_retval < 0) { \ PlafStatusMsg("send failed: %d"); \ }\ } while (_retval < 0 && _retries-- > 0); \ } #define RECV_TMO 2000/*========================================================================= * Functions *=======================================================================*/static intparseURL(const char* url, char* host, int* port, char* path);static char *fetchURL(const char *host, int port, const char *path, int *httpCodeP, int *contentLengthP, int *retryDelayP, int complain);static char *postURL(const char *host, int port, const char *path, int len, char* data, int *httpCodeP, int *contentLengthP, int *retryDelayP, int complain);/* * Decompose a URL into host, port and part parts. Note that * the query string is not supported. Only "http://" URLs are supported. * * host and path must be of size MAX_URL. * * Returns TRUE if parse is successful, FALSE if it failed. */static intparseURL(const char* url, char* host, int* port, char* path){ char* p; char* start; if (strncmp(url, "http://", 7) != 0) { PlafErrorMsg("bad protocol, must be http://\n"); return FALSE; } /* * Get host name. */ start = p = (char*)url + 7; while (*p && (isalnum((int)*p) || *p == '.' || *p == '-'|| *p == '_')) { p++; } if (p - start >= MAX_BUF) { PlafErrorMsg("bad host name: too long\n"); return FALSE; } strnzcpy(host, start, p-start); /* * Get port number */ if (*p == ':') { char num[10]; p++; start = p; while (isdigit((int)*p)) { p++; } if ((start - p) > 5) { PlafErrorMsg("bad port number\n"); return FALSE; } strnzcpy(num, start, p-start); *port = atoi(num); if (*port <= 0 || *port >= 65535) { PlafErrorMsg("bad port number %d\n", *port); return FALSE; } } else { *port = 80; } /* * Get path */ if (*p == 0) { strcpy(path, "/"); } else if (*p != '/') { PlafErrorMsg("bad path: must start with \"/\"\n"); } else if (strlen(p) >= MAX_BUF) { PlafErrorMsg("bad path: too long\n"); } else { strcpy(path, p); } return TRUE;}/* * Downloads the content of the given URL. The content is returned in * a malloc'ed buffer. NULL is returned in case of error. * * Implement HTTP policy for retransmissions, etc. ... */char*JamHttpGet(const char* url, int* contentLengthP, int complain){ int port; char host[MAX_URL]; char path[MAX_URL]; if (!parseURL(url, host, &port, path)) { return FALSE; } for(;;) { int httpCode, retryDelay = 0; char *content = fetchURL(host, port, path, &httpCode, contentLengthP, &retryDelay, complain); if (httpCode == 200) { return content; } /* In all other cases, the content is NULL and should be ignored */ if (httpCode == 503) { if (retryDelay > 0) { PlafSleep(retryDelay*1000); } continue; } return NULL; }}char *JamHttpPost(const char* url, int buflen, char* buf, int *contentLengthP, int complain){ int port; char host[MAX_URL]; char path[MAX_URL]; if (!parseURL(url, host, &port, path)) { return FALSE; } for(;;) { int httpCode, retryDelay = 0; char *content = postURL(host, port, path, buflen, buf, &httpCode, contentLengthP, &retryDelay, complain); if (httpCode == 200) { return content; } /* In all other cases, the content is NULL and should be ignored */ if (httpCode == 503) { if (retryDelay > 0) { PlafSleep(retryDelay*1000); } continue; } return NULL; } return NULL;}static char *fetchURL(const char *host, int port, const char *path, int *httpCodeP, int *contentLengthP, int *retryDelayP, int complain){ int sock = -1; char buffer[1024]; /* we reuse this for sending and receiving the data */ unsigned int length, contentLength; char *p; char *content = NULL; int readBody; int retcode; /* Let's set the return args to default values */ *httpCodeP = 404; /* unable to make a connection */ *contentLengthP = 0; *retryDelayP = 0; contentLength = 0; /* Open the socket and connect to the server */ { struct hostent* hep; struct sockaddr_in sin; memset((void*)&sin, 0, sizeof (sin)); sin.sin_family = AF_INET; sin.sin_port = htons((short)port); hep = gethostbyname(host); if (hep == NULL) { if (complain) PlafErrorMsg("Unable to resolve host name %s\n", host); return NULL; } memcpy(&sin.sin_addr, hep->h_addr, hep->h_length); sock = socket(PF_INET, SOCK_STREAM, 0); printf("[opened socket %d]", sock); retcode = connect(sock, (struct sockaddr*)&sin, sizeof (sin)); if (retcode < 0) { if (complain) PlafErrorMsg("Unable to connect to %s:%ld\n", host, (long)port); goto error; } } //ret sprintf(buffer, "GET %s HTTP/1.0\r\n\r\n", path); DO_SEND(sock, buffer, strlen(buffer), 0); /* * Read as much as we can into "buffer", upto the size of buffer. * Note that the size of the HTTP header need to be smaller than 1024 * bytes, or else we'd be in trouble. */ memset(buffer, 0, sizeof(buffer)); for (length = 0; length < sizeof(buffer); ) { retcode = recv(sock, buffer + length, sizeof(buffer) - length, 0); if (retcode > 0) { length += retcode; } else if (retcode == 0) { /* EOF */ break; } else { if (complain) PlafErrorMsg("Error reading socket\n"); goto error; } } if (length <= 5) { goto error; } /* We're assuming that the buffer is long enough to hold the complete * header. If not, well something is wrong. */ p = strchr(buffer, ' ') + 1; /* Skip past the first space */ while (*p == ' ') p++; /* Skip additional space */ *httpCodeP = atoi(p); switch(*httpCodeP) { case 200: readBody = TRUE; break; case 503: readBody = FALSE; break; default: if (complain) PlafErrorMsg("%s not available", path); goto error; } p = strchr(p, '\n') + 1; for (;;) { if (*p == '\n') { p++; break;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?