📄 http.asm
字号:
mov ecx,eax
push ecx
invoke StrLen,StrSub
pop ecx
mov ebx,eax
.if ecx<eax
mov eax,FALSE
.elseif ecx==eax
mov esi,StrMain
mov edi,StrSub
repe cmpsb
je Equal
mov eax,FALSE
jmp GetOut
Equal:
xor eax,eax
GetOut:
.else
sub ecx,eax
inc ecx
mov eax,ecx
xor edx,edx
push eax
.while eax!=0
mov edi,StrMain
add edi,edx
mov esi,StrSub
mov ecx,ebx
repe cmpsb
je Found
jmp DontFind
Found:
.break
DontFind:
inc edx
dec eax
.endw
pop ecx
.if eax!=0
sub ecx,eax
mov eax,ecx
.else
mov eax,-1
.endif
.endif
ret
InString ENDP
;=====================================================================
; InStringi
;=====================================================================
; Search for a substring in one string. Case insensitive
; Return Value: -1 if substring not found, offset of the first byte
; of the substring if successful
;=========================================================================
InStringi PROC StrMain:DWORD,StrSub:DWORD
LOCAL hMemory1:DWORD
LOCAL pMemory1:DWORD
LOCAL hMemory2:DWORD
LOCAL pMemory2:DWORD
invoke StrLen,StrMain
inc eax
invoke GlobalAlloc,GHND,eax
.if eax==NULL
mov eax,-1
.else
mov hMemory1,eax
invoke GlobalLock,eax
.if eax==NULL
invoke GlobalFree,hMemory1
mov eax,-1
.else
mov pMemory1,eax
invoke StrLen,StrSub
inc eax
invoke GlobalAlloc,GHND,eax
.if eax==NULL
invoke GlobalUnlock,pMemory1
invoke GlobalFree,hMemory1
mov eax,-1
.else
mov hMemory2,eax
invoke GlobalLock,eax
.if eax==NULL
invoke GlobalUnlock,pMemory1
invoke GlobalFree,hMemory1
invoke GlobalFree,hMemory2
mov eax,-1
.else
mov pMemory2,eax
invoke StrCpy,pMemory1,StrMain
invoke StrCpy,pMemory2,StrSub
invoke CharLower,pMemory1
invoke CharLower,pMemory2
invoke InString,pMemory1,pMemory2
push eax
invoke GlobalUnlock,pMemory1
invoke GlobalFree,hMemory1
invoke GlobalUnlock,pMemory2
invoke GlobalFree,hMemory2
pop eax
.endif
.endif
.endif
.endif
ret
InStringi ENDP
ReadSocket PROC
.if WaitingForName==0 ; if the SaveAs dialog box is diplayed, we don't want to read the data from the socket
; yet because the file is not created yet. So we jump over the read until the file is created
invoke ioctlsocket,sock,FIONREAD,addr sizetoread ; Check the number of bytes available to read from the socket
invoke GlobalAlloc,GHND,sizetoread ; allocate memory enough for the data to read from the socket
mov mHandle,eax
invoke GlobalLock,eax
mov buffer,eax
invoke recv,sock,buffer,sizetoread,0 ; Read the data from the socket
.if eax==SOCKET_ERROR
invoke ShowErrorMessage
.else
mov sizetoread,eax ; Save the actual number of bytes read from the socket
; BEWARE! The value returned from ioctlsocket and the actual number of bytes
; read in from the socket are not always equal.
.if HeaderParsed==FALSE ; If the HTTP header is not received and parsed, store the data in HTTPHeader
invoke ParseAllHeaders
.else ; when the http header is out of the way, what follows is the actual data
.if MultipartPresent==FALSE || (MultipartPresent==TRUE && MultipartHeaderParsed==TRUE)
invoke WriteOutputFile,buffer,sizetoread
.else
invoke FillMultipartHeader
.endif
.endif
invoke GlobalUnlock,buffer
invoke GlobalFree,mHandle
.endif
.endif
ret
ReadSocket ENDP
FillMultipartHeader PROC uses edi
mov edi,offset MultipartHeader
add edi,MultipartIndex
mov eax,FirstDataOffset
sub eax,buffer
mov ecx,sizetoread
sub ecx,eax
mov eax,FirstDataOffset
.while ecx>0
.if byte ptr [eax]==0Ah && byte ptr [eax+2]==0Ah
mov dl,byte ptr [eax]
mov byte ptr [edi],dl
add eax,3
mov FirstDataOffset,eax
.if Resuming==FALSE
invoke ParseHeader,addr MultipartHeader
.endif
mov MultipartHeaderParsed,TRUE
invoke CreateOutputFile
.break
.else
mov dl,byte ptr [eax]
mov byte ptr [edi],dl
inc eax
inc edi
inc MultipartIndex
dec ecx
.endif
.endw
ret
FillMultipartHeader ENDP
ParseAllHeaders PROC uses edi esi
mov edi,offset HTTPHeader
add edi,HeaderIndex ; the address of the first empty space in HTTPHeader
mov esi,buffer
.while eax!=0
.if (byte ptr [esi]==0Ah) && (byte ptr [esi-2]==0Ah) ; if there are two 0Ah, that's the end of http header
mov cl,byte ptr [esi]
mov byte ptr [edi],cl
inc esi
inc edi
mov byte ptr [edi],0
mov HeaderParsed,TRUE ; Set the flag to show that the http header is received. what follows will be actual data
mov FirstDataOffset,esi ; Address of the first byte of the real data
invoke ParseHeader,addr HTTPHeader
invoke String2Dword,addr StatusCode ;Convert status code string to number
mov StatusValue,ax
.if byte ptr [StatusCode]=="3" ; If the status code starts with "3", it means we have to go to the url specified by "location:" field.
mov Redirection,1 ; Set the flag that redirection is in progress
invoke lstrcpy,addr ErrorString,addr HTTPHeader ; We will convert the HTTP header to lower case so we must copy it to another buffer
invoke CharLower,addr ErrorString
invoke lstrlen,addr ErrorString
mov ecx,eax
mov edi,offset ErrorString
Find_l_again:
mov al,"l" ; Search for "l" which is the first char of "location:"
repne scasb
push edi
push ecx
dec edi
mov esi,offset Location ; if "l" is found, check if it's the first char of "location:"
mov ecx,9
repe cmpsb
mov esi,edi
pop ecx
pop edi
jne Find_l_again
invoke RtlFillMemory,addr URLString,512,0
mov edi,esi
mov esi,offset URLString
.if byte ptr [edi]==20h ; skip spaces before url (if any)
mov al,20h
mov ecx,512
repe scasb
dec edi
.endif
.while (byte ptr [edi]!=0) && (byte ptr [edi]!=0dh) && (byte ptr [edi]!=0Ah)
mov al,byte ptr [edi]
mov byte ptr [esi],al
inc edi
inc esi
.endw
invoke CloseSock ; Close the socket
invoke ClearMessages,hwnd,WM_SOCKET
mov FileHandle,0
invoke ConnectSocket ; Connect again with the new url
.elseif StatusValue==503 ; Server is busy
invoke MessageBox,hwnd,addr ServerBusy,addr AppName,MB_OK+MB_ICONERROR
invoke CloseSock
invoke EnableControls
.elseif byte ptr [StatusCode]=="5"
invoke MessageBox,hwnd,addr ServerError,addr AppName,MB_OK+MB_ICONERROR
invoke CloseSock
invoke EnableControls
.elseif StatusValue==204
invoke MessageBox,hwnd,addr NoContent,addr AppName,MB_OK+MB_ICONERROR
invoke CloseSock
invoke EnableControls
.elseif StatusValue==400
invoke MessageBox,hwnd,addr BadRequest,addr AppName,MB_OK+MB_ICONERROR
invoke CloseSock
invoke EnableControls
.elseif StatusValue==401
invoke MessageBox,hwnd,addr Unauthorized,addr AppName,MB_OK+MB_ICONERROR
invoke CloseSock
invoke EnableControls
.elseif StatusValue==403
invoke MessageBox,hwnd,addr Forbidden,addr AppName,MB_OK+MB_ICONERROR
invoke CloseSock
invoke EnableControls
.elseif StatusValue==404
invoke MessageBox,hwnd,addr NotFound,addr AppName,MB_OK+MB_ICONERROR
invoke CloseSock
invoke EnableControls
.elseif StatusValue==406
invoke MessageBox,hwnd,addr NotAcceptable,addr AppName,MB_OK+MB_ICONERROR
invoke CloseSock
invoke EnableControls
.elseif StatusValue==410
invoke MessageBox,hwnd,addr Gone,addr AppName,MB_OK+MB_ICONERROR
invoke CloseSock
invoke EnableControls
.elseif byte ptr [StatusCode]=="2"
invoke InStringi,addr HTTPHeader,addr Multipart
.if eax!=-1
mov CanResume,TRUE
mov MultipartPresent,TRUE
invoke FillMultipartHeader
.else
invoke InStringi,addr HTTPHeader,addr AcceptRanges
.if eax!=-1 || StatusValue==206
mov CanResume,TRUE
.else
invoke InStringi,addr HTTPHeader,addr ContentRange
.if eax!=-1
mov CanResume,TRUE
.endif
.endif
invoke CreateOutputFile
; invoke MessageBox,NULL,addr HTTPHeader,addr AppName,MB_OK
.endif
.else
invoke MessageBox,hwnd,addr Undefined,addr AppName,MB_OK+MB_ICONERROR
invoke CloseSock
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -