long rtplatform_read(int fd, unsigned char RTSMB_FAR * buf, long count) { long rv; rv = rtp_file_read ((RTP_HANDLE) fd, buf, count); if (rv < 0) { return -1; } return rv; }
/** @memo Read from a file to buffer. @doc Reads n items of size len from the current position in the rtpfile and stores them in buffer. @precondition Should not mix rtp_stdio_fread and rtp_stdio_fgets calls. @return Number of items read, 0 if end of file, -1 on error, and -2 on non-fatal error. */ long rtp_stdio_fread ( void * buffer, /** Buffer to store the read items. */ unsigned long len, /** Size of items to read. */ unsigned long n, /** Number of items to read. */ void * rtpfile /** Handle of file to be read. */ ) { int result = (-1); if( !rtpfile || (((RTP_STDIO_FILE *)rtpfile)->verify != RTP_FILE_VERIFICATION_VALUE) ) { /* --------------------------------------- */ /* Application passed an RTP_HANDLE */ /* instead of an RTP_STDIO_FILE. Should */ /* use low level rtp_file_read(). */ /* --------------------------------------- */ return ((long) -1); } if (((RTP_STDIO_FILE *)rtpfile)->handle) { result = rtp_file_read (((RTP_STDIO_FILE *)rtpfile)->handle, (unsigned char *) buffer, (unsigned int) (len * n)); if (result > 0) { result /= len; } } if (result == 0) { /* --------------------------------------- */ /* End of file reached, indicate this in */ /* the RTP_STDIO_FILE and return. */ /* --------------------------------------- */ ((RTP_STDIO_FILE *)rtpfile)->eofBool = 1; } return ((long) result); }
/** @memo Read lines from a file to a buffer. @doc Read lines from a file to buf or if the end of the file or the line has not been reached yet, reads (buflen-1) of data. @precondition Should not mix rtp_stdio_fread and rtpstdio_fgets calls. @return Number of bytes written, -1 otherwise. */ int rtp_stdio_fgets ( char * buf, /** Buffer to store the read. */ int buflen, /** Number of bytes to read. */ void * rtpfile /** Handle of file to be read. */ ) { if( !rtpfile || (((RTP_STDIO_FILE *)rtpfile)->verify != RTP_FILE_VERIFICATION_VALUE) ) { /* --------------------------------------- */ /* Application passed an RTP_HANDLE */ /* instead of an RTP_STDIO_FILE. Should */ /* use low level rtp_file_read(). */ /* --------------------------------------- */ return ((long) -1); } if (buflen <= 0) { return (-1); } buflen--; if ( !(((RTP_STDIO_FILE *)rtpfile)->buffer) ) { /* --------------------------------------- */ /* Allocate buffer. If successful, use it. */ /* --------------------------------------- */ /* --------------------------------------- */ /* Assume no line is larger than */ /* RTP_READLINE_BUFFER characters. Then we */ /* can use a buffer RTP_READLINE_BUFFER */ /* bytes and only read that many bytes at */ /* a time to speed up reading. */ /* --------------------------------------- */ ((RTP_STDIO_FILE *)rtpfile)->buffer = (char *) rtp_malloc ((unsigned int)RTP_READLINE_BUFFER, 0); /* SPRZ */ if (((RTP_STDIO_FILE *)rtpfile)->buffer) { ((RTP_STDIO_FILE *)rtpfile)->bufsiz = RTP_READLINE_BUFFER; } /* --------------------------------------- */ /* ((RTP_STDIO_FILE *)rtpfile)->bufpos = 0;*/ /* ((RTP_STDIO_FILE *)rtpfile)->buffil = 0;*/ /* --------------------------------------- */ } while (((RTP_STDIO_FILE *)rtpfile)->buffer) { int i; int n; if (buflen == 0) { buf[0] = 0; return (0); } /* --------------------------------------- */ /* check if we still got a line worth in */ /* there... */ /* --------------------------------------- */ for (i = ((RTP_STDIO_FILE *)rtpfile)->bufpos; i < ((RTP_STDIO_FILE *)rtpfile)->buffil; i++) { if (((RTP_STDIO_FILE *)rtpfile)->buffer[i] == '\n') { /* --------------------------------------- */ /* Have a line. */ /* --------------------------------------- */ i = i + 1 - ((RTP_STDIO_FILE *)rtpfile)->bufpos; if (buflen < i) { i = buflen; } rtp_memmove(buf, ((RTP_STDIO_FILE *)rtpfile)->buffer + ((RTP_STDIO_FILE *)rtpfile)->bufpos, i); ((RTP_STDIO_FILE *)rtpfile)->bufpos += i; buf[i] = 0; return (i); } } /* --------------------------------------- */ /* no more lines in buffer: get new data */ /* in there. FIRST: move what we've got */ /* to front. */ /* --------------------------------------- */ if (((RTP_STDIO_FILE *)rtpfile)->bufpos < ((RTP_STDIO_FILE *)rtpfile)->buffil) { rtp_memmove(((RTP_STDIO_FILE *)rtpfile)->buffer, ((RTP_STDIO_FILE *)rtpfile)->buffer + ((RTP_STDIO_FILE *)rtpfile)->bufpos, ((RTP_STDIO_FILE *)rtpfile)->buffil - ((RTP_STDIO_FILE *)rtpfile)->bufpos); ((RTP_STDIO_FILE *)rtpfile)->buffil -= ((RTP_STDIO_FILE *)rtpfile)->bufpos; ((RTP_STDIO_FILE *)rtpfile)->bufpos = 0; } else { ((RTP_STDIO_FILE *)rtpfile)->buffil = 0; ((RTP_STDIO_FILE *)rtpfile)->bufpos = 0; } /* --------------------------------------- */ /* Get more data. Assume we don't mix */ /* fgets() with fread(). */ /* --------------------------------------- */ if (((((RTP_STDIO_FILE *)rtpfile)->bufsiz - ((RTP_STDIO_FILE *)rtpfile)->buffil) & ~(RTP_READLINE_BUFFER-1)) > 0) { /* --------------------------------------- */ /* load alligned: sector */ /* --------------------------------------- */ n = rtp_file_read (((RTP_STDIO_FILE *)rtpfile)->handle, (unsigned char *) ((RTP_STDIO_FILE *)rtpfile)->buffer + ((RTP_STDIO_FILE *)rtpfile)->buffil, (unsigned int) ((((RTP_STDIO_FILE *)rtpfile)->bufsiz - ((RTP_STDIO_FILE *)rtpfile)->buffil) & ~(RTP_READLINE_BUFFER-1))); if (n > 0) { ((RTP_STDIO_FILE *)rtpfile)->buffil += n; /* --------------------------------------- */ /* check if we got a line worth in there. */ /* --------------------------------------- */ for (i = ((RTP_STDIO_FILE *)rtpfile)->bufpos; i < ((RTP_STDIO_FILE *)rtpfile)->buffil; i++) { if (((RTP_STDIO_FILE *)rtpfile)->buffer[i] == '\n') { /* --------------------------------------- */ /* Have line. */ /* --------------------------------------- */ i = i + 1 - ((RTP_STDIO_FILE *)rtpfile)->bufpos; if (buflen < i) { i = buflen; } rtp_memmove(buf, ((RTP_STDIO_FILE *)rtpfile)->buffer + ((RTP_STDIO_FILE *)rtpfile)->bufpos, i); ((RTP_STDIO_FILE *)rtpfile)->bufpos += i; buf[i] = 0; return (i); } } } } /* --------------------------------------- */ /* load as much as possible. */ /* --------------------------------------- */ if (((RTP_STDIO_FILE *)rtpfile)->bufsiz > ((RTP_STDIO_FILE *)rtpfile)->buffil) { /* --------------------------------------- */ /* load UNalligned */ /* --------------------------------------- */ n = rtp_file_read (((RTP_STDIO_FILE *)rtpfile)->handle, (unsigned char *) ((RTP_STDIO_FILE *)rtpfile)->buffer + ((RTP_STDIO_FILE *)rtpfile)->buffil, (unsigned int) (((RTP_STDIO_FILE *)rtpfile)->bufsiz - ((RTP_STDIO_FILE *)rtpfile)->buffil)); if (n > 0) { ((RTP_STDIO_FILE *)rtpfile)->buffil += n; /* --------------------------------------- */ /* check if we got a line worth in there. */ /* --------------------------------------- */ for (i = ((RTP_STDIO_FILE *)rtpfile)->bufpos; i < ((RTP_STDIO_FILE *)rtpfile)->buffil; i++) { if (((RTP_STDIO_FILE *)rtpfile)->buffer[i] == '\n') { /* --------------------------------------- */ /* Have line. */ /* --------------------------------------- */ i = i + 1 - ((RTP_STDIO_FILE *)rtpfile)->bufpos; if (buflen < i) { i = buflen; } rtp_memmove(buf, ((RTP_STDIO_FILE *)rtpfile)->buffer + ((RTP_STDIO_FILE *)rtpfile)->bufpos, i); ((RTP_STDIO_FILE *)rtpfile)->bufpos += i; buf[i] = 0; return (i); } } } } /* --------------------------------------- */ /* If we get here, the line is too long or */ /* we're stuck with the last line, which */ /* is NOT '\n' terminated. */ /* --------------------------------------- */ if (((RTP_STDIO_FILE *)rtpfile)->buffil > ((RTP_STDIO_FILE *)rtpfile)->bufpos) { i = ((RTP_STDIO_FILE *)rtpfile)->buffil - ((RTP_STDIO_FILE *)rtpfile)->bufpos; if (buflen < i) { i = buflen; } rtp_memmove(buf, ((RTP_STDIO_FILE *)rtpfile)->buffer + ((RTP_STDIO_FILE *)rtpfile)->bufpos, i); ((RTP_STDIO_FILE *)rtpfile)->bufpos += i; buf[i] = 0; /* --------------------------------------- */ /* This may be part of a very large line. */ /* So correct pointers and everything and */ /* loop. */ /* --------------------------------------- */ buflen -= i; buf += i; if (buflen == 0) { return (0); } } /* --------------------------------------- */ /* We just copied the remains of our */ /* buffer into the user buffer. Set pos to */ /* 0 and try one last ALLIGNED load to see */ /* if we still got data coming in. But */ /* shift remaining data, if any, to FRONT */ /* first. */ /* --------------------------------------- */ if (((RTP_STDIO_FILE *)rtpfile)->bufpos < ((RTP_STDIO_FILE *)rtpfile)->buffil) { rtp_memmove(((RTP_STDIO_FILE *)rtpfile)->buffer, ((RTP_STDIO_FILE *)rtpfile)->buffer + ((RTP_STDIO_FILE *)rtpfile)->bufpos, ((RTP_STDIO_FILE *)rtpfile)->buffil - ((RTP_STDIO_FILE *)rtpfile)->bufpos); ((RTP_STDIO_FILE *)rtpfile)->buffil -= ((RTP_STDIO_FILE *)rtpfile)->bufpos; ((RTP_STDIO_FILE *)rtpfile)->bufpos = 0; } else { ((RTP_STDIO_FILE *)rtpfile)->buffil = 0; ((RTP_STDIO_FILE *)rtpfile)->bufpos = 0; } /* --------------------------------------- */ /* Get more data. And check if there's any */ /* left. */ /* --------------------------------------- */ /* --------------------------------------- */ /* load alligned: sector */ /* --------------------------------------- */ n = rtp_file_read (((RTP_STDIO_FILE *)rtpfile)->handle, (unsigned char *) ((RTP_STDIO_FILE *)rtpfile)->buffer + ((RTP_STDIO_FILE *)rtpfile)->buffil, (unsigned int) ((((RTP_STDIO_FILE *)rtpfile)->bufsiz - ((RTP_STDIO_FILE *)rtpfile)->buffil) & ~(RTP_READLINE_BUFFER-1))); if (n > 0) { ((RTP_STDIO_FILE *)rtpfile)->buffil += n; } else { /* --------------------------------------- */ /* EOF reached and buffer empty. */ /* --------------------------------------- */ ((RTP_STDIO_FILE *)rtpfile)->eofBool = 1; ((RTP_STDIO_FILE *)rtpfile)->buffer = 0; return (0); } /* --------------------------------------- */ /* we get here, iff we are reading a very */ /* long line that is larger than our */ /* '((RTP_STDIO_FILE *)rtpfile)->buffer': */ /* add next piece to output 'buf'. */ /* --------------------------------------- */ } return (-1); }
static int http_client_put(HTTPManagedClient* phttpClient) { HTTPManagedClientSession* session = 0; char urlpath[255]; char urlfile[255]; char localfile[255]; char contenttype[255]; HTTP_INT32 result = -1; HTTP_INT32 totalresult = 0; HTTPResponseInfo info; HTTP_INT32 contentLength; RTP_HANDLE fd; HTTP_INT32 nread; rtp_strcpy(contenttype, "application/x-www-form-urlencoded"); /* content-type */ rtp_gui_prompt_text(" ","IP Address (eg: 192.161.2.1) or domain name of host (eg: www.google.com)\n :", &urlpath[0]); rtp_gui_prompt_text(" ","File name on server\n :", &urlfile[0]); rtp_gui_prompt_text(" ","Local file name to put\n :", &localfile[0]); rtp_gui_prompt_text(" ","Content type eg: text/html\n :", &contenttype[0]); contentLength = 0; /* Set content length to zero so we use chunked encoding */ /* A HTTPManagedClientSession is the abstraction for a SINGLE HTTP request/response pair. Thus a new session must be opened for each HTTP operation (although this may not cause a new connection to be established, if keep alive is used), and closed when the operation has completed (though, again, this may not actually close a physical network connection) */ if (HTTP_ManagedClientStartTransaction ( phttpClient, &urlpath[0], 80, 4, HTTP_SESSION_TYPE_TCP, 1, /* blocking? */ &session ) < 0) { rtp_printf("Failed: connecting to %s\n", urlpath); return(-1); } /* Once the session is open, one command may be issued; in this case a Post */ HTTP_ManagedClientPut ( session, urlfile, /* path */ contenttype, contentLength /* content-length */ ); if (rtp_file_open (&fd, (const char *) &localfile[0], RTP_FILE_O_RDONLY, 0) < 0) { rtp_printf("Failure opening %s\n", localfile); return(-1); } /* write the POST data */ do { nread = rtp_file_read(fd,read_buffer, (long)read_buffer_size); if (nread > 0) HTTP_ManagedClientWrite (session, (HTTP_UINT8*) &read_buffer[0], nread); } while (nread >= 0); /* this function must be called when all data has been written */ HTTP_ManagedClientWriteDone (session); /* This may be called at any time after the command is issued to get information about the server response; this info includes the status code given, date when the request was processed, file mime type information (if a file is transferred as the result of a command), authentication information, etc. */ HTTP_ManagedClientReadResponseInfo(session, &info); do { /* Read data from the session */ result = HTTP_ManagedClientRead(session, read_buffer, read_buffer_size); } while (result > 0); /* Now we are done; close the session (see note above about sessions) */ HTTP_ManagedClientCloseSession(session); /* When all HTTP client activity is completed, the managed client context may safely be destroyed */ HTTP_ManagedClientDestroy(phttpClient); rtp_file_close(fd); if (result == 0) { rtp_printf("Success: putting file: %s to %s%s\n", localfile, urlpath, urlfile); return(0); } else { rtp_printf("Failed: putting file: %s to %s%s\n", localfile, urlpath, urlfile); return(-1); } }
/*---------------------------------------------------------------------------*/ static int __HTTP_ServerHandleRequest (HTTPServerRequestContext *ctx, HTTPSession *session, HTTPRequest *request, RTP_NET_ADDR *clientAddr, HTTPVirtualFileInfo *vfile) { HTTP_CHAR fsPath[HTTP_SERVER_PATH_LEN]; HTTPServerContext *server = ctx->server; switch (request->methodType) { case HTTP_METHOD_GET: { HTTPResponse response; RTP_FILE fd; HTTP_INT32 bytesRead, bufferSize = 1024; HTTP_INT32 bytesleft=0; HTTP_UINT8 buffer[1024]; FileContentType contentType; unsigned chunked = 0; unsigned found = 0; const HTTP_UINT8 *pdata; if (vfile) { pdata=vfile->data; bytesleft = vfile->size; } if (vfile) { HTTP_ServerReadHeaders( ctx, session, _HTTP_VirtualFileProcessHeader, 0, buffer, bufferSize ); found = 1; } else { _HTTP_ServerReadHeaders(ctx, session, 0, 0, buffer, bufferSize); _HTTP_ConstructLocalPath(server, fsPath, (HTTP_CHAR *) request->target, HTTP_SERVER_PATH_LEN); if (rtp_file_open(&fd, fsPath, RTP_FILE_O_BINARY|RTP_FILE_O_RDONLY, RTP_FILE_S_IREAD) < 0) { if ((server->defaultFile) && (server->defaultFile[0]) && (fsPath[0]=='\0'||(fsPath[rtp_strlen(fsPath)-1] == '\\') || (fsPath[rtp_strlen(fsPath)-1] == '/'))) { if ((HTTP_SERVER_PATH_LEN - rtp_strlen(server->defaultFile)) > rtp_strlen(server->defaultFile)) { rtp_strcat(fsPath, server->defaultFile); if (rtp_file_open(&fd, fsPath, RTP_FILE_O_BINARY|RTP_FILE_O_RDONLY, RTP_FILE_S_IREAD) >= 0) { found = 1; } } } } else found = 1; } if (!found) { _HTTP_ServerSendError(ctx, session, 404, "Not Found"); return (0); } _HTTP_ServerInitResponse(ctx, session, &response, 200, "OK"); _HTTP_ServerSetDefaultHeaders(ctx, &response); if (vfile) { HTTP_SetResponseHeaderStr(&response, "Content-Type", vfile->contentType); if (vfile->contentEncoding) { HTTP_SetResponseHeaderStr(&response, "Content-Encoding", vfile->contentEncoding); } HTTP_SetResponseHeaderTime(&response, "Last-Modified", &vfile->creationTime); } else { contentType = GetFileTypeByExtension(fsPath); if (contentType != FILE_TYPE_UNKNOWN) { HTTP_SetResponseHeaderStr(&response, "Content-Type", FileContentTypeToStr(contentType)); } } if (ctx->keepAlive) { if (request->httpMajorVersion > 1 || (request->httpMajorVersion == 1 && request->httpMinorVersion >= 1)) { HTTP_SetResponseHeaderStr(&response, "Transfer-Encoding", "chunked"); chunked = 1; } else { void* dirobj; unsigned long fileSize; if (vfile) { fileSize = vfile->size; } else { if (rtp_file_gfirst(&dirobj, fsPath) < 0) { _HTTP_ServerSendError(ctx, session, 500, "Internal Server Error"); HTTP_FreeResponse(&response); rtp_file_close(fd); return (-1); } if (rtp_file_get_size(dirobj, &fileSize) < 0) { _HTTP_ServerSendError(ctx, session, 500, "Internal Server Error"); HTTP_FreeResponse(&response); rtp_file_gdone(dirobj); rtp_file_close(fd); return (-1); } rtp_file_gdone(dirobj); } HTTP_SetResponseHeaderInt(&response, "Content-Length", fileSize); } } HTTP_WriteResponse(session, &response); HTTP_FreeResponse(&response); do { #define EBSMIN(X,Y) ((X)<(Y)?(X):(Y)) if (vfile) { bytesRead=EBSMIN(bufferSize,bytesleft); rtp_memcpy(buffer,pdata,bytesRead); bytesleft -= bytesRead; pdata += bytesRead; } else bytesRead = rtp_file_read(fd, buffer, bufferSize); if (bytesRead > 0) { if (chunked) { if (HTTP_WriteChunkStart(session, bytesRead) < 0) { break; } } if (HTTP_Write(session, buffer, bytesRead) < bytesRead) { break; } if (chunked) { if (HTTP_WriteChunkEnd(session) < 0) { break; } } } } while (bytesRead > 0); /* this tells the client the transfer is complete */ if (chunked) { HTTP_WriteChunkStart(session, 0); HTTP_WriteChunkEnd(session); } HTTP_WriteFlush(session); if (!vfile) rtp_file_close(fd); break; } default: break; } return (0); }