mirror of
https://github.com/sheumann/NetDisk.git
synced 2025-02-17 12:30:32 +00:00
Add and use code to parse URLs specifying the resource.
This commit is contained in:
parent
ef272cb998
commit
28a0b1be19
12
hostname.c
12
hostname.c
@ -7,7 +7,14 @@
|
|||||||
Boolean DoLookupName(Session *sess) {
|
Boolean DoLookupName(Session *sess) {
|
||||||
dnrBuffer dnrInfo;
|
dnrBuffer dnrInfo;
|
||||||
|
|
||||||
TCPIPDNRNameToIP(sess->domainName, &dnrInfo);
|
if (TCPIPValidateIPString(sess->hostName)) {
|
||||||
|
cvtRec cvtInfo;
|
||||||
|
TCPIPConvertIPToHex(&cvtInfo, sess->hostName);
|
||||||
|
sess->ipAddr = cvtInfo.cvtIPAddress;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
TCPIPDNRNameToIP(sess->hostName, &dnrInfo);
|
||||||
if (toolerror())
|
if (toolerror())
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
@ -22,6 +29,9 @@ Boolean DoLookupName(Session *sess) {
|
|||||||
sess->ipAddr = dnrInfo.DNRIPaddress;
|
sess->ipAddr = dnrInfo.DNRIPaddress;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
} else {
|
} else {
|
||||||
|
if (dnrInfo.DNRstatus == DNR_Pending) {
|
||||||
|
TCPIPCancelDNR(&dnrInfo);
|
||||||
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
6
http.c
6
http.c
@ -7,14 +7,14 @@
|
|||||||
#include "session.h"
|
#include "session.h"
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
|
|
||||||
Boolean BuildHTTPRequest(Session *sess, char *resourceStr, char *hostStr) {
|
Boolean BuildHTTPRequest(Session *sess, char *resourceStr) {
|
||||||
int sizeNeeded = 0;
|
int sizeNeeded = 0;
|
||||||
int rangeOffset;
|
int rangeOffset;
|
||||||
int round = 0;
|
int round = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
sizeNeeded = snprintf(sess->httpRequest, sizeNeeded,
|
sizeNeeded = snprintf(sess->httpRequest, sizeNeeded,
|
||||||
"GET %s HTTP/1.1\r\n"
|
"GET /%s HTTP/1.1\r\n"
|
||||||
"Host: %s\r\n"
|
"Host: %s\r\n"
|
||||||
"User-Agent: GSRemoteDisk/0.1\r\n"
|
"User-Agent: GSRemoteDisk/0.1\r\n"
|
||||||
"Accept-Encoding: identity\r\n"
|
"Accept-Encoding: identity\r\n"
|
||||||
@ -23,7 +23,7 @@ Boolean BuildHTTPRequest(Session *sess, char *resourceStr, char *hostStr) {
|
|||||||
"Range: bytes=%n1234567890-1234567890\r\n"
|
"Range: bytes=%n1234567890-1234567890\r\n"
|
||||||
"\r\n",
|
"\r\n",
|
||||||
resourceStr,
|
resourceStr,
|
||||||
hostStr,
|
sess->hostName+1,
|
||||||
&rangeOffset);
|
&rangeOffset);
|
||||||
|
|
||||||
if (sizeNeeded <= 0) {
|
if (sizeNeeded <= 0) {
|
||||||
|
2
http.h
2
http.h
@ -4,7 +4,7 @@
|
|||||||
#include <types.h>
|
#include <types.h>
|
||||||
#include "session.h"
|
#include "session.h"
|
||||||
|
|
||||||
Boolean BuildHTTPRequest(Session *sess, char *resourceStr, char *hostStr);
|
Boolean BuildHTTPRequest(Session *sess, char *resourceStr);
|
||||||
void UpdateRequestRange(Session *sess, unsigned long start, unsigned long end);
|
void UpdateRequestRange(Session *sess, unsigned long start, unsigned long end);
|
||||||
|
|
||||||
#endif
|
#endif
|
85
main.c
85
main.c
@ -5,8 +5,10 @@
|
|||||||
#include <locator.h>
|
#include <locator.h>
|
||||||
#include <misctool.h>
|
#include <misctool.h>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
|
#include <orca.h>
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
#include "session.h"
|
#include "session.h"
|
||||||
|
#include "seturl.h"
|
||||||
#include "hostname.h"
|
#include "hostname.h"
|
||||||
|
|
||||||
#define buffTypePointer 0x0000 /* For TCPIPReadTCP() */
|
#define buffTypePointer 0x0000 /* For TCPIPReadTCP() */
|
||||||
@ -21,38 +23,48 @@ http://ia800505.us.archive.org/16/items/a2gs_System_1.0_1986_Apple_FW/System_1.0
|
|||||||
|
|
||||||
static char delimitStr[] = "\p\r\n\r\n";
|
static char delimitStr[] = "\p\r\n\r\n";
|
||||||
|
|
||||||
int main(void) {
|
char *defaultURL = "http://ia800505.us.archive.org/16/items/a2gs_System_1.0_1986_Apple_FW/System_1.0_1986_Apple_FW.2mg";
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
TLStartUp();
|
TLStartUp();
|
||||||
|
|
||||||
LoadOneTool(54,0x200);
|
LoadOneTool(54,0x200);
|
||||||
TCPIPStartUp();
|
TCPIPStartUp();
|
||||||
|
|
||||||
TCPIPConnect(NULL);
|
if (TCPIPGetConnectStatus() == FALSE) {
|
||||||
|
TCPIPConnect(NULL);
|
||||||
|
if (toolerror())
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
Session sess;
|
Session sess = {0};
|
||||||
FILE *f = fopen("out", "wb");
|
|
||||||
|
char *url = (argc > 1) ? argv[1] : defaultURL;
|
||||||
|
|
||||||
BuildHTTPRequest(&sess, "/16/items/a2gs_System_1.0_1986_Apple_FW/System_1.0_1986_Apple_FW.2mg", "ia800505.us.archive.org");
|
enum SetURLResult result = SetURL(&sess, url, TRUE, FALSE);
|
||||||
fputs(sess.httpRequest, f);
|
|
||||||
|
if (result != SETURL_SUCCESSFUL) {
|
||||||
UpdateRequestRange(&sess, 0, 511);
|
printf("SetURL error %i\n", (int)result);
|
||||||
fputs(sess.httpRequest, f);
|
|
||||||
|
|
||||||
strcpy(sess.domainName, "\pia800505.us.archive.org");
|
|
||||||
Boolean result = DoLookupName(&sess);
|
|
||||||
|
|
||||||
if (result) {
|
|
||||||
printf("IP = %lu.%lu.%lu.%lu\n",
|
|
||||||
sess.ipAddr & 0xFF,
|
|
||||||
(sess.ipAddr >> 8) & 0xFF,
|
|
||||||
(sess.ipAddr >> 16) & 0xFF,
|
|
||||||
(sess.ipAddr >> 24));
|
|
||||||
} else {
|
|
||||||
printf("Address lookup failed\n");
|
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
sess.port = 80;
|
unsigned long startByte = 0;
|
||||||
|
if (argc > 2) {
|
||||||
|
startByte = strtoul(argv[2], NULL, 0);
|
||||||
|
}
|
||||||
|
UpdateRequestRange(&sess, startByte, startByte + 511);
|
||||||
|
|
||||||
|
printf("Request:\n");
|
||||||
|
printf("=========\n");
|
||||||
|
int i;
|
||||||
|
for (i = 0; sess.httpRequest[i] != '\0'; i++) {
|
||||||
|
char ch = sess.httpRequest[i];
|
||||||
|
if (ch != '\r')
|
||||||
|
putchar(ch);
|
||||||
|
}
|
||||||
|
printf("=========\n");
|
||||||
|
printf("\n", i);
|
||||||
|
|
||||||
int err;
|
int err;
|
||||||
if ((err = StartTCPConnection(&sess)) != 0) {
|
if ((err = StartTCPConnection(&sess)) != 0) {
|
||||||
@ -61,18 +73,20 @@ int main(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TCPIPWriteTCP(sess.ipid, sess.httpRequest, strlen(sess.httpRequest), TRUE, FALSE);
|
TCPIPWriteTCP(sess.ipid, sess.httpRequest, strlen(sess.httpRequest), TRUE, FALSE);
|
||||||
|
|
||||||
LongWord startTime = GetTick();
|
|
||||||
|
|
||||||
while (GetTick() - startTime < 3*60) {
|
|
||||||
//printf("polling\n");
|
|
||||||
TCPIPPoll();
|
|
||||||
}
|
|
||||||
|
|
||||||
rlrBuff rlrBuff;
|
rlrBuff rlrBuff = {0};
|
||||||
TCPIPReadLineTCP(sess.ipid, (void*)((LongWord)delimitStr | 0x80000000),
|
Word tcpError;
|
||||||
buffTypeNewHandle, (Ref)NULL,
|
do {
|
||||||
0xFFFFFF, &rlrBuff);
|
TCPIPPoll();
|
||||||
|
tcpError = TCPIPReadLineTCP(sess.ipid,
|
||||||
|
(void*)((LongWord)delimitStr | 0x80000000),
|
||||||
|
buffTypeNewHandle, (Ref)NULL,
|
||||||
|
0xFFFFFF, &rlrBuff);
|
||||||
|
if (tcpError || toolerror()) {
|
||||||
|
printf("tcpError = %u, toolerror = %u\n", tcpError, toolerror());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (rlrBuff.rlrBuffCount == 0);
|
||||||
|
|
||||||
printf("Response:\n");
|
printf("Response:\n");
|
||||||
printf("=========\n");
|
printf("=========\n");
|
||||||
@ -81,11 +95,8 @@ int main(void) {
|
|||||||
if (ch != '\r')
|
if (ch != '\r')
|
||||||
putchar(ch);
|
putchar(ch);
|
||||||
}
|
}
|
||||||
//printf("%s\n", *(rlrBuff.rlrBuffHandle));
|
|
||||||
printf("=========\n");
|
printf("=========\n");
|
||||||
|
printf("Response size = %lu\n", rlrBuff.rlrBuffCount);
|
||||||
printf("Response headers handle size = %lu \n", GetHandleSize(rlrBuff.rlrBuffHandle));
|
|
||||||
printf("Reported response size = %lu \n", rlrBuff.rlrBuffCount);
|
|
||||||
|
|
||||||
EndTCPConnection(&sess);
|
EndTCPConnection(&sess);
|
||||||
|
|
||||||
|
@ -25,8 +25,8 @@ typedef struct Session {
|
|||||||
LongWord ipAddr;
|
LongWord ipAddr;
|
||||||
Word port;
|
Word port;
|
||||||
|
|
||||||
/* Domain name of host (p-string; empty string for host specified by IP) */
|
/* Domain name or IP address of host (p-string, but also null-terminated) */
|
||||||
char domainName[256];
|
char hostName[257];
|
||||||
/* Time (GetTick) of last DNS lookup */
|
/* Time (GetTick) of last DNS lookup */
|
||||||
LongWord dnsTime;
|
LongWord dnsTime;
|
||||||
} Session;
|
} Session;
|
||||||
|
95
seturl.c
Normal file
95
seturl.c
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
#include <types.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include "session.h"
|
||||||
|
#include "urlparser.h"
|
||||||
|
#include "strcasecmp.h"
|
||||||
|
#include "hostname.h"
|
||||||
|
#include "http.h"
|
||||||
|
#include "tcpconnection.h"
|
||||||
|
#include "seturl.h"
|
||||||
|
|
||||||
|
#define DEFAULT_HTTP_PORT 80
|
||||||
|
|
||||||
|
/* Limit to make sure sizes stay within the range of 16-bit values */
|
||||||
|
#define MAX_URL_LENGTH 30000
|
||||||
|
|
||||||
|
|
||||||
|
enum SetURLResult
|
||||||
|
SetURL(Session *sess, char *url, Boolean permissive, Boolean partialOK) {
|
||||||
|
if (strlen(url) > MAX_URL_LENGTH) {
|
||||||
|
return URL_TOO_LONG;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(unsigned int i = 0; url[i] != '\0'; i++) {
|
||||||
|
if (url[i] <= ' ' && url[i] >= 0) {
|
||||||
|
return INVALID_CHARACTER_IN_URL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
URLParts urlParts = ParseURL(url);
|
||||||
|
|
||||||
|
if (urlParts.errorFound)
|
||||||
|
return BAD_URL_SYNTAX;
|
||||||
|
|
||||||
|
if (urlParts.scheme == NULL) {
|
||||||
|
if (permissive) {
|
||||||
|
urlParts.scheme = "http";
|
||||||
|
} else {
|
||||||
|
return BAD_URL_SYNTAX;
|
||||||
|
}
|
||||||
|
} else if (strcasecmp(urlParts.scheme, "http") != 0) {
|
||||||
|
return UNSUPPORTED_URL_SCHEME;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (urlParts.username != NULL || urlParts.password != NULL) {
|
||||||
|
return AUTHENTICATION_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (urlParts.fragment != NULL) {
|
||||||
|
return FRAGMENT_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long portNum;
|
||||||
|
char *endPtr;
|
||||||
|
if (urlParts.port == NULL || *urlParts.port == '\0') {
|
||||||
|
portNum = DEFAULT_HTTP_PORT;
|
||||||
|
} else {
|
||||||
|
errno = 0;
|
||||||
|
portNum = strtoul(urlParts.port, &endPtr, 10);
|
||||||
|
if (errno || *endPtr != '\0' || portNum > 0xFFFF) {
|
||||||
|
return INVALID_PORT_NUMBER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sess->port = portNum;
|
||||||
|
|
||||||
|
if (urlParts.host == NULL) {
|
||||||
|
if (!partialOK || sess->hostName[0] == 0) {
|
||||||
|
return NO_HOST_SPECIFIED;
|
||||||
|
}
|
||||||
|
} else if (*urlParts.host == '\0') {
|
||||||
|
return NO_HOST_SPECIFIED;
|
||||||
|
} else if (*urlParts.host == '[') {
|
||||||
|
return IPV6_NOT_SUPPORTED;
|
||||||
|
} else {
|
||||||
|
size_t len;
|
||||||
|
if ((len = strlen(urlParts.host)) > 255) {
|
||||||
|
return HOSTNAME_TOO_LONG;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(&sess->hostName[1], urlParts.host);
|
||||||
|
sess->hostName[0] = len;
|
||||||
|
|
||||||
|
if (!DoLookupName(sess)) {
|
||||||
|
return NAME_LOOKUP_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!BuildHTTPRequest(sess, urlParts.path)) {
|
||||||
|
return OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* End any existing TCP connection to old URL */
|
||||||
|
EndTCPConnection(sess);
|
||||||
|
|
||||||
|
return SETURL_SUCCESSFUL;
|
||||||
|
}
|
23
seturl.h
Normal file
23
seturl.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#ifndef SETURL_H
|
||||||
|
#define SETURL_H
|
||||||
|
|
||||||
|
enum SetURLResult {
|
||||||
|
SETURL_SUCCESSFUL = 0,
|
||||||
|
URL_TOO_LONG,
|
||||||
|
INVALID_CHARACTER_IN_URL,
|
||||||
|
BAD_URL_SYNTAX,
|
||||||
|
UNSUPPORTED_URL_SCHEME,
|
||||||
|
AUTHENTICATION_NOT_SUPPORTED,
|
||||||
|
FRAGMENT_NOT_SUPPORTED,
|
||||||
|
INVALID_PORT_NUMBER,
|
||||||
|
NO_HOST_SPECIFIED,
|
||||||
|
IPV6_NOT_SUPPORTED,
|
||||||
|
HOSTNAME_TOO_LONG,
|
||||||
|
NAME_LOOKUP_FAILED,
|
||||||
|
OUT_OF_MEMORY
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SetURLResult
|
||||||
|
SetURL(Session *sess, char *url, Boolean permissive, Boolean partialOK);
|
||||||
|
|
||||||
|
#endif
|
@ -5,12 +5,23 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
int strcasecmp(const char *s1, const char *s2)
|
||||||
|
{
|
||||||
|
while (*s1 != '\0' && tolower(*s1) == tolower(*s2)) {
|
||||||
|
s1++;
|
||||||
|
s2++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int)*s1 - (int)*s2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int strncasecmp(const char *s1, const char *s2, size_t n)
|
int strncasecmp(const char *s1, const char *s2, size_t n)
|
||||||
{
|
{
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
while (n > 1 && *s1 != 0 && tolower(*s1) == tolower(*s2)) {
|
while (n > 1 && *s1 != '\0' && tolower(*s1) == tolower(*s2)) {
|
||||||
s1++;
|
s1++;
|
||||||
s2++;
|
s2++;
|
||||||
n--;
|
n--;
|
9
strcasecmp.h
Normal file
9
strcasecmp.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#ifndef STRCASECMP_H
|
||||||
|
#define STRCASECMP_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
int strcasecmp(const char *s1, const char *s2);
|
||||||
|
int strncasecmp(const char *s1, const char *s2, size_t n);
|
||||||
|
|
||||||
|
#endif
|
@ -1,6 +0,0 @@
|
|||||||
#ifndef STRNCASECMP_H
|
|
||||||
#define STRNCASECMP_H
|
|
||||||
|
|
||||||
int strncasecmp(const char *s1, const char *s2, size_t n);
|
|
||||||
|
|
||||||
#endif
|
|
@ -20,11 +20,8 @@ Word StartTCPConnection(Session *sess) {
|
|||||||
srBuff mySRBuff;
|
srBuff mySRBuff;
|
||||||
LongWord initialTime;
|
LongWord initialTime;
|
||||||
|
|
||||||
if (TCPIPGetConnectStatus() == FALSE) {
|
/* End any existing TCP connection */
|
||||||
TCPIPConnect(NULL);
|
EndTCPConnection(sess);
|
||||||
if (toolerror())
|
|
||||||
return aspNetworkErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
sess->ipid =
|
sess->ipid =
|
||||||
TCPIPLogin(userid(), sess->ipAddr, sess->port, 0, 0x40);
|
TCPIPLogin(userid(), sess->ipAddr, sess->port, 0, 0x40);
|
||||||
|
122
urlparser.c
Normal file
122
urlparser.c
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
#include "urlparser.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse the URL and break it up into its component parts.
|
||||||
|
*
|
||||||
|
* This handles http URLs and other schemes with the same syntax.
|
||||||
|
*
|
||||||
|
* It can also handle relative URLs containing an absolute-path reference
|
||||||
|
* (i.e. starting with /) and URL-like addresses without the scheme prefix.
|
||||||
|
* In these cases, the portions of the URL not provided will be NULL.
|
||||||
|
*
|
||||||
|
* This modifies the original string passed in, breaking it up into components.
|
||||||
|
*/
|
||||||
|
URLParts ParseURL(char *url) {
|
||||||
|
char *sep, sep2;
|
||||||
|
URLParts urlParts = {0};
|
||||||
|
|
||||||
|
sep = strrchr(url, '#');
|
||||||
|
if (sep) {
|
||||||
|
*sep = '\0';
|
||||||
|
urlParts.fragment = sep + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Detect relative URL (absolute-path reference only) */
|
||||||
|
if (url[0] == '/') {
|
||||||
|
if (url[1] != '/') {
|
||||||
|
url++;
|
||||||
|
goto pathPart;
|
||||||
|
} else {
|
||||||
|
urlParts.errorFound = 1;
|
||||||
|
return urlParts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sep = strchr(url, ':');
|
||||||
|
if (sep) {
|
||||||
|
urlParts.scheme = url;
|
||||||
|
*sep = '\0';
|
||||||
|
url = sep + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (urlParts.scheme != NULL) {
|
||||||
|
if (strncmp(url, "//", 2) == 0) {
|
||||||
|
url += 2;
|
||||||
|
} else {
|
||||||
|
urlParts.errorFound = 1;
|
||||||
|
return urlParts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
urlParts.path = strchr(url, '/');
|
||||||
|
if (urlParts.path == NULL) {
|
||||||
|
urlParts.path = "";
|
||||||
|
} else {
|
||||||
|
*urlParts.path = '\0';
|
||||||
|
urlParts.path++;
|
||||||
|
}
|
||||||
|
|
||||||
|
sep = strchr(url, '@');
|
||||||
|
if (sep) {
|
||||||
|
*sep = '\0';
|
||||||
|
urlParts.username = url;
|
||||||
|
|
||||||
|
urlParts.password = strchr(url, ':');
|
||||||
|
if (urlParts.password != NULL) {
|
||||||
|
*urlParts.password = '\0';
|
||||||
|
urlParts.password++;
|
||||||
|
}
|
||||||
|
|
||||||
|
url = sep + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
urlParts.host = url;
|
||||||
|
|
||||||
|
/* Handle IPv6 address syntax */
|
||||||
|
if (*url == '[') {
|
||||||
|
sep = strchr(url, ']');
|
||||||
|
if (sep) {
|
||||||
|
url = sep + 1;
|
||||||
|
} else {
|
||||||
|
urlParts.errorFound = 1;
|
||||||
|
return urlParts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sep = strchr(url, ':');
|
||||||
|
if (sep) {
|
||||||
|
*sep = '\0';
|
||||||
|
urlParts.port = sep + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pathPart:
|
||||||
|
return urlParts;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef URLPARSER_TEST
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
URLParts urlParts;
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
urlParts = ParseURL(argv[1]);
|
||||||
|
|
||||||
|
printf("scheme: %s\n", urlParts.scheme ? urlParts.scheme : "(NULL)");
|
||||||
|
printf("username: %s\n", urlParts.username ? urlParts.username : "(NULL)");
|
||||||
|
printf("password: %s\n", urlParts.password ? urlParts.password : "(NULL)");
|
||||||
|
printf("host: %s\n", urlParts.host ? urlParts.host : "(NULL)");
|
||||||
|
printf("port: %s\n", urlParts.port ? urlParts.port : "(NULL)");
|
||||||
|
printf("path: %s\n", urlParts.path ? urlParts.path : "(NULL)");
|
||||||
|
printf("fragment: %s\n", urlParts.fragment ? urlParts.fragment : "(NULL)");
|
||||||
|
|
||||||
|
if (urlParts.errorFound) {
|
||||||
|
printf("Error found\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
25
urlparser.h
Normal file
25
urlparser.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef URLPARSER_H
|
||||||
|
#define URLPARSER_H
|
||||||
|
|
||||||
|
#ifdef __ORCAC__
|
||||||
|
# include <types.h>
|
||||||
|
#else
|
||||||
|
typedef _Bool Boolean;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct URLParts {
|
||||||
|
char *scheme;
|
||||||
|
char *username;
|
||||||
|
char *password;
|
||||||
|
char *host;
|
||||||
|
char *port;
|
||||||
|
char *path; /* Omits leading '/'. Includes query, if any. */
|
||||||
|
char *fragment;
|
||||||
|
|
||||||
|
Boolean errorFound;
|
||||||
|
} URLParts;
|
||||||
|
|
||||||
|
|
||||||
|
URLParts ParseURL(char *url);
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user