Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
140 views
in Technique[技术] by (71.8m points)

Handling POST data sent by html form in CGI C

So, as I said a few days ago, I'm trying to make a login script using CGI-C on a Apache server.

My form is submitting two variables to Test.cgi: username and password (pattern 2 to 40 characters only) using the POST method.

here is my code so far:

#include <stdio.h>
#include <stdlib.h>
int main(void) 
{
char *lengthy;
int figures;
char somelimit[512];
lengthy = getenv("CONTENT_LENGTH");
figures = atoi(lengthy);
fgets(somelimit, figures, stdin);
printf("Content-type: text/html

");
printf("%s
", somelimit);
return 0;
}

Q. How do I extract username and password values from stdin? A normal return I'm getting in the above case is "username=xyz&password=xyz12" how do I process this?

Q.I want to limit what I read from CONTENT_LENGTH header, in-case of a malformed CONTENT-LENGTH header.

what type of Data is this header returning? I know it is supposed to return a "Decimal no of Octets". Valid values are 0 or more. I want to take 1 to X, where X is the upper limit, considering I have two variables, username/password, both limited to 40 characters each in html form.

I tried int[] and char[], instead of the pointer. Why can't I convert it directly with something like:

int some[1024];
some = atoi(gentenv("CONTENT_LENGTH"));

why is atoi considered unsafe?

Q. How do I take only the stdin to contain only US-ASCII characters, to avoid malformed message-body.

I'm a C Newbie, so please go easy :) PS: Please don't recommend any frameworks/web-servers, etc.

Edit:I just realized that perhaps I asked too many questions. Sorry about that. I'm going to fix this post to make it cohesive and well bounded. Please stand by.

Edit2: This is the final question, no more edits. I will accept an answer which at least answers 2 out of 3 questions above.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

A lot of things going on here, and a lot of questions.

First, I recommend that you not output your HTTP header until you're about to output the rest. It's more logical that way, and allows you to output a Redirect header instead if something in your program requires it.

Second, use strtoul() instead of atoi(), since the latter has no error-checking.

You only need one buffer, not two; and I recommend you allocate it dynamically based off the content length. Use malloc() and don't forget to check the return value. Do NOT try to anticipate the upper bounds of your content length.

You'll have to decode the argument string to get any values out. What you do with them is up to you, but handling user names and passwords is a wholly separate topic that could take days to cover. But suffice it to say, never EVER store a password in plain text in a file.

CONTENT_LENGTH is text passed by stdin. That text includes the number of bytes of content. You will have to convert the text to an integer type, probably size_t, before it is useful to you. That's what your atoi() function is doing (which, again, you should replace with strtoul())

Use HTTPS.

Stop emitting your Content-type header prematurely. Then, if you decide you need to redirect, you can emit a Redirect header instead.

getenv() returns a pointer to a static text block that you cannot change. If you copy the pointer, you cannot change the text in the string. If you copy the string to a new array, you would be able to change the text in the string; however, I cannot think of a reason why you'd want to do that.

In your current code, you do not allocate any memory off the heap so you do not need to call free(). However, I recommend you rethink this aspect of your design.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...